aboutsummaryrefslogtreecommitdiff
path: root/nuttx/arch/arm
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-09-17 18:18:44 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-09-17 18:18:44 +0000
commit57623d42ebb04f0a0b9e6eb7c0847a3ece2aa0ff (patch)
tree25d07d14e920d31c0b1947c9ca586f2a01fc32d8 /nuttx/arch/arm
downloadpx4-firmware-57623d42ebb04f0a0b9e6eb7c0847a3ece2aa0ff.tar.gz
px4-firmware-57623d42ebb04f0a0b9e6eb7c0847a3ece2aa0ff.tar.bz2
px4-firmware-57623d42ebb04f0a0b9e6eb7c0847a3ece2aa0ff.zip
Resync new repository with old repo r5166
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5153 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/arm')
-rw-r--r--nuttx/arch/arm/Kconfig284
-rw-r--r--nuttx/arch/arm/include/arch.h122
-rw-r--r--nuttx/arch/arm/include/arm/irq.h231
-rw-r--r--nuttx/arch/arm/include/arm/syscall.h243
-rw-r--r--nuttx/arch/arm/include/armv7-m/irq.h306
-rw-r--r--nuttx/arch/arm/include/armv7-m/irq_cmnvector.h164
-rw-r--r--nuttx/arch/arm/include/armv7-m/irq_lazyfpu.h182
-rw-r--r--nuttx/arch/arm/include/armv7-m/syscall.h243
-rw-r--r--nuttx/arch/arm/include/c5471/irq.h105
-rw-r--r--nuttx/arch/arm/include/calypso/armio.h52
-rw-r--r--nuttx/arch/arm/include/calypso/clock.h67
-rw-r--r--nuttx/arch/arm/include/calypso/debug.h31
-rw-r--r--nuttx/arch/arm/include/calypso/defines.h18
-rw-r--r--nuttx/arch/arm/include/calypso/irq.h81
-rw-r--r--nuttx/arch/arm/include/calypso/memory.h28
-rw-r--r--nuttx/arch/arm/include/calypso/timer.h25
-rw-r--r--nuttx/arch/arm/include/calypso/uwire.h6
-rw-r--r--nuttx/arch/arm/include/dm320/irq.h134
-rw-r--r--nuttx/arch/arm/include/imx/irq.h164
-rw-r--r--nuttx/arch/arm/include/irq.h100
-rw-r--r--nuttx/arch/arm/include/kinetis/irq.h343
-rw-r--r--nuttx/arch/arm/include/limits.h86
-rw-r--r--nuttx/arch/arm/include/lm3s/irq.h497
-rw-r--r--nuttx/arch/arm/include/lpc17xx/irq.h285
-rw-r--r--nuttx/arch/arm/include/lpc214x/irq.h130
-rw-r--r--nuttx/arch/arm/include/lpc2378/irq.h151
-rw-r--r--nuttx/arch/arm/include/lpc31xx/irq.h118
-rw-r--r--nuttx/arch/arm/include/lpc43xx/chip.h557
-rw-r--r--nuttx/arch/arm/include/lpc43xx/irq.h224
-rw-r--r--nuttx/arch/arm/include/sam3u/irq.h297
-rw-r--r--nuttx/arch/arm/include/serial.h58
-rw-r--r--nuttx/arch/arm/include/stdarg.h59
-rw-r--r--nuttx/arch/arm/include/stm32/chip.h568
-rw-r--r--nuttx/arch/arm/include/stm32/irq.h117
-rw-r--r--nuttx/arch/arm/include/stm32/stm32f10xxx_irq.h287
-rw-r--r--nuttx/arch/arm/include/stm32/stm32f20xxx_irq.h182
-rw-r--r--nuttx/arch/arm/include/stm32/stm32f40xxx_irq.h185
-rw-r--r--nuttx/arch/arm/include/str71x/irq.h151
-rw-r--r--nuttx/arch/arm/include/syscall.h90
-rw-r--r--nuttx/arch/arm/include/types.h101
-rw-r--r--nuttx/arch/arm/include/watchdog.h61
-rw-r--r--nuttx/arch/arm/src/Makefile157
-rw-r--r--nuttx/arch/arm/src/arm/arm.h451
-rw-r--r--nuttx/arch/arm/src/arm/pg_macros.h522
-rw-r--r--nuttx/arch/arm/src/arm/up_allocpage.c243
-rw-r--r--nuttx/arch/arm/src/arm/up_assert.c325
-rw-r--r--nuttx/arch/arm/src/arm/up_blocktask.c167
-rw-r--r--nuttx/arch/arm/src/arm/up_cache.S74
-rw-r--r--nuttx/arch/arm/src/arm/up_checkmapping.c123
-rw-r--r--nuttx/arch/arm/src/arm/up_copystate.c82
-rw-r--r--nuttx/arch/arm/src/arm/up_dataabort.c201
-rw-r--r--nuttx/arch/arm/src/arm/up_doirq.c114
-rw-r--r--nuttx/arch/arm/src/arm/up_fullcontextrestore.S118
-rw-r--r--nuttx/arch/arm/src/arm/up_head.S638
-rw-r--r--nuttx/arch/arm/src/arm/up_initialstate.c146
-rw-r--r--nuttx/arch/arm/src/arm/up_nommuhead.S167
-rw-r--r--nuttx/arch/arm/src/arm/up_pginitialize.c96
-rw-r--r--nuttx/arch/arm/src/arm/up_prefetchabort.c154
-rw-r--r--nuttx/arch/arm/src/arm/up_releasepending.c132
-rw-r--r--nuttx/arch/arm/src/arm/up_reprioritizertr.c187
-rw-r--r--nuttx/arch/arm/src/arm/up_saveusercontext.S119
-rw-r--r--nuttx/arch/arm/src/arm/up_schedulesigaction.c204
-rw-r--r--nuttx/arch/arm/src/arm/up_sigdeliver.c139
-rw-r--r--nuttx/arch/arm/src/arm/up_syscall.c96
-rw-r--r--nuttx/arch/arm/src/arm/up_unblocktask.c159
-rw-r--r--nuttx/arch/arm/src/arm/up_undefinedinsn.c81
-rw-r--r--nuttx/arch/arm/src/arm/up_va2pte.c121
-rw-r--r--nuttx/arch/arm/src/arm/up_vectoraddrexcptn.S83
-rw-r--r--nuttx/arch/arm/src/arm/up_vectors.S446
-rw-r--r--nuttx/arch/arm/src/arm/up_vectortab.S103
-rw-r--r--nuttx/arch/arm/src/armv7-m/exc_return.h117
-rw-r--r--nuttx/arch/arm/src/armv7-m/mpu.h509
-rw-r--r--nuttx/arch/arm/src/armv7-m/nvic.h531
-rw-r--r--nuttx/arch/arm/src/armv7-m/psr.h87
-rw-r--r--nuttx/arch/arm/src/armv7-m/svcall.h94
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_assert.c334
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_blocktask.c167
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_copystate.c86
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_doirq.c123
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_exception.S237
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_fpu.S286
-rwxr-xr-xnuttx/arch/arm/src/armv7-m/up_fullcontextrestore.S95
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_hardfault.c144
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_initialstate.c192
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_memfault.c110
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_mpu.c176
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_releasepending.c129
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_reprioritizertr.c182
-rwxr-xr-xnuttx/arch/arm/src/armv7-m/up_saveusercontext.S104
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_schedulesigaction.c208
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_sigdeliver.c142
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_svcall.c363
-rwxr-xr-xnuttx/arch/arm/src/armv7-m/up_switchcontext.S97
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_unblocktask.c157
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_vectors.c95
-rw-r--r--nuttx/arch/arm/src/c5471/Kconfig6
-rw-r--r--nuttx/arch/arm/src/c5471/Make.defs49
-rw-r--r--nuttx/arch/arm/src/c5471/c5471_ethernet.c2178
-rw-r--r--nuttx/arch/arm/src/c5471/c5471_irq.c244
-rw-r--r--nuttx/arch/arm/src/c5471/c5471_lowputc.S129
-rw-r--r--nuttx/arch/arm/src/c5471/c5471_serial.c869
-rw-r--r--nuttx/arch/arm/src/c5471/c5471_timerisr.c128
-rw-r--r--nuttx/arch/arm/src/c5471/c5471_vectors.S485
-rw-r--r--nuttx/arch/arm/src/c5471/c5471_watchdog.c397
-rw-r--r--nuttx/arch/arm/src/c5471/chip.h371
-rw-r--r--nuttx/arch/arm/src/calypso/Kconfig6
-rw-r--r--nuttx/arch/arm/src/calypso/Make.defs53
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_armio.c104
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_head.S23
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_heap.c102
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_irq.c313
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_lowputc.S133
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_power.c18
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_serial.c962
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_spi.c232
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_spi.h30
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_timer.c207
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_uwire.c152
-rw-r--r--nuttx/arch/arm/src/calypso/chip.h211
-rw-r--r--nuttx/arch/arm/src/calypso/clock.c220
-rw-r--r--nuttx/arch/arm/src/common/up_allocateheap.c83
-rw-r--r--nuttx/arch/arm/src/common/up_arch.h105
-rw-r--r--nuttx/arch/arm/src/common/up_checkstack.c147
-rw-r--r--nuttx/arch/arm/src/common/up_createstack.c197
-rw-r--r--nuttx/arch/arm/src/common/up_etherstub.c86
-rw-r--r--nuttx/arch/arm/src/common/up_exit.c174
-rw-r--r--nuttx/arch/arm/src/common/up_idle.c91
-rw-r--r--nuttx/arch/arm/src/common/up_initialize.c191
-rw-r--r--nuttx/arch/arm/src/common/up_internal.h393
-rw-r--r--nuttx/arch/arm/src/common/up_interruptcontext.c70
-rw-r--r--nuttx/arch/arm/src/common/up_lowputs.c74
-rw-r--r--nuttx/arch/arm/src/common/up_mdelay.c90
-rw-r--r--nuttx/arch/arm/src/common/up_modifyreg16.c85
-rw-r--r--nuttx/arch/arm/src/common/up_modifyreg32.c85
-rw-r--r--nuttx/arch/arm/src/common/up_modifyreg8.c85
-rw-r--r--nuttx/arch/arm/src/common/up_puts.c75
-rw-r--r--nuttx/arch/arm/src/common/up_releasestack.c79
-rw-r--r--nuttx/arch/arm/src/common/up_udelay.c129
-rw-r--r--nuttx/arch/arm/src/common/up_usestack.c155
-rw-r--r--nuttx/arch/arm/src/dm320/Kconfig6
-rw-r--r--nuttx/arch/arm/src/dm320/Make.defs54
-rw-r--r--nuttx/arch/arm/src/dm320/chip.h61
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_ahb.h59
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_allocateheap.c83
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_boot.c237
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_busc.h58
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_clkc.h81
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_decodeirq.c129
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_emif.h108
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_framebuffer.c1438
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_gio.h175
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_intc.h101
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_irq.c249
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_lowputc.S130
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_memorymap.h263
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_osd.h114
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_restart.S138
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_serial.c839
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_timer.h108
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_timerisr.c157
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_uart.h176
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_usb.h249
-rw-r--r--nuttx/arch/arm/src/dm320/dm320_usbdev.c2579
-rw-r--r--nuttx/arch/arm/src/imx/Kconfig6
-rw-r--r--nuttx/arch/arm/src/imx/Make.defs54
-rw-r--r--nuttx/arch/arm/src/imx/chip.h65
-rw-r--r--nuttx/arch/arm/src/imx/imx_aitc.h119
-rw-r--r--nuttx/arch/arm/src/imx/imx_allocateheap.c118
-rw-r--r--nuttx/arch/arm/src/imx/imx_boot.c225
-rw-r--r--nuttx/arch/arm/src/imx/imx_cspi.h210
-rw-r--r--nuttx/arch/arm/src/imx/imx_decodeirq.c136
-rw-r--r--nuttx/arch/arm/src/imx/imx_dma.h250
-rw-r--r--nuttx/arch/arm/src/imx/imx_eim.h85
-rw-r--r--nuttx/arch/arm/src/imx/imx_gpio.c122
-rw-r--r--nuttx/arch/arm/src/imx/imx_gpio.h562
-rw-r--r--nuttx/arch/arm/src/imx/imx_i2c.h69
-rw-r--r--nuttx/arch/arm/src/imx/imx_irq.c145
-rw-r--r--nuttx/arch/arm/src/imx/imx_lowputc.S130
-rw-r--r--nuttx/arch/arm/src/imx/imx_memorymap.h258
-rw-r--r--nuttx/arch/arm/src/imx/imx_rtc.h85
-rw-r--r--nuttx/arch/arm/src/imx/imx_serial.c1244
-rw-r--r--nuttx/arch/arm/src/imx/imx_spi.c1157
-rw-r--r--nuttx/arch/arm/src/imx/imx_system.h187
-rw-r--r--nuttx/arch/arm/src/imx/imx_timer.h104
-rw-r--r--nuttx/arch/arm/src/imx/imx_timerisr.c164
-rw-r--r--nuttx/arch/arm/src/imx/imx_uart.h227
-rw-r--r--nuttx/arch/arm/src/imx/imx_usbd.h320
-rw-r--r--nuttx/arch/arm/src/imx/imx_wdog.h81
-rw-r--r--nuttx/arch/arm/src/kinetis/Kconfig6
-rw-r--r--nuttx/arch/arm/src/kinetis/Make.defs94
-rw-r--r--nuttx/arch/arm/src/kinetis/chip.h853
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_adc.h313
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_aips.h208
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_axbs.h251
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_clockconfig.c379
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_clrpend.c104
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_cmp.h190
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_cmt.h138
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_config.h235
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_crc.h117
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_dac.h235
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_dma.h775
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_dmamux.h111
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_dspi.h321
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_enet.c1565
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_enet.h609
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_ewm.h90
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_flexbus.h213
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_flexcan.h318
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_fmc.h389
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_ftfl.h159
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_ftm.h528
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_gpio.h142
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_i2c.h185
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_i2s.h297
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_idle.c104
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_internal.h847
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_irq.c511
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_k40pinmux.h518
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_k60pinmux.h481
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_llwu.h252
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_lowputc.c452
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_lptmr.h133
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_mcg.h186
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_mcm.h151
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_memorymap.h343
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_mmcau.h138
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_mpu.h398
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_osc.h84
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_pdb.h255
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_pin.c261
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_pindma.c146
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_pingpio.c151
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_pinirq.c438
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_pinmux.h75
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_pit.h124
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_pmc.h111
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_port.h431
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_rngb.h161
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_rtc.h207
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_sdhc.c2934
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_sdhc.h388
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_serial.c1350
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_sim.h545
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_slcd.h420
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_smc.h122
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_start.c158
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_timerisr.c157
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_tsi.h311
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_uart.h511
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_usbdcd.h141
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_usbotg.h328
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_vectors.S741
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_vrefv1.h92
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_wdog.c117
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_wdog.h135
-rw-r--r--nuttx/arch/arm/src/lm3s/Kconfig77
-rw-r--r--nuttx/arch/arm/src/lm3s/Make.defs54
-rw-r--r--nuttx/arch/arm/src/lm3s/chip.h134
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_dumpgpio.c167
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_epi.h113
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_ethernet.c1470
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_ethernet.h203
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_flash.h128
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_gpio.c854
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_gpio.h395
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_gpioirq.c433
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_i2c.h247
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_internal.h546
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_irq.c456
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_lowputc.c308
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_memorymap.h360
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_serial.c1066
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_ssi.c1573
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_ssi.h235
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_start.c152
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_syscontrol.c314
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_syscontrol.h495
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_timer.h125
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_timerisr.c143
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_uart.h347
-rw-r--r--nuttx/arch/arm/src/lm3s/lm3s_vectors.S805
-rw-r--r--nuttx/arch/arm/src/lpc17xx/Kconfig622
-rw-r--r--nuttx/arch/arm/src/lpc17xx/Make.defs102
-rw-r--r--nuttx/arch/arm/src/lpc17xx/chip.h226
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_adc.c279
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_adc.h180
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_allocateheap.c230
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_can.c1306
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_can.h510
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_clockconfig.c208
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_clrpend.c97
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_dac.c199
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_dac.h97
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_emacram.h242
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_ethernet.c2509
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_ethernet.h597
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_gpdma.c226
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_gpdma.h417
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c655
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_gpio.h196
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_gpiodbg.c173
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_gpioint.c431
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_i2c.c545
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_i2c.h208
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_i2s.h190
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_idle.c104
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_internal.h854
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_irq.c471
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_lowputc.c394
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_mcpwm.h280
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_memorymap.h136
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_ohciram.h263
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_pinconn.h635
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_pwm.h223
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_qei.h190
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_rit.h92
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_rtc.h270
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_serial.c1518
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_serial.h127
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_spi.c608
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_spi.h141
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c929
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_ssp.h174
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_start.c151
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_syscon.h494
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_timer.h250
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_timerisr.c151
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_uart.h339
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_usb.h778
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_usbdev.c3459
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c2706
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_vectors.S394
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_wdt.h108
-rw-r--r--nuttx/arch/arm/src/lpc214x/Kconfig6
-rw-r--r--nuttx/arch/arm/src/lpc214x/Make.defs57
-rw-r--r--nuttx/arch/arm/src/lpc214x/README.txt61
-rw-r--r--nuttx/arch/arm/src/lpc214x/chip.h349
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_apb.h72
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_decodeirq.c177
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_head.S634
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_i2c.h141
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_irq.c224
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_lowputc.S209
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_pinsel.h259
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_pll.h105
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_power.h90
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_serial.c842
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_spi.h166
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_timer.h152
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_timerisr.c170
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_uart.h142
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c3375
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.h346
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_vic.h70
-rw-r--r--nuttx/arch/arm/src/lpc2378/Kconfig6
-rw-r--r--nuttx/arch/arm/src/lpc2378/Make.defs63
-rw-r--r--nuttx/arch/arm/src/lpc2378/chip.h959
-rw-r--r--nuttx/arch/arm/src/lpc2378/internal.h70
-rw-r--r--nuttx/arch/arm/src/lpc2378/lpc23xx_decodeirq.c176
-rw-r--r--nuttx/arch/arm/src/lpc2378/lpc23xx_gpio.h71
-rwxr-xr-xnuttx/arch/arm/src/lpc2378/lpc23xx_head.S234
-rw-r--r--nuttx/arch/arm/src/lpc2378/lpc23xx_io.c101
-rw-r--r--nuttx/arch/arm/src/lpc2378/lpc23xx_irq.c302
-rwxr-xr-xnuttx/arch/arm/src/lpc2378/lpc23xx_lowputc.S262
-rw-r--r--nuttx/arch/arm/src/lpc2378/lpc23xx_pinsel.h792
-rw-r--r--nuttx/arch/arm/src/lpc2378/lpc23xx_pllsetup.c242
-rw-r--r--nuttx/arch/arm/src/lpc2378/lpc23xx_scb.h131
-rw-r--r--nuttx/arch/arm/src/lpc2378/lpc23xx_serial.c973
-rw-r--r--nuttx/arch/arm/src/lpc2378/lpc23xx_timer.h163
-rw-r--r--nuttx/arch/arm/src/lpc2378/lpc23xx_timerisr.c202
-rw-r--r--nuttx/arch/arm/src/lpc2378/lpc23xx_uart.h231
-rw-r--r--nuttx/arch/arm/src/lpc2378/lpc23xx_vic.h76
-rw-r--r--nuttx/arch/arm/src/lpc31xx/Kconfig204
-rw-r--r--nuttx/arch/arm/src/lpc31xx/Make.defs67
-rw-r--r--nuttx/arch/arm/src/lpc31xx/chip.h85
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_adc.h132
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_allocateheap.c206
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_analogdie.h421
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_bcrndx.c100
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_boot.c397
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_cgu.h1631
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_cgudrvr.h819
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_clkdomain.c125
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_clkexten.c152
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_clkfreq.c177
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_clkinit.c298
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_decodeirq.c137
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_defclk.c119
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_dma.h425
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_esrndx.c134
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_evntrtr.h264
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_fdcndx.c127
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_fdivinit.c204
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_freqin.c82
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_i2c.c608
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_i2c.h207
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_i2s.h315
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_intc.h198
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_internal.h300
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_ioconfig.h357
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_irq.c218
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_lcd.h161
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_lowputc.c356
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_mci.h270
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_memorymap.h415
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_mpmc.h340
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_nand.h424
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_otp.h139
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_pcm.h174
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_pllconfig.c267
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_pwm.h97
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_resetclks.c151
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_rng.h85
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_serial.c856
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_setfdiv.c135
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_setfreqin.c119
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_softreset.c90
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_spi.c969
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_spi.h252
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_syscreg.h611
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_timer.h119
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_timerisr.c162
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_uart.h263
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_usbdev.c2668
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_usbotg.h654
-rw-r--r--nuttx/arch/arm/src/lpc31xx/lpc31_wdt.h130
-rw-r--r--nuttx/arch/arm/src/lpc43xx/Kconfig318
-rw-r--r--nuttx/arch/arm/src/lpc43xx/Make.defs126
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip.h173
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc4310203050_memorymap.h196
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc4310203050_pinconfig.h982
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc435357_memorymap.h200
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_adc.h198
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_aes.h110
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_atimer.h117
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_can.h458
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_ccu.h356
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_cgu.h866
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_creg.h291
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_dac.h94
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_eeprom.h158
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_emc.h425
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h666
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_evntmntr.h150
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_evntrtr.h159
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_flash.h187
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_gima.h336
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_gpdma.h466
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_gpio.h439
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_i2c.h205
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_i2s.h202
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_lcd.h304
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_mcpwm.h274
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_otp.h192
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_pmc.h82
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_qei.h211
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_rgu.h669
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_rit.h89
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_rtc.h371
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_sct.h1593
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_scu.h435
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_sdmmc.h391
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_sgpio.h682
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_spi.h138
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_spifi.h275
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_ssp.h171
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_timer.h269
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_uart.h397
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_usb0.h716
-rw-r--r--nuttx/arch/arm/src/lpc43xx/chip/lpc43_wwdt.h111
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_adc.c283
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_adc.h95
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_allocateheap.c290
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_cgu.c482
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_cgu.h91
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_clrpend.c99
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_config.h153
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_dac.c204
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_dac.h95
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_debug.c96
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_emacram.h62
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_emc.h63
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_gpdma.c226
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_gpdma.h236
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_gpio.c251
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_gpio.h324
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_gpioint.c317
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_gpioint.h140
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_i2c.c567
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_idle.c187
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_irq.c503
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_irq.h92
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_pinconfig.c154
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_pinconfig.h278
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_rgu.c125
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_rgu.h92
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_serial.c1460
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_serial.h66
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_spi.c604
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_spi.h180
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_spifi.c1268
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_spifi.h136
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_ssp.c930
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_ssp.h197
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_start.c349
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_timerisr.c151
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_uart.c600
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_uart.h156
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_usb0dev.c2671
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_usb0dev.h98
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_usbram.h62
-rw-r--r--nuttx/arch/arm/src/sam3u/Kconfig6
-rw-r--r--nuttx/arch/arm/src/sam3u/Make.defs80
-rw-r--r--nuttx/arch/arm/src/sam3u/chip.h97
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_adc.h236
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_allocateheap.c149
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_chipid.h167
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_clockconfig.c335
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_dmac.c1540
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_dmac.h441
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_eefc.h120
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_gpbr.h90
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_gpioirq.c367
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_hsmci.c2503
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_hsmci.h297
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_internal.h910
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_irq.c461
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_lowputc.c333
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_matrix.h214
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_memorymap.h145
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_mpuinit.c122
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_pdc.h103
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_pio.c394
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_pio.h324
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_pmc.h316
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_pwm.h633
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_rstc.h102
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_rtc.h184
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_rtt.h89
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_serial.c1450
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_smc.h432
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_spi.c948
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_spi.h189
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_ssc.h292
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_start.c161
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_supc.h164
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_tc.h347
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_timerisr.c162
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_twi.h192
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_uart.h391
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_udphs.h371
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_userspace.c105
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_vectors.S385
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_wdt.h96
-rw-r--r--nuttx/arch/arm/src/stm32/Kconfig1838
-rw-r--r--nuttx/arch/arm/src/stm32/Make.defs144
-rw-r--r--nuttx/arch/arm/src/stm32/chip.h127
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_adc.h564
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_bkp.h190
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_can.h505
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_dac.h256
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_dbgmcu.h144
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_eth.h829
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_exti.h141
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_flash.h190
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_i2c.h192
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_memorymap.h57
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_otgfs.h1017
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_pwr.h103
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_sdio.h291
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_spi.h205
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_syscfg.h151
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_tim.h1029
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_uart.h229
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_usbdev.h236
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_wdg.h145
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f100_pinmap.h267
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f103re_pinmap.h332
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f103vc_pinmap.h423
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f103ze_pinmap.h583
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f105vb_pinmap.h416
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f107vc_pinmap.h420
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f10xxx_dma.h350
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f10xxx_gpio.h367
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f10xxx_memorymap.h145
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f10xxx_rcc.h416
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f10xxx_rtc.h96
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f10xxx_vectors.h222
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f20xxx_dma.h520
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f20xxx_gpio.h370
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f20xxx_memorymap.h205
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f20xxx_pinmap.h695
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f20xxx_rcc.h504
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f20xxx_rtc.h338
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f20xxx_vectors.h141
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f40xxx_dma.h520
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f40xxx_gpio.h370
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f40xxx_memorymap.h205
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f40xxx_pinmap.h695
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f40xxx_rcc.h506
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f40xxx_rtc.h338
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f40xxx_vectors.h142
-rw-r--r--nuttx/arch/arm/src/stm32/stm32.h103
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_adc.c1542
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_adc.h602
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_allocateheap.c324
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_bkp.h52
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_can.c1636
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_can.h145
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_dac.c860
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_dac.h139
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_dbgmcu.h64
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_dma.c80
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_dma.h309
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_dumpgpio.c179
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_eth.c3245
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_eth.h97
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_exti.h119
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_exti_alarm.c167
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_exti_gpio.c337
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_flash.c247
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_flash.h49
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_fsmc.h304
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_gpio.c736
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_gpio.h514
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_i2c.c1917
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_i2c.h50
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_idle.c188
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_internal.h45
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_irq.c476
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_iwdg.c711
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_lowputc.c428
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_lowputc.h79
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_lse.c105
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_lsi.c100
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_otgfs.h93
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_otgfsdev.c5439
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_otgfshost.c4290
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_pm.h142
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_pminitialize.c94
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_pmsleep.c117
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_pmstandby.c109
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_pmstop.c122
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_pwm.c1525
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_pwm.h370
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_pwr.c98
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_pwr.h89
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_qencoder.c1228
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_qencoder.h142
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_rcc.c183
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_rcc.h272
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_rtc.c80
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_rtc.h85
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_sdio.c2844
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_sdio.h127
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_serial.c1991
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_spi.c1440
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_spi.h121
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_start.c232
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_syscfg.h54
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_tim.c1020
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_tim.h191
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_timerisr.c164
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_uart.h271
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_usbdev.c3664
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_usbdev.h98
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_usbhost.h128
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_vectors.S427
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_waste.c57
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_waste.h78
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_wdg.h118
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_wwdg.c807
-rw-r--r--nuttx/arch/arm/src/stm32/stm32f10xxx_dma.c615
-rw-r--r--nuttx/arch/arm/src/stm32/stm32f10xxx_rcc.c562
-rw-r--r--nuttx/arch/arm/src/stm32/stm32f10xxx_rtc.c689
-rw-r--r--nuttx/arch/arm/src/stm32/stm32f20xxx_dma.c904
-rw-r--r--nuttx/arch/arm/src/stm32/stm32f20xxx_rcc.c666
-rw-r--r--nuttx/arch/arm/src/stm32/stm32f20xxx_rtc.c842
-rw-r--r--nuttx/arch/arm/src/stm32/stm32f40xxx_dma.c904
-rw-r--r--nuttx/arch/arm/src/stm32/stm32f40xxx_rcc.c668
-rw-r--r--nuttx/arch/arm/src/stm32/stm32f40xxx_rtc.c842
-rw-r--r--nuttx/arch/arm/src/str71x/Kconfig6
-rw-r--r--nuttx/arch/arm/src/str71x/Make.defs60
-rw-r--r--nuttx/arch/arm/src/str71x/chip.h80
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_adc12.h109
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_apb.h109
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_bspi.h153
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_can.h207
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_decodeirq.c147
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_eic.h176
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_emi.h103
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_flash.h123
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_gpio.h94
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_head.S629
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_i2c.h153
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_internal.h156
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_irq.c232
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_lowputc.c319
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_map.h99
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_pcu.h159
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_prccu.c473
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_rccu.h143
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_rtc.h92
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_serial.c1049
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_timer.h155
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_timerisr.c213
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_uart.h181
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_usb.h180
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_wdog.h75
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_xti.c321
-rw-r--r--nuttx/arch/arm/src/str71x/str71x_xti.h105
712 files changed, 255856 insertions, 0 deletions
diff --git a/nuttx/arch/arm/Kconfig b/nuttx/arch/arm/Kconfig
new file mode 100644
index 000000000..3bd531232
--- /dev/null
+++ b/nuttx/arch/arm/Kconfig
@@ -0,0 +1,284 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+if ARCH_ARM
+choice
+ prompt "ARM chip selection"
+ default ARCH_CHIP_STM32
+
+config ARCH_CHIP_C5471
+ bool "TMS320 C5471"
+ select ARCH_ARM7TDMI
+ select ARCH_HAVE_LOWVECTORS
+ ---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
+ ---help---
+ TI Calypso-based cell phones (ARM7TDMI)
+
+config ARCH_CHIP_DM320
+ bool "TMS320 DM320"
+ select ARCH_ARM926EJS
+ select ARCH_HAVE_LOWVECTORS
+ select ARCH_HAVE_MMU
+ ---help---
+ TI DMS320 DM320 (ARM926EJS)
+
+config ARCH_CHIP_IMX
+ bool "Freescale iMX"
+ select ARCH_ARM920T
+ select ARCH_HAVE_HEAP2
+ select ARCH_HAVE_LOWVECTORS
+ select ARCH_HAVE_MMU
+ ---help---
+ Freescale iMX architectures (ARM920T)
+
+config ARCH_CHIP_KINETIS
+ bool "Freescale Kinetis"
+ select ARCH_CORTEXM4
+ select ARCH_HAVE_MPU
+ ---help---
+ Freescale Kinetis Architectures (ARM Cortex-M4)
+
+config ARCH_CHIP_LM3S
+ bool "TI Stellaris"
+ select ARCH_CORTEXM3
+ select ARCH_HAVE_MPU
+ ---help---
+ TI Stellaris LMS3 architecutres (ARM Cortex-M3)
+
+config ARCH_CHIP_LPC17XX
+ bool "NXP LPC17xx"
+ select ARCH_CORTEXM3
+ select ARCH_HAVE_MPU
+ ---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
+ select ARCH_HAVE_MMU
+ ---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
+ ---help---
+ NPX LPC43XX architectures (ARM Cortex-M4).
+
+config ARCH_CHIP_SAM3U
+ bool "Atmel AT91SAM3U"
+ select ARCH_CORTEXM3
+ select ARCH_HAVE_MPU
+ ---help---
+ Atmel AT91SAM3U architectures (ARM Cortex-M3)
+
+config ARCH_CHIP_STM32
+ bool "STMicro STM32"
+ select ARCH_HAVE_CMNVECTOR
+ select ARCH_HAVE_MPU
+ ---help---
+ STMicro STM32 architectures (ARM Cortex-M3/4).
+
+config ARCH_CHIP_STR71X
+ bool "STMicro STR71x"
+ select ARCH_ARM7TDMI
+ select ARCH_HAVE_LOWVECTORS
+ ---help---
+ STMicro STR71x architectures (ARM7TDMI).
+
+endchoice
+
+config ARCH_ARM7TDMI
+ bool
+
+config ARCH_ARM926EJS
+ bool
+
+config ARCH_ARM920T
+ bool
+
+config ARCH_CORTEXM3
+ bool
+
+config ARCH_CORTEXM4
+ bool
+
+config ARCH_FAMILY
+ string
+ default "arm" if ARCH_ARM7TDMI || ARCH_ARM926EJS || ARCH_ARM920T
+ default "armv7-m" if ARCH_CORTEXM3 || ARCH_CORTEXM4
+
+config ARCH_CHIP
+ string
+ default "c5471" if ARCH_CHIP_C5471
+ default "calypso" if ARCH_CHIP_CALYPSO
+ default "dm320" if ARCH_CHIP_DM320
+ default "imx" if ARCH_CHIP_IMX
+ default "kinetis" if ARCH_CHIP_KINETIS
+ default "lm3s" if ARCH_CHIP_LM3S
+ 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 "sam3u" if ARCH_CHIP_SAM3U
+ default "stm32" if ARCH_CHIP_STM32
+ default "str71x" if ARCH_CHIP_STR71X
+
+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 ARCH_FPU
+ bool "FPU support"
+ default y
+ depends on ARCH_CORTEXM4
+ ---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_HAVE_MPU
+ bool
+
+config ARMV7M_MPU
+ bool "MPU support"
+ default n
+ depends on ARCH_HAVE_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 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_HAVE_MMU
+ bool
+
+config PGTABLE_VADDR
+ hex "Page table virtual address"
+ depends on ARCH_HAVE_MMU
+ ---help---
+ Page table virtual address (might be defined in the board.h file). Not
+ applicable to all architectures.
+
+config ARCH_ROMPGTABLE
+ bool "ROM page table"
+ default n
+ depends on ARCH_HAVE_MMU
+ ---help---
+ Support a fixed memory mapping use a (read-only) page table in ROM/FLASH.
+
+config PAGING
+ bool "On-demand paging"
+ default n
+ depends on ARCH_HAVE_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.
+
+config ARCH_IRQPRIO
+ bool "Interrupt priority"
+ default y if ARCH_CORTEXM3 || ARCH_CORTEXM4
+ ---help---
+ Select if your board supports interrupt prioritization.
+
+config BOARD_LOOPSPERMSEC
+ int "Delay loops per millisecond"
+ default 5000
+ ---help---
+ Delay loops nust be calibrated for correct operation.
+
+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 calibratre BOARD_LOOPSPERMSEC. You simply use a stop
+ watch to measure the 100 second delay then adjust BOARD_LOOPSPERMSEC until
+ the delay actually is 100 seconds.
+
+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_IMX
+source arch/arm/src/imx/Kconfig
+endif
+if ARCH_CHIP_KINETIS
+source arch/arm/src/kinetis/Kconfig
+endif
+if ARCH_CHIP_LM3S
+source arch/arm/src/lm3s/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_SAM3U
+source arch/arm/src/sam3u/Kconfig
+endif
+if ARCH_CHIP_STM32
+source arch/arm/src/stm32/Kconfig
+endif
+if ARCH_CHIP_STR71X
+source arch/arm/src/str71x/Kconfig
+endif
+
+endif
diff --git a/nuttx/arch/arm/include/arch.h b/nuttx/arch/arm/include/arch.h
new file mode 100644
index 000000000..d0b2602eb
--- /dev/null
+++ b/nuttx/arch/arm/include/arch.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+ * arch/arm/include/arch.h
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+#ifndef __ASSEMBLY__
+# include <stdint.h>
+#endif
+
+/****************************************************************************
+ * 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
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/include/arm/irq.h b/nuttx/arch/arm/include/arm/irq.h
new file mode 100644
index 000000000..a06abe888
--- /dev/null
+++ b/nuttx/arch/arm/include/arm/irq.h
@@ -0,0 +1,231 @@
+/****************************************************************************
+ * arch/arm/include/arm/irq.h
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/irq.h>
+#ifndef __ASSEMBLY__
+# include <stdint.h>
+#endif
+
+/****************************************************************************
+ * 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__
+
+/* Save the current interrupt enable state & disable IRQs */
+
+static inline irqstate_t irqsave(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 irqrestore(irqstate_t flags)
+{
+ __asm__ __volatile__
+ (
+ "msr cpsr_c, %0"
+ :
+ : "r" (flags)
+ : "memory");
+}
+#endif /* __ASSEMBLY__ */
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/include/arm/syscall.h b/nuttx/arch/arm/include/arm/syscall.h
new file mode 100644
index 000000000..3fc36c3db
--- /dev/null
+++ b/nuttx/arch/arm/include/arm/syscall.h
@@ -0,0 +1,243 @@
+/****************************************************************************
+ * arch/arm/include/arm/syscall.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+
+#ifndef __ASSEMBLY__
+# include <stdint.h>
+#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"
+ );
+
+ 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"
+ );
+
+ 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"
+ );
+
+ 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"
+ );
+
+ 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"
+ );
+
+ 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"
+ );
+
+ 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"
+ );
+
+ return reg0;
+}
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/include/armv7-m/irq.h b/nuttx/arch/arm/include/armv7-m/irq.h
new file mode 100644
index 000000000..6cef85c02
--- /dev/null
+++ b/nuttx/arch/arm/include/armv7-m/irq.h
@@ -0,0 +1,306 @@
+/****************************************************************************
+ * arch/arm/include/armv7-m/irq.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+
+#include <nuttx/irq.h>
+#ifndef __ASSEMBLY__
+# include <stdint.h>
+#endif
+
+/* Included implementation-dependent register save structure layouts */
+
+#ifdef CONFIG_ARMV7M_CMNVECTOR
+# include <arch/armv7-m/irq_cmnvector.h>
+#else
+# include <arch/armv7-m/irq_lazyfpu.h>
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* 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
+ ****************************************************************************/
+
+/* The following structure is included in the TCB and defines the complete
+ * state of the thread.
+ */
+
+#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, PRIMASK, and xPSR used during
+ * signal processing.
+ */
+
+ uint32_t saved_pc;
+ uint32_t saved_primask;
+ uint32_t saved_xpsr;
+#endif
+
+ /* Register save area */
+
+ uint32_t regs[XCPTCONTEXT_REGS];
+};
+#endif
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/* Disable IRQs */
+
+static inline void irqdisable(void)
+{
+ __asm__ __volatile__ ("\tcpsid i\n");
+}
+
+/* Save the current primask state & disable IRQs */
+
+static inline irqstate_t irqsave(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 irqenable(void)
+{
+ __asm__ __volatile__ ("\tcpsie i\n");
+}
+
+/* Restore saved primask state */
+
+static inline void irqrestore(irqstate_t primask)
+{
+ /* If bit 0 of the primask is 0, then we need to restore
+ * interupts.
+ */
+
+ __asm__ __volatile__
+ (
+ "\ttst %0, #1\n"
+ "\tbne 1f\n"
+ "\tcpsie i\n"
+ "1:\n"
+ :
+ : "r" (primask)
+ : "memory");
+}
+
+/* Get/set the primask register */
+
+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)
+{
+ __asm__ __volatile__
+ (
+ "\tmsr primask, %0\n"
+ :
+ : "r" (primask)
+ : "memory");
+}
+
+/* Get/set the basepri register */
+
+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)
+{
+ __asm__ __volatile__
+ (
+ "\tmsr basepri, %0\n"
+ :
+ : "r" (basepri)
+ : "memory");
+}
+
+/* Get/set IPSR */
+
+static inline uint32_t getipsr(void)
+{
+ uint32_t ipsr;
+ __asm__ __volatile__
+ (
+ "\tmrs %0, ipsr\n"
+ : "=r" (ipsr)
+ :
+ : "memory");
+ return ipsr;
+}
+
+static inline void setipsr(uint32_t ipsr)
+{
+ __asm__ __volatile__
+ (
+ "\tmsr ipsr, %0\n"
+ :
+ : "r" (ipsr)
+ : "memory");
+}
+
+/* Get/set CONTROL */
+
+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)
+{
+ __asm__ __volatile__
+ (
+ "\tmsr control, %0\n"
+ :
+ : "r" (control)
+ : "memory");
+}
+
+#endif /* __ASSEMBLY__ */
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/include/armv7-m/irq_cmnvector.h b/nuttx/arch/arm/include/armv7-m/irq_cmnvector.h
new file mode 100644
index 000000000..e646731eb
--- /dev/null
+++ b/nuttx/arch/arm/include/armv7-m/irq_cmnvector.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+ * arch/arm/include/armv7-m/irq_cmnvector.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 */
+#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 */
+#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 Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#endif /* __ARCH_ARM_INCLUDE_ARMV7_M_IRQ_CMNVECTOR_H */
+
diff --git a/nuttx/arch/arm/include/armv7-m/irq_lazyfpu.h b/nuttx/arch/arm/include/armv7-m/irq_lazyfpu.h
new file mode 100644
index 000000000..2c3600b7f
--- /dev/null
+++ b/nuttx/arch/arm/include/armv7-m/irq_lazyfpu.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+ * arch/arm/include/armv7-m/irq.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 */
+#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 */
+
+#ifdef CONFIG_NUTTX_KERNEL
+# 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<n>
+ * S<2n+1> maps to the most significant half of D<n>.
+ */
+
+#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 Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#endif /* __ARCH_ARM_INCLUDE_ARMV7_M_IRQ_LAZYFPU_H */
+
diff --git a/nuttx/arch/arm/include/armv7-m/syscall.h b/nuttx/arch/arm/include/armv7-m/syscall.h
new file mode 100644
index 000000000..4278c3a36
--- /dev/null
+++ b/nuttx/arch/arm/include/armv7-m/syscall.h
@@ -0,0 +1,243 @@
+/****************************************************************************
+ * arch/arm/include/armv7-m/syscall.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+
+#ifndef __ASSEMBLY__
+# include <stdint.h>
+#endif
+
+/****************************************************************************
+ * Pro-processor Definitions
+ ****************************************************************************/
+
+#define SYS_syscall 0x00
+
+/****************************************************************************
+ * 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 */
+
+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 */
+
+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 */
+
+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 Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/include/c5471/irq.h b/nuttx/arch/arm/include/c5471/irq.h
new file mode 100644
index 000000000..97aa0352a
--- /dev/null
+++ b/nuttx/arch/arm/include/c5471/irq.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+ * arch/arm/include/c5471/irq.h
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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 Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/include/calypso/armio.h b/nuttx/arch/arm/include/calypso/armio.h
new file mode 100644
index 000000000..9502e835e
--- /dev/null
+++ b/nuttx/arch/arm/include/calypso/armio.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+ * Driver for Calypso ARMIO
+ *
+ * Copyright (C) 2011 Stefan Richter. All rights reserved.
+ * Author: Stefan Richter <ichgeh@l--putt.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+
+
+/****************************************************************************
+ * Prototypes for interrupt handling
+ ****************************************************************************/
+
+void calypso_kbd_irq();
+void calypso_gpio_irq();
+
+
+/****************************************************************************
+ * Initialize device, add /dev/... nodes
+ ****************************************************************************/
+
+void calypso_armio(void);
+void calypso_keypad(void);
diff --git a/nuttx/arch/arm/include/calypso/clock.h b/nuttx/arch/arm/include/calypso/clock.h
new file mode 100644
index 000000000..abcfde1d4
--- /dev/null
+++ b/nuttx/arch/arm/include/calypso/clock.h
@@ -0,0 +1,67 @@
+#ifndef _CALYPSO_CLK_H
+#define _CALYPSO_CLK_H
+
+#include <stdint.h>
+
+#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/nuttx/arch/arm/include/calypso/debug.h b/nuttx/arch/arm/include/calypso/debug.h
new file mode 100644
index 000000000..27c4185d7
--- /dev/null
+++ b/nuttx/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, args ...) printf(x, ## args)
+#else
+#define dputchar(x)
+#define dputs(x)
+#define dphex(x,y)
+#define printd(x, args ...)
+#endif
+
+#endif /* _DEBUG_H */
diff --git a/nuttx/arch/arm/include/calypso/defines.h b/nuttx/arch/arm/include/calypso/defines.h
new file mode 100644
index 000000000..3c8732f92
--- /dev/null
+++ b/nuttx/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/nuttx/arch/arm/include/calypso/irq.h b/nuttx/arch/arm/include/calypso/irq.h
new file mode 100644
index 000000000..fd579c4d3
--- /dev/null
+++ b/nuttx/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 <laforge@gnumonks.org>
+ * (C) 2011 by Stefan Richter <ichgeh@l--putt.de>
+ *
+ * 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 <nuttx/irq.h>"
+#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/nuttx/arch/arm/include/calypso/memory.h b/nuttx/arch/arm/include/calypso/memory.h
new file mode 100644
index 000000000..b0a0490ce
--- /dev/null
+++ b/nuttx/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/nuttx/arch/arm/include/calypso/timer.h b/nuttx/arch/arm/include/calypso/timer.h
new file mode 100644
index 000000000..694e4ebc9
--- /dev/null
+++ b/nuttx/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/nuttx/arch/arm/include/calypso/uwire.h b/nuttx/arch/arm/include/calypso/uwire.h
new file mode 100644
index 000000000..19a277bcc
--- /dev/null
+++ b/nuttx/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/nuttx/arch/arm/include/dm320/irq.h b/nuttx/arch/arm/include/dm320/irq.h
new file mode 100644
index 000000000..320b56614
--- /dev/null
+++ b/nuttx/arch/arm/include/dm320/irq.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+ * arch/arm/include/dm320/irq.h
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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 Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/include/imx/irq.h b/nuttx/arch/arm/include/imx/irq.h
new file mode 100644
index 000000000..28158bb8d
--- /dev/null
+++ b/nuttx/arch/arm/include/imx/irq.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+ * arch/arm/include/imx/irq.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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_IMX_IRQ_H
+#define __ARCH_ARM_INCLUDE_IMX_IRQ_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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 Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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_IMX_IRQ_H */
+
diff --git a/nuttx/arch/arm/include/irq.h b/nuttx/arch/arm/include/irq.h
new file mode 100644
index 000000000..bde751b99
--- /dev/null
+++ b/nuttx/arch/arm/include/irq.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+ * arch/arm/include/irq.h
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/irq.h>
+
+/* Include chip-specific IRQ definitions (including IRQ numbers) */
+
+#include <arch/chip/irq.h>
+
+/* Include ARM architecture-specific IRQ definitions (including register
+ * save structure and irqsave()/irqrestore() macros)
+ */
+
+#if defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4)
+# include <arch/armv7-m/irq.h>
+#else
+# include <arch/arm/irq.h>
+#endif
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/include/kinetis/irq.h b/nuttx/arch/arm/include/kinetis/irq.h
new file mode 100644
index 000000000..8a020ea1b
--- /dev/null
+++ b/nuttx/arch/arm/include/kinetis/irq.h
@@ -0,0 +1,343 @@
+/************************************************************************************
+ * arch/arm/include/kinetis/irq.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+#include <nuttx/irq.h>
+
+/************************************************************************************
+ * 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)
+
+/* K40 Family ***********************************************************************
+ *
+ * The interrupt vectors for the following parts is defined in Freescale document
+ * K40P144M100SF2RM
+ */
+
+#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 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)
+
+# 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 numver 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) /* 97 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 memory map is 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/nuttx/arch/arm/include/limits.h b/nuttx/arch/arm/include/limits.h
new file mode 100644
index 000000000..12c92f6cf
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+#define CHAR_BIT 8
+#define SCHAR_MIN (-128)
+#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 (-32768)
+#define SHRT_MAX 32767
+#define USHRT_MAX 65535
+
+#define INT_MIN (-2147483648)
+#define INT_MAX 2147483647
+#define UINT_MAX 4294967295
+
+/* These change on 32-bit and 64-bit platforms */
+
+#define LONG_MIN (-2147483648L)
+#define LONG_MAX 2147483647L
+#define ULONG_MAX 4294967295UL
+
+#define LLONG_MIN (-9223372036854775808LL)
+#define LLONG_MAX 9223372036854775807LL
+#define ULLONG_MAX 18446744073709551615ULL
+
+/* A pointer is 4 bytes */
+
+#define PTR_MIN (-2147483648)
+#define PTR_MAX 2147483647
+#define UPTR_MAX 4294967295
+
+#endif /* __ARCH_ARM_INCLUDE_LIMITS_H */
diff --git a/nuttx/arch/arm/include/lm3s/irq.h b/nuttx/arch/arm/include/lm3s/irq.h
new file mode 100644
index 000000000..6ffc7dec0
--- /dev/null
+++ b/nuttx/arch/arm/include/lm3s/irq.h
@@ -0,0 +1,497 @@
+/************************************************************************************
+ * arch/arm/include/lm3s/irq.h
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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_LM3S_IRQ_H
+#define __ARCH_ARM_INCLUDE_LM3S_IRQ_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+
+/************************************************************************************
+ * 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 LM3S_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 LM3S_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */
+#define LM3S_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */
+#define LM3S_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */
+#define LM3S_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */
+#define LM3S_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */
+#define LM3S_IRQ_SVCALL (11) /* Vector 11: SVC call */
+#define LM3S_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */
+ /* Vector 13: Reserved */
+#define LM3S_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */
+#define LM3S_IRQ_SYSTICK (15) /* Vector 15: System tick */
+
+/* External interrupts (vectors >= 16) */
+
+#define LM3S_IRQ_INTERRUPTS (16) /* Vector number of the first external interrupt */
+#if defined(CONFIG_ARCH_CHIP_LM3S6918)
+
+# define LM3S_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */
+# define LM3S_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */
+# define LM3S_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */
+# define LM3S_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */
+# define LM3S_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */
+# define LM3S_IRQ_UART0 (21) /* Vector 21: UART 0 */
+# define LM3S_IRQ_UART1 (22) /* Vector 22: UART 1 */
+# define LM3S_IRQ_SSI0 (23) /* Vector 23: SSI 0 */
+# define LM3S_IRQ_I2C0 (24) /* Vector 24: I2C 0 */
+ /* Vector 25-29: Reserved */
+# define LM3S_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */
+# define LM3S_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */
+# define LM3S_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */
+# define LM3S_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */
+# define LM3S_IRQ_WDOG (34) /* Vector 34: Watchdog Timer */
+# define LM3S_IRQ_TIMER0A (35) /* Vector 35: Timer 0 A */
+# define LM3S_IRQ_TIMER0B (36) /* Vector 36: Timer 0 B */
+# define LM3S_IRQ_TIMER1A (37) /* Vector 37: Timer 1 A */
+# define LM3S_IRQ_TIMER1B (38) /* Vector 38: Timer 1 B */
+# define LM3S_IRQ_TIMER2A (39) /* Vector 39: Timer 2 A */
+# define LM3S_IRQ_TIMER2B (40) /* Vector 40: Timer 3 B */
+# define LM3S_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */
+# define LM3S_IRQ_COMPARE1 (42) /* Vector 42: Analog Comparator 1 */
+ /* Vector 43: Reserved */
+# define LM3S_IRQ_SYSCON (44) /* Vector 44: System Control */
+# define LM3S_IRQ_FLASHCON (45) /* Vector 45: FLASH Control */
+# define LM3S_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */
+# define LM3S_IRQ_GPIOG (47) /* Vector 47: GPIO Port G */
+# define LM3S_IRQ_GPIOH (48) /* Vector 48: GPIO Port H */
+ /* Vector 49: Reserved */
+# define LM3S_IRQ_SSI1 (50) /* Vector 50: SSI 1 */
+# define LM3S_IRQ_TIMER3A (51) /* Vector 51: Timer 3 A */
+# define LM3S_IRQ_TIMER3B (52) /* Vector 52: Timer 3 B */
+# define LM3S_IRQ_I2C1 (53) /* Vector 53: I2C 1 */
+ /* Vectors 54-57: Reserved */
+# define LM3S_IRQ_ETHCON (58) /* Vector 58: Ethernet Controller */
+# define LM3S_IRQ_HIBERNATE (59) /* Vector 59: Hibernation Module */
+ /* Vectors 60-70: Reserved */
+# define NR_IRQS (60) /* (Really less because of reserved vectors) */
+#elif defined(CONFIG_ARCH_CHIP_LM3S6432)
+# define LM3S_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */
+# define LM3S_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */
+# define LM3S_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */
+# define LM3S_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */
+# define LM3S_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */
+# define LM3S_IRQ_UART0 (21) /* Vector 21: UART 0 */
+# define LM3S_IRQ_UART1 (22) /* Vector 22: UART 1 */
+# define LM3S_IRQ_SSI0 (23) /* Vector 23: SSI 0 */
+# define LM3S_IRQ_I2C0 (24) /* Vector 24: I2C 0 */
+ /* Vector 25: Reserved */
+# define LM3S_IRQ_PWM0 (26) /* Vector 26: PWM Generator 0 */
+ /* Vectors 27-29: Reserved */
+# define LM3S_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */
+# define LM3S_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */
+# define LM3S_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */
+# define LM3S_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */
+# define LM3S_IRQ_WDOG (34) /* Vector 34: Watchdog Timer */
+# define LM3S_IRQ_TIMER0A (35) /* Vector 35: Timer 0 A */
+# define LM3S_IRQ_TIMER0B (36) /* Vector 36: Timer 0 B */
+# define LM3S_IRQ_TIMER1A (37) /* Vector 37: Timer 1 A */
+# define LM3S_IRQ_TIMER1B (38) /* Vector 38: Timer 1 B */
+# define LM3S_IRQ_TIMER2A (39) /* Vector 39: Timer 2 A */
+# define LM3S_IRQ_TIMER2B (40) /* Vector 40: Timer 3 B */
+# define LM3S_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */
+# define LM3S_IRQ_COMPARE1 (42) /* Vector 42: Analog Comparator 1 */
+ /* Vector 43: Reserved */
+# define LM3S_IRQ_SYSCON (44) /* Vector 44: System Control */
+# define LM3S_IRQ_FLASHCON (45) /* Vector 45: FLASH Control */
+# define LM3S_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */
+# define LM3S_IRQ_GPIOG (47) /* Vector 47: GPIO Port G */
+ /* Vectors 48-57: Reserved */
+# define LM3S_IRQ_ETHCON (58) /* Vector 58: Ethernet Controller */
+ /* Vectors 59-70: Reserved */
+# define NR_IRQS (60) /* (Really less because of reserved vectors) */
+#elif defined(CONFIG_ARCH_CHIP_LM3S6965)
+# define LM3S_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */
+# define LM3S_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */
+# define LM3S_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */
+# define LM3S_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */
+# define LM3S_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */
+# define LM3S_IRQ_UART0 (21) /* Vector 21: UART 0 */
+# define LM3S_IRQ_UART1 (22) /* Vector 22: UART 1 */
+# define LM3S_IRQ_SSI0 (23) /* Vector 23: SSI 0 */
+# define LM3S_IRQ_I2C0 (24) /* Vector 24: I2C 0 */
+# define LM3S_IRQ_PWMFAULT (25) /* Vector 25: PWM Fault */
+# define LM3S_IRQ_PWM0 (26) /* Vector 26: PWM Generator 0 */
+# define LM3S_IRQ_PWM1 (27) /* Vector 27: PWM Generator 1 */
+# define LM3S_IRQ_PWM2 (28) /* Vector 28: PWM Generator 2 */
+# define LM3S_IRQ_QEI0 (29) /* Vector 29: QEI0 */
+# define LM3S_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */
+# define LM3S_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */
+# define LM3S_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */
+# define LM3S_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */
+# define LM3S_IRQ_WDOG (34) /* Vector 34: Watchdog Timer */
+# define LM3S_IRQ_TIMER0A (35) /* Vector 35: Timer 0 A */
+# define LM3S_IRQ_TIMER0B (36) /* Vector 36: Timer 0 B */
+# define LM3S_IRQ_TIMER1A (37) /* Vector 37: Timer 1 A */
+# define LM3S_IRQ_TIMER1B (38) /* Vector 38: Timer 1 B */
+# define LM3S_IRQ_TIMER2A (39) /* Vector 39: Timer 2 A */
+# define LM3S_IRQ_TIMER2B (40) /* Vector 40: Timer 3 B */
+# define LM3S_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */
+# define LM3S_IRQ_COMPARE1 (42) /* Vector 42: Analog Comparator 1 */
+ /* Vector 43: Reserved */
+# define LM3S_IRQ_SYSCON (44) /* Vector 44: System Control */
+# define LM3S_IRQ_FLASHCON (45) /* Vector 45: FLASH Control */
+# define LM3S_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */
+# define LM3S_IRQ_GPIOG (47) /* Vector 47: GPIO Port G */
+ /* Vector 48: Reserved */
+# define LM3S_IRQ_UART2 (49) /* Vector 49: UART 2 */
+ /* Vector 50: Reserved */
+# define LM3S_IRQ_TIMER3A (51) /* Vector 51: Timer 3 A */
+# define LM3S_IRQ_TIMER3B (52) /* Vector 52: Timer 3 B */
+# define LM3S_IRQ_I2C1 (53) /* Vector 53: I2C 1 */
+# define LM3S_IRQ_QEI1 (54) /* Vector 54: QEI1 */
+ /* Vectors 55-57: Reserved */
+# define LM3S_IRQ_ETHCON (58) /* Vector 58: Ethernet Controller */
+# define LM3S_IRQ_HIBERNATE (59) /* Vector 59: Hibernation Module */
+ /* Vectors 60-70: Reserved */
+# define NR_IRQS (60) /* (Really less because of reserved vectors) */
+#elif defined(CONFIG_ARCH_CHIP_LM3S9B96)
+# define LM3S_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */
+# define LM3S_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */
+# define LM3S_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */
+# define LM3S_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */
+# define LM3S_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */
+# define LM3S_IRQ_UART0 (21) /* Vector 21: UART 0 */
+# define LM3S_IRQ_UART1 (22) /* Vector 22: UART 1 */
+# define LM3S_IRQ_SSI0 (23) /* Vector 23: SSI 0 */
+# define LM3S_IRQ_I2C0 (24) /* Vector 24: I2C 0 */
+# define LM3S_IRQ_PWMFAULT (25) /* Vector 25: PWM Fault */
+# define LM3S_IRQ_PWM0 (26) /* Vector 26: PWM Generator 0 */
+# define LM3S_IRQ_PWM1 (27) /* Vector 27: PWM Generator 1 */
+# define LM3S_IRQ_PWM2 (28) /* Vector 28: PWM Generator 2 */
+# define LM3S_IRQ_QEI0 (29) /* Vector 29: QEI0 */
+# define LM3S_IRQ_ADC0 (30) /* Vector 30: ADC0 Sequence 0 */
+# define LM3S_IRQ_ADC1 (31) /* Vector 31: ADC0 Sequence 1 */
+# define LM3S_IRQ_ADC2 (32) /* Vector 32: ADC0 Sequence 2 */
+# define LM3S_IRQ_ADC3 (33) /* Vector 33: ADC0 Sequence 3 */
+# define LM3S_IRQ_WDOG (34) /* Vector 34: Watchdog Timer */
+# define LM3S_IRQ_TIMER0A (35) /* Vector 35: Timer 0 A */
+# define LM3S_IRQ_TIMER0B (36) /* Vector 36: Timer 0 B */
+# define LM3S_IRQ_TIMER1A (37) /* Vector 37: Timer 1 A */
+# define LM3S_IRQ_TIMER1B (38) /* Vector 38: Timer 1 B */
+# define LM3S_IRQ_TIMER2A (39) /* Vector 39: Timer 2 A */
+# define LM3S_IRQ_TIMER2B (40) /* Vector 40: Timer 3 B */
+# define LM3S_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */
+# define LM3S_IRQ_COMPARE1 (42) /* Vector 42: Analog Comparator 1 */
+# define LM3S_IRQ_COMPARE2 (43) /* Vector 43: Analog Comparator 3 */
+# define LM3S_IRQ_SYSCON (44) /* Vector 44: System Control */
+# define LM3S_IRQ_FLASHCON (45) /* Vector 45: FLASH Control */
+# define LM3S_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */
+# define LM3S_IRQ_GPIOG (47) /* Vector 47: GPIO Port G */
+# define LM3S_IRQ_GPIOH (48) /* Vector 48: GPIO Port H */
+# define LM3S_IRQ_UART2 (49) /* Vector 49: UART 2 */
+# define LM3S_IRQ_SSI1 (50) /* Vector 50: SSI 1 */
+# define LM3S_IRQ_TIMER3A (51) /* Vector 51: Timer 3 A */
+# define LM3S_IRQ_TIMER3B (52) /* Vector 52: Timer 3 B */
+# define LM3S_IRQ_I2C1 (53) /* Vector 53: I2C 1 */
+# define LM3S_IRQ_QEI1 (54) /* Vector 54: QEI1 */
+# define LM3S_IRQ_CAN0 (55) /* Vector 55: CAN 1 */
+# define LM3S_IRQ_CAN1 (56) /* Vector 56: CAN 2 */
+ /* Vector 57: Reserved */
+# define LM3S_IRQ_ETHCON (58) /* Vector 58: Ethernet Controller */
+ /* Vector 59: Reserved */
+# define LM3S_IRQ_USB (60) /* Vector 60: USB */
+# define LM3S_IRQ_PWM3 (61) /* Vector 61: PWM Generator 3 */
+# define LM3S_IRQ_UDMASOFT (62) /* Vector 62: uDMA Software */
+# define LM3S_IRQ_UDMAERROR (63) /* Vector 63: uDMA Error */
+# define LM3S_IRQ_ADC1_0 (64) /* Vector 64: ADC1 Sequence 0 */
+# define LM3S_IRQ_ADC1_1 (65) /* Vector 65: ADC1 Sequence 1 */
+# define LM3S_IRQ_ADC1_2 (66) /* Vector 66: ADC1 Sequence 2 */
+# define LM3S_IRQ_ADC1_3 (67) /* Vector 67: ADC1 Sequence 3 */
+# define LM3S_IRQ_I2S0 (68) /* Vector 68: I2S0 */
+# define LM3S_IRQ_EPI (69) /* Vector 69: EPI */
+# define LM3S_IRQ_GPIOJ (70) /* Vector 70: GPIO Port J */
+ /* Vector 71: Reserved */
+# define NR_IRQS (71) /* (Really less because of reserved vectors) */
+#elif defined(CONFIG_ARCH_CHIP_LM3S8962)
+# define LM3S_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */
+# define LM3S_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */
+# define LM3S_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */
+# define LM3S_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */
+# define LM3S_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */
+# define LM3S_IRQ_UART0 (21) /* Vector 21: UART 0 */
+# define LM3S_IRQ_UART1 (22) /* Vector 22: UART 1 */
+# define LM3S_IRQ_SSI0 (23) /* Vector 23: SSI 0 */
+# define LM3S_IRQ_I2C0 (24) /* Vector 24: I2C 0 */
+# define LM3S_IRQ_PWMFAULT (25) /* Vector 25: PWM Fault */
+# define LM3S_IRQ_PWM0 (26) /* Vector 26: PWM Generator 0 */
+# define LM3S_IRQ_PWM1 (27) /* Vector 27: PWM Generator 1 */
+# define LM3S_IRQ_PWM2 (28) /* Vector 28: PWM Generator 2 */
+# define LM3S_IRQ_QEI0 (29) /* Vector 29: QEI0 */
+# define LM3S_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */
+# define LM3S_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */
+# define LM3S_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */
+# define LM3S_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */
+# define LM3S_IRQ_WDOG (34) /* Vector 34: Watchdog Timer */
+# define LM3S_IRQ_TIMER0A (35) /* Vector 35: Timer 0 A */
+# define LM3S_IRQ_TIMER0B (36) /* Vector 36: Timer 0 B */
+# define LM3S_IRQ_TIMER1A (37) /* Vector 37: Timer 1 A */
+# define LM3S_IRQ_TIMER1B (38) /* Vector 38: Timer 1 B */
+# define LM3S_IRQ_TIMER2A (39) /* Vector 39: Timer 2 A */
+# define LM3S_IRQ_TIMER2B (40) /* Vector 40: Timer 3 B */
+# define LM3S_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */
+ /* Vector 42: Reserved */
+ /* Vector 43: Reserved */
+# define LM3S_IRQ_SYSCON (44) /* Vector 44: System Control */
+# define LM3S_IRQ_FLASHCON (45) /* Vector 45: FLASH Control */
+# define LM3S_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */
+# define LM3S_IRQ_GPIOG (47) /* Vector 47: GPIO Port G */
+ /* Vector 48: Reserved */
+ /* Vector 49: Reserved */
+ /* Vector 50: Reserved */
+# define LM3S_IRQ_TIMER3A (51) /* Vector 51: Timer 3 A */
+# define LM3S_IRQ_TIMER3B (52) /* Vector 52: Timer 3 B */
+# define LM3S_IRQ_I2C1 (53) /* Vector 53: I2C 1 */
+# define LM3S_IRQ_QEI1 (54) /* Vector 54: QEI1 */
+# define LM3S_IRQ_CAN0 (54) /* Vector 55: CAN0 */
+ /* Vectors 56-57: Reserved */
+# define LM3S_IRQ_ETHCON (58) /* Vector 58: Ethernet Controller */
+# define LM3S_IRQ_HIBERNATE (59) /* Vector 59: Hibernation Module */
+ /* Vectors 60-70: Reserved */
+# define NR_IRQS (60) /* (Really less because of reserved vectors) */
+#else
+# error "IRQ Numbers not specified for this LM3S chip"
+#endif
+
+/* GPIO IRQs -- Note that support for individual GPIO ports can
+ * be disabled in order to reduce the size of the implemenation.
+ */
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOA_IRQS
+# define LM3S_IRQ_GPIOA_0 (NR_IRQS + 0)
+# define LM3S_IRQ_GPIOA_1 (NR_IRQS + 1)
+# define LM3S_IRQ_GPIOA_2 (NR_IRQS + 2)
+# define LM3S_IRQ_GPIOA_3 (NR_IRQS + 3)
+# define LM3S_IRQ_GPIOA_4 (NR_IRQS + 4)
+# define LM3S_IRQ_GPIOA_5 (NR_IRQS + 5)
+# define LM3S_IRQ_GPIOA_6 (NR_IRQS + 6)
+# define LM3S_IRQ_GPIOA_7 (NR_IRQS + 7)
+# define _NGPIOAIRQS (NR_IRQS + 8)
+#else
+# define _NGPIOAIRQS NR_IRQS
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOB_IRQS
+# define LM3S_IRQ_GPIOB_0 (_NGPIOAIRQS + 0)
+# define LM3S_IRQ_GPIOB_1 (_NGPIOAIRQS + 1)
+# define LM3S_IRQ_GPIOB_2 (_NGPIOAIRQS + 2)
+# define LM3S_IRQ_GPIOB_3 (_NGPIOAIRQS + 3)
+# define LM3S_IRQ_GPIOB_4 (_NGPIOAIRQS + 4)
+# define LM3S_IRQ_GPIOB_5 (_NGPIOAIRQS + 5)
+# define LM3S_IRQ_GPIOB_6 (_NGPIOAIRQS + 6)
+# define LM3S_IRQ_GPIOB_7 (_NGPIOAIRQS + 7)
+# define _NGPIOBIRQS (_NGPIOAIRQS + 8)
+#else
+# define _NGPIOBIRQS _NGPIOAIRQS
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOC_IRQS
+# define LM3S_IRQ_GPIOC_0 (_NGPIOBIRQS + 0)
+# define LM3S_IRQ_GPIOC_1 (_NGPIOBIRQS + 1)
+# define LM3S_IRQ_GPIOC_2 (_NGPIOBIRQS + 2)
+# define LM3S_IRQ_GPIOC_3 (_NGPIOBIRQS + 3)
+# define LM3S_IRQ_GPIOC_4 (_NGPIOBIRQS + 4)
+# define LM3S_IRQ_GPIOC_5 (_NGPIOBIRQS + 5)
+# define LM3S_IRQ_GPIOC_6 (_NGPIOBIRQS + 6)
+# define LM3S_IRQ_GPIOC_7 (_NGPIOBIRQS + 7)
+# define _NGPIOCIRQS (_NGPIOBIRQS + 8)
+#else
+# define _NGPIOCIRQS _NGPIOBIRQS
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOD_IRQS
+# define LM3S_IRQ_GPIOD_0 (_NGPIOCIRQS + 0)
+# define LM3S_IRQ_GPIOD_1 (_NGPIOCIRQS + 1)
+# define LM3S_IRQ_GPIOD_2 (_NGPIOCIRQS + 2)
+# define LM3S_IRQ_GPIOD_3 (_NGPIOCIRQS + 3)
+# define LM3S_IRQ_GPIOD_4 (_NGPIOCIRQS + 4)
+# define LM3S_IRQ_GPIOD_5 (_NGPIOCIRQS + 5)
+# define LM3S_IRQ_GPIOD_6 (_NGPIOCIRQS + 6)
+# define LM3S_IRQ_GPIOD_7 (_NGPIOCIRQS + 7)
+# define _NGPIODIRQS (_NGPIOCIRQS + 8)
+#else
+# define _NGPIODIRQS _NGPIOCIRQS
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOE_IRQS
+# define LM3S_IRQ_GPIOE_0 (_NGPIODIRQS + 0)
+# define LM3S_IRQ_GPIOE_1 (_NGPIODIRQS + 1)
+# define LM3S_IRQ_GPIOE_2 (_NGPIODIRQS + 2)
+# define LM3S_IRQ_GPIOE_3 (_NGPIODIRQS + 3)
+# define LM3S_IRQ_GPIOE_4 (_NGPIODIRQS + 4)
+# define LM3S_IRQ_GPIOE_5 (_NGPIODIRQS + 5)
+# define LM3S_IRQ_GPIOE_6 (_NGPIODIRQS + 6)
+# define LM3S_IRQ_GPIOE_7 (_NGPIODIRQS + 7)
+# define _NGPIOEIRQS (_NGPIODIRQS + 8)
+#else
+# define _NGPIOEIRQS _NGPIODIRQS
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOF_IRQS
+# define LM3S_IRQ_GPIOF_0 (_NGPIOEIRQS + 0)
+# define LM3S_IRQ_GPIOF_1 (_NGPIOEIRQS + 1)
+# define LM3S_IRQ_GPIOF_2 (_NGPIOEIRQS + 2)
+# define LM3S_IRQ_GPIOF_3 (_NGPIOEIRQS + 3)
+# define LM3S_IRQ_GPIOF_4 (_NGPIOEIRQS + 4)
+# define LM3S_IRQ_GPIOF_5 (_NGPIOEIRQS + 5)
+# define LM3S_IRQ_GPIOF_6 (_NGPIOEIRQS + 6)
+# define LM3S_IRQ_GPIOF_7 (_NGPIOEIRQS + 7)
+# define _NGPIOFIRQS (_NGPIOEIRQS + 8)
+#else
+# define _NGPIOFIRQS _NGPIOEIRQS
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOG_IRQS
+# define LM3S_IRQ_GPIOG_0 (_NGPIOFIRQS + 0)
+# define LM3S_IRQ_GPIOG_1 (_NGPIOFIRQS + 1)
+# define LM3S_IRQ_GPIOG_2 (_NGPIOFIRQS + 2)
+# define LM3S_IRQ_GPIOG_3 (_NGPIOFIRQS + 3)
+# define LM3S_IRQ_GPIOG_4 (_NGPIOFIRQS + 4)
+# define LM3S_IRQ_GPIOG_5 (_NGPIOFIRQS + 5)
+# define LM3S_IRQ_GPIOG_6 (_NGPIOFIRQS + 6)
+# define LM3S_IRQ_GPIOG_7 (_NGPIOFIRQS + 7)
+# define _NGPIOGIRQS (_NGPIOFIRQS + 8)
+#else
+# define _NGPIOGIRQS _NGPIOFIRQS
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOH_IRQS
+# define LM3S_IRQ_GPIOH_0 (_NGPIOGIRQS + 0)
+# define LM3S_IRQ_GPIOH_1 (_NGPIOGIRQS + 1)
+# define LM3S_IRQ_GPIOH_2 (_NGPIOGIRQS + 2)
+# define LM3S_IRQ_GPIOH_3 (_NGPIOGIRQS + 3)
+# define LM3S_IRQ_GPIOH_4 (_NGPIOGIRQS + 4)
+# define LM3S_IRQ_GPIOH_5 (_NGPIOGIRQS + 5)
+# define LM3S_IRQ_GPIOH_6 (_NGPIOGIRQS + 6)
+# define LM3S_IRQ_GPIOH_7 (_NGPIOGIRQS + 7)
+# define _NGPIOHIRQS (_NGPIOGIRQS + 8)
+#else
+# define _NGPIOHIRQS _NGPIOGIRQS
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOJ_IRQS
+# define LM3S_IRQ_GPIOJ_0 (_NGPIOHIRQS + 0)
+# define LM3S_IRQ_GPIOJ_1 (_NGPIOHIRQS + 1)
+# define LM3S_IRQ_GPIOJ_2 (_NGPIOHIRQS + 2)
+# define LM3S_IRQ_GPIOJ_3 (_NGPIOHIRQS + 3)
+# define LM3S_IRQ_GPIOJ_4 (_NGPIOHIRQS + 4)
+# define LM3S_IRQ_GPIOJ_5 (_NGPIOHIRQS + 5)
+# define LM3S_IRQ_GPIOJ_6 (_NGPIOHIRQS + 6)
+# define LM3S_IRQ_GPIOJ_7 (_NGPIOHIRQS + 7)
+# define _NGPIOJIRQS (_NGPIOHIRQS + 8)
+#else
+# define _NGPIOJIRQS _NGPIOHIRQS
+#endif
+
+#define NR_GPIO_IRQS (_NGPIOJIRQS - NR_IRQS)
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/****************************************************************************
+ * Name: gpio_irqattach
+ *
+ * Description:
+ * Attach the interrupt handler 'isr' to the GPIO IRQ 'irq'
+ *
+ ****************************************************************************/
+
+EXTERN int gpio_irqattach(int irq, xcpt_t isr);
+#define gpio_irqdetach(isr) gpio_irqattach(isr, NULL)
+
+/****************************************************************************
+ * Name: gpio_irqenable
+ *
+ * Description:
+ * Enable the GPIO IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+EXTERN void gpio_irqenable(int irq);
+
+/****************************************************************************
+ * Name: gpio_irqdisable
+ *
+ * Description:
+ * Disable the GPIO IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+EXTERN void gpio_irqdisable(int irq);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif /* __ARCH_ARM_INCLUDE_LM3S_IRQ_H */
+
diff --git a/nuttx/arch/arm/include/lpc17xx/irq.h b/nuttx/arch/arm/include/lpc17xx/irq.h
new file mode 100644
index 000000000..a7eebb32c
--- /dev/null
+++ b/nuttx/arch/arm/include/lpc17xx/irq.h
@@ -0,0 +1,285 @@
+/****************************************************************************
+ * arch/lpc17xxx/irq.h
+ *
+ * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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_LPC17XX_IRQ_H
+#define __ARCH_LPC17XX_IRQ_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+# include <stdint.h>
+#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 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 */
+#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 interrrupt 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_IRQS (LPC17_IRQ_EXTINT+LPC17_IRQ_NEXTINT+LPC17_NGPIOAIRQS)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+typedef void (*vic_vector_t)(uint32_t *regs);
+#endif
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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_LPC17XX_IRQ_H */
+
diff --git a/nuttx/arch/arm/include/lpc214x/irq.h b/nuttx/arch/arm/include/lpc214x/irq.h
new file mode 100644
index 000000000..5652fc7a9
--- /dev/null
+++ b/nuttx/arch/arm/include/lpc214x/irq.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+ * arch/lpc214x/irq.h
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <stdint.h>
+#endif
+
+/****************************************************************************
+ * 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 Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+#ifndef CONFIG_VECTORED_INTERRUPTS
+EXTERN void up_attach_vector(int irq, int vector, vic_vector_t handler);
+EXTERN void up_detach_vector(int vector);
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif /* __ARCH_LPC214X_IRQ_H */
+
diff --git a/nuttx/arch/arm/include/lpc2378/irq.h b/nuttx/arch/arm/include/lpc2378/irq.h
new file mode 100644
index 000000000..807c99119
--- /dev/null
+++ b/nuttx/arch/arm/include/lpc2378/irq.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+ * arch/lpc2378/irq.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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <stdint.h>
+#endif
+
+/****************************************************************************
+ * 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 Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+#ifndef CONFIG_VECTORED_INTERRUPTS
+EXTERN void up_attach_vector(int irq, int priority, vic_vector_t handler);
+EXTERN void up_detach_vector(int vector);
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif /* __ARCH_LPC2378_IRQ_H */
+
diff --git a/nuttx/arch/arm/include/lpc31xx/irq.h b/nuttx/arch/arm/include/lpc31xx/irq.h
new file mode 100644
index 000000000..d3654a507
--- /dev/null
+++ b/nuttx/arch/arm/include/lpc31xx/irq.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+ * arch/arm/include/lpc31xx/irq.h
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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 Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/include/lpc43xx/chip.h b/nuttx/arch/arm/include/lpc43xx/chip.h
new file mode 100644
index 000000000..220ce38d0
--- /dev/null
+++ b/nuttx/arch/arm/include/lpc43xx/chip.h
@@ -0,0 +1,557 @@
+/************************************************************************************
+ * arch/arm/include/lpc43xx/chip.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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
+ * --------------------- -------- ------- ------- ------- ------- -------
+ * 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.
+ */
+
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (4) /* Four ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (4) /* Four ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (4) /* Four ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#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_NADC (2) /* Two 10-bit ADC controllers */
+# define LPC43_NADC_CHANNELS (8) /* Eight ADC channels */
+#else
+# error "Unsupported LPC43xx chip"
+#endif
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_INCLUDE_LPC43XX_CHIP_H */
diff --git a/nuttx/arch/arm/include/lpc43xx/irq.h b/nuttx/arch/arm/include/lpc43xx/irq.h
new file mode 100644
index 000000000..f2c899a44
--- /dev/null
+++ b/nuttx/arch/arm/include/lpc43xx/irq.h
@@ -0,0 +1,224 @@
+/********************************************************************************************
+ * arch/arm/include/lpc43xxx/irq.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <stdint.h>
+#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_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_IRQS LPC43M0_IRQ_NIRQS
+#endif
+
+/********************************************************************************************
+ * Public Types
+ ********************************************************************************************/
+
+#ifndef __ASSEMBLY__
+typedef void (*vic_vector_t)(uint32_t *regs);
+#endif
+
+/********************************************************************************************
+ * Inline functions
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Variables
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * 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/nuttx/arch/arm/include/sam3u/irq.h b/nuttx/arch/arm/include/sam3u/irq.h
new file mode 100644
index 000000000..481db74a2
--- /dev/null
+++ b/nuttx/arch/arm/include/sam3u/irq.h
@@ -0,0 +1,297 @@
+/****************************************************************************************
+ * arch/arm/include/sam3u/irq.h
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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_SAM3U_IRQ_H
+#define __ARCH_ARM_INCLUDE_SAM3U_IRQ_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Definitions
+ ****************************************************************************************/
+
+/* SAM3U Peripheral Identifiers */
+
+#define SAM3U_PID_SUPC (0) /* Supply Controller */
+#define SAM3U_PID_RSTC (1) /* Reset Controller */
+#define SAM3U_PID_RTC (2) /* Real Time Clock */
+#define SAM3U_PID_RTT (3) /* Real Time Timer */
+#define SAM3U_PID_WDT (4) /* Watchdog Timer */
+#define SAM3U_PID_PMC (5) /* Power Management Controller */
+#define SAM3U_PID_EEFC0 (6) /* Enhanced Embedded Flash Controller 0 */
+#define SAM3U_PID_EEFC1 (7) /* Enhanced Embedded Flash Controller 1 */
+#define SAM3U_PID_UART (8) /* Universal Asynchronous Receiver Transmitter */
+#define SAM3U_PID_SMC (9) /* Static Memory Controller */
+#define SAM3U_PID_PIOA (10) /* Parallel I/O Controller A */
+#define SAM3U_PID_PIOB (11) /* Parallel I/O Controller B */
+#define SAM3U_PID_PIOC (12) /* Parallel I/O Controller C */
+#define SAM3U_PID_USART0 (13) /* USART 0 */
+#define SAM3U_PID_USART1 (14) /* USART 1 */
+#define SAM3U_PID_USART2 (15) /* USART 2 */
+#define SAM3U_PID_USART3 (16) /* USART 3 */
+#define SAM3U_PID_HSMCI (17) /* High Speed Multimedia Card Interface */
+#define SAM3U_PID_TWI0 (18) /* Two-Wire Interface 0 */
+#define SAM3U_PID_TWI1 (19) /* Two-Wire Interface 1 */
+#define SAM3U_PID_SPI (20) /* Serial Peripheral Interface */
+#define SAM3U_PID_SSC (21) /* Synchronous Serial Controller */
+#define SAM3U_PID_TC0 (22) /* Timer Counter 0 */
+#define SAM3U_PID_TC1 (23) /* Timer Counter 1 */
+#define SAM3U_PID_TC2 (24) /* Timer Counter 2 */
+#define SAM3U_PID_PWM (25) /* Pulse Width Modulation Controller */
+#define SAM3U_PID_ADC12B (26) /* 12-bit ADC Controller */
+#define SAM3U_PID_ADC (27) /* 10-bit ADC Controller */
+#define SAM3U_PID_DMAC (28) /* DMA Controller */
+#define SAM3U_PID_UDPHS (29) /* USB Device High Speed */
+#define NR_PIDS (30) /* Number of peripheral identifiers */
+
+/* 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 SAM3U_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 SAM3U_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */
+#define SAM3U_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */
+#define SAM3U_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */
+#define SAM3U_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */
+#define SAM3U_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */
+#define SAM3U_IRQ_SVCALL (11) /* Vector 11: SVC call */
+#define SAM3U_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */
+ /* Vector 13: Reserved */
+#define SAM3U_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */
+#define SAM3U_IRQ_SYSTICK (15) /* Vector 15: System tick */
+
+/* External interrupts (vectors >= 16) */
+
+#define SAM3U_IRQ_EXTINT (16) /* Vector number of the first external interrupt */
+#define SAM3U_IRQ_SUPC (SAM3U_IRQ_EXTINT+SAM3U_PID_SUPC) /* Supply Controller */
+#define SAM3U_IRQ_RSTC (SAM3U_IRQ_EXTINT+SAM3U_PID_RSTC) /* Reset Controller */
+#define SAM3U_IRQ_RTC (SAM3U_IRQ_EXTINT+SAM3U_PID_RTC) /* Real Time Clock */
+#define SAM3U_IRQ_RTT (SAM3U_IRQ_EXTINT+SAM3U_PID_RTT) /* Real Time Timer */
+#define SAM3U_IRQ_WDT (SAM3U_IRQ_EXTINT+SAM3U_PID_WDT) /* Watchdog Timer */
+#define SAM3U_IRQ_PMC (SAM3U_IRQ_EXTINT+SAM3U_PID_PMC) /* Power Management Controller */
+#define SAM3U_IRQ_EEFC0 (SAM3U_IRQ_EXTINT+SAM3U_PID_EEFC0) /* Enhanced Embedded Flash Controller 0 */
+#define SAM3U_IRQ_EEFC1 (SAM3U_IRQ_EXTINT+SAM3U_PID_EEFC1) /* Enhanced Embedded Flash Controller 1 */
+#define SAM3U_IRQ_UART (SAM3U_IRQ_EXTINT+SAM3U_PID_UART) /* Universal Asynchronous Receiver Transmitter */
+#define SAM3U_IRQ_SMC (SAM3U_IRQ_EXTINT+SAM3U_PID_SMC) /* Static Memory Controller */
+#define SAM3U_IRQ_PIOA (SAM3U_IRQ_EXTINT+SAM3U_PID_PIOA) /* Parallel I/O Controller A */
+#define SAM3U_IRQ_PIOB (SAM3U_IRQ_EXTINT+SAM3U_PID_PIOB) /* Parallel I/O Controller B */
+#define SAM3U_IRQ_PIOC (SAM3U_IRQ_EXTINT+SAM3U_PID_PIOC) /* Parallel I/O Controller C */
+#define SAM3U_IRQ_USART0 (SAM3U_IRQ_EXTINT+SAM3U_PID_USART0) /* USART 0 */
+#define SAM3U_IRQ_USART1 (SAM3U_IRQ_EXTINT+SAM3U_PID_USART1) /* USART 1 */
+#define SAM3U_IRQ_USART2 (SAM3U_IRQ_EXTINT+SAM3U_PID_USART2) /* USART 2 */
+#define SAM3U_IRQ_USART3 (SAM3U_IRQ_EXTINT+SAM3U_PID_USART3) /* USART 3 */
+#define SAM3U_IRQ_HSMCI (SAM3U_IRQ_EXTINT+SAM3U_PID_HSMCI) /* High Speed Multimedia Card Interface */
+#define SAM3U_IRQ_TWI0 (SAM3U_IRQ_EXTINT+SAM3U_PID_TWI0) /* Two-Wire Interface 0 */
+#define SAM3U_IRQ_TWI1 (SAM3U_IRQ_EXTINT+SAM3U_PID_TWI1) /* Two-Wire Interface 1 */
+#define SAM3U_IRQ_SPI (SAM3U_IRQ_EXTINT+SAM3U_PID_SPI) /* Serial Peripheral Interface */
+#define SAM3U_IRQ_SSC (SAM3U_IRQ_EXTINT+SAM3U_PID_SSC) /* Synchronous Serial Controller */
+#define SAM3U_IRQ_TC0 (SAM3U_IRQ_EXTINT+SAM3U_PID_TC0) /* Timer Counter 0 */
+#define SAM3U_IRQ_TC1 (SAM3U_IRQ_EXTINT+SAM3U_PID_TC1) /* Timer Counter 1 */
+#define SAM3U_IRQ_TC2 (SAM3U_IRQ_EXTINT+SAM3U_PID_TC2) /* Timer Counter 2 */
+#define SAM3U_IRQ_PWM (SAM3U_IRQ_EXTINT+SAM3U_PID_PWM) /* Pulse Width Modulation Controller */
+#define SAM3U_IRQ_ADC12B (SAM3U_IRQ_EXTINT+SAM3U_PID_ADC12B) /* 12-bit ADC Controller */
+#define SAM3U_IRQ_ADC (SAM3U_IRQ_EXTINT+SAM3U_PID_ADC) /* 10-bit ADC Controller */
+#define SAM3U_IRQ_DMAC (SAM3U_IRQ_EXTINT+SAM3U_PID_DMAC) /* DMA Controller */
+#define SAM3U_IRQ_UDPHS (SAM3U_IRQ_EXTINT+SAM3U_PID_UDPHS) /* USB Device High Speed */
+#define SAM3U_IRQ_NEXTINT NR_PIDS /* Total number of external interrupt numbers */
+#define SAM3U_IRQ_NIRQS (SAM3U_IRQ_EXTINT+NR_PIDS) /* The number of real IRQs */
+
+/* GPIO interrupts (derived from SAM3U_IRQ_PIOA/B/C) */
+
+#ifdef CONFIG_GPIOA_IRQ
+# define SAM3U_IRQ_GPIOA_PINS (SAM3U_IRQ_EXTINT+SAM3U_IRQ_NEXTINT)
+# define SAM3U_IRQ_PA0 (SAM3U_IRQ_GPIOA_PINS+0) /* GPIOA, PIN 0 */
+# define SAM3U_IRQ_PA1 (SAM3U_IRQ_GPIOA_PINS+1) /* GPIOA, PIN 1 */
+# define SAM3U_IRQ_PA2 (SAM3U_IRQ_GPIOA_PINS+2) /* GPIOA, PIN 2 */
+# define SAM3U_IRQ_PA3 (SAM3U_IRQ_GPIOA_PINS+3) /* GPIOA, PIN 3 */
+# define SAM3U_IRQ_PA4 (SAM3U_IRQ_GPIOA_PINS+4) /* GPIOA, PIN 4 */
+# define SAM3U_IRQ_PA5 (SAM3U_IRQ_GPIOA_PINS+5) /* GPIOA, PIN 5 */
+# define SAM3U_IRQ_PA6 (SAM3U_IRQ_GPIOA_PINS+6) /* GPIOA, PIN 6 */
+# define SAM3U_IRQ_PA7 (SAM3U_IRQ_GPIOA_PINS+7) /* GPIOA, PIN 7 */
+# define SAM3U_IRQ_PA8 (SAM3U_IRQ_GPIOA_PINS+8) /* GPIOA, PIN 8 */
+# define SAM3U_IRQ_PA9 (SAM3U_IRQ_GPIOA_PINS+9) /* GPIOA, PIN 9 */
+# define SAM3U_IRQ_PA10 (SAM3U_IRQ_GPIOA_PINS+10) /* GPIOA, PIN 10 */
+# define SAM3U_IRQ_PA11 (SAM3U_IRQ_GPIOA_PINS+11) /* GPIOA, PIN 11 */
+# define SAM3U_IRQ_PA12 (SAM3U_IRQ_GPIOA_PINS+12) /* GPIOA, PIN 12 */
+# define SAM3U_IRQ_PA13 (SAM3U_IRQ_GPIOA_PINS+13) /* GPIOA, PIN 13 */
+# define SAM3U_IRQ_PA14 (SAM3U_IRQ_GPIOA_PINS+14) /* GPIOA, PIN 14 */
+# define SAM3U_IRQ_PA15 (SAM3U_IRQ_GPIOA_PINS+15) /* GPIOA, PIN 15 */
+# define SAM3U_IRQ_PA16 (SAM3U_IRQ_GPIOA_PINS+16) /* GPIOA, PIN 16 */
+# define SAM3U_IRQ_PA17 (SAM3U_IRQ_GPIOA_PINS+17) /* GPIOA, PIN 17 */
+# define SAM3U_IRQ_PA18 (SAM3U_IRQ_GPIOA_PINS+18) /* GPIOA, PIN 18 */
+# define SAM3U_IRQ_PA19 (SAM3U_IRQ_GPIOA_PINS+19) /* GPIOA, PIN 19 */
+# define SAM3U_IRQ_PA20 (SAM3U_IRQ_GPIOA_PINS+20) /* GPIOA, PIN 20 */
+# define SAM3U_IRQ_PA21 (SAM3U_IRQ_GPIOA_PINS+21) /* GPIOA, PIN 21 */
+# define SAM3U_IRQ_PA22 (SAM3U_IRQ_GPIOA_PINS+22) /* GPIOA, PIN 22 */
+# define SAM3U_IRQ_PA23 (SAM3U_IRQ_GPIOA_PINS+23) /* GPIOA, PIN 23 */
+# define SAM3U_IRQ_PA24 (SAM3U_IRQ_GPIOA_PINS+24) /* GPIOA, PIN 24 */
+# define SAM3U_IRQ_PA25 (SAM3U_IRQ_GPIOA_PINS+25) /* GPIOA, PIN 25 */
+# define SAM3U_IRQ_PA26 (SAM3U_IRQ_GPIOA_PINS+26) /* GPIOA, PIN 26 */
+# define SAM3U_IRQ_PA27 (SAM3U_IRQ_GPIOA_PINS+27) /* GPIOA, PIN 27 */
+# define SAM3U_IRQ_PA28 (SAM3U_IRQ_GPIOA_PINS+28) /* GPIOA, PIN 28 */
+# define SAM3U_IRQ_PA29 (SAM3U_IRQ_GPIOA_PINS+29) /* GPIOA, PIN 29 */
+# define SAM3U_IRQ_PA30 (SAM3U_IRQ_GPIOA_PINS+30) /* GPIOA, PIN 30 */
+# define SAM3U_IRQ_PA31 (SAM3U_IRQ_GPIOA_PINS+31) /* GPIOA, PIN 31 */
+# define SAM3U_NGPIOAIRQS 32
+#else
+# define SAM3U_NGPIOAIRQS 0
+#endif
+
+#ifdef CONFIG_GPIOB_IRQ
+# define SAM3U_IRQ_GPIOB_PINS (SAM3U_IRQ_EXTINT+SAM3U_IRQ_NEXTINT+SAM3U_IRQ_GPIOA_PINS)
+# define SAM3U_IRQ_PB0 (SAM3U_IRQ_GPIOB_PINS+0) /* GPIOB, PIN 0 */
+# define SAM3U_IRQ_PB1 (SAM3U_IRQ_GPIOB_PINS+1) /* GPIOB, PIN 1 */
+# define SAM3U_IRQ_PB2 (SAM3U_IRQ_GPIOB_PINS+2) /* GPIOB, PIN 2 */
+# define SAM3U_IRQ_PB3 (SAM3U_IRQ_GPIOB_PINS+3) /* GPIOB, PIN 3 */
+# define SAM3U_IRQ_PB4 (SAM3U_IRQ_GPIOB_PINS+4) /* GPIOB, PIN 4 */
+# define SAM3U_IRQ_PB5 (SAM3U_IRQ_GPIOB_PINS+5) /* GPIOB, PIN 5 */
+# define SAM3U_IRQ_PB6 (SAM3U_IRQ_GPIOB_PINS+6) /* GPIOB, PIN 6 */
+# define SAM3U_IRQ_PB7 (SAM3U_IRQ_GPIOB_PINS+7) /* GPIOB, PIN 7 */
+# define SAM3U_IRQ_PB8 (SAM3U_IRQ_GPIOB_PINS+8) /* GPIOB, PIN 8 */
+# define SAM3U_IRQ_PB9 (SAM3U_IRQ_GPIOB_PINS+9) /* GPIOB, PIN 9 */
+# define SAM3U_IRQ_PB10 (SAM3U_IRQ_GPIOB_PINS+10) /* GPIOB, PIN 10 */
+# define SAM3U_IRQ_PB11 (SAM3U_IRQ_GPIOB_PINS+11) /* GPIOB, PIN 11 */
+# define SAM3U_IRQ_PB12 (SAM3U_IRQ_GPIOB_PINS+12) /* GPIOB, PIN 12 */
+# define SAM3U_IRQ_PB13 (SAM3U_IRQ_GPIOB_PINS+13) /* GPIOB, PIN 13 */
+# define SAM3U_IRQ_PB14 (SAM3U_IRQ_GPIOB_PINS+14) /* GPIOB, PIN 14 */
+# define SAM3U_IRQ_PB15 (SAM3U_IRQ_GPIOB_PINS+15) /* GPIOB, PIN 15 */
+# define SAM3U_IRQ_PB16 (SAM3U_IRQ_GPIOB_PINS+16) /* GPIOB, PIN 16 */
+# define SAM3U_IRQ_PB17 (SAM3U_IRQ_GPIOB_PINS+17) /* GPIOB, PIN 17 */
+# define SAM3U_IRQ_PB18 (SAM3U_IRQ_GPIOB_PINS+18) /* GPIOB, PIN 18 */
+# define SAM3U_IRQ_PB19 (SAM3U_IRQ_GPIOB_PINS+19) /* GPIOB, PIN 19 */
+# define SAM3U_IRQ_PB20 (SAM3U_IRQ_GPIOB_PINS+20) /* GPIOB, PIN 20 */
+# define SAM3U_IRQ_PB21 (SAM3U_IRQ_GPIOB_PINS+21) /* GPIOB, PIN 21 */
+# define SAM3U_IRQ_PB22 (SAM3U_IRQ_GPIOB_PINS+22) /* GPIOB, PIN 22 */
+# define SAM3U_IRQ_PB23 (SAM3U_IRQ_GPIOB_PINS+23) /* GPIOB, PIN 23 */
+# define SAM3U_IRQ_PB24 (SAM3U_IRQ_GPIOB_PINS+24) /* GPIOB, PIN 24 */
+# define SAM3U_IRQ_PB25 (SAM3U_IRQ_GPIOB_PINS+25) /* GPIOB, PIN 25 */
+# define SAM3U_IRQ_PB26 (SAM3U_IRQ_GPIOB_PINS+26) /* GPIOB, PIN 26 */
+# define SAM3U_IRQ_PB27 (SAM3U_IRQ_GPIOB_PINS+27) /* GPIOB, PIN 27 */
+# define SAM3U_IRQ_PB28 (SAM3U_IRQ_GPIOB_PINS+28) /* GPIOB, PIN 28 */
+# define SAM3U_IRQ_PB29 (SAM3U_IRQ_GPIOB_PINS+29) /* GPIOB, PIN 29 */
+# define SAM3U_IRQ_PB30 (SAM3U_IRQ_GPIOB_PINS+30) /* GPIOB, PIN 30 */
+# define SAM3U_IRQ_PB31 (SAM3U_IRQ_GPIOB_PINS+31) /* GPIOB, PIN 31 */
+# define SAM3U_NGPIOAIRQS 32
+#else
+# define SAM3U_NGPIOBIRQS 0
+#endif
+
+#ifdef CONFIG_GPIOC_IRQ
+# define SAM3U_IRQ_GPIOC_PINS (SAM3U_IRQ_EXTINT+SAM3U_IRQ_NEXTINT+SAM3U_IRQ_GPIOA_PINS+SAM3U_IRQ_GPIOB_PINS)
+# define SAM3U_IRQ_PC0 (SAM3U_IRQ_GPIOC_PINS+0) /* GPIOC, PIN 0 */
+# define SAM3U_IRQ_PC1 (SAM3U_IRQ_GPIOC_PINS+1) /* GPIOC, PIN 1 */
+# define SAM3U_IRQ_PC2 (SAM3U_IRQ_GPIOC_PINS+2) /* GPIOC, PIN 2 */
+# define SAM3U_IRQ_PC3 (SAM3U_IRQ_GPIOC_PINS+3) /* GPIOC, PIN 3 */
+# define SAM3U_IRQ_PC4 (SAM3U_IRQ_GPIOC_PINS+4) /* GPIOC, PIN 4 */
+# define SAM3U_IRQ_PC5 (SAM3U_IRQ_GPIOC_PINS+5) /* GPIOC, PIN 5 */
+# define SAM3U_IRQ_PC6 (SAM3U_IRQ_GPIOC_PINS+6) /* GPIOC, PIN 6 */
+# define SAM3U_IRQ_PC7 (SAM3U_IRQ_GPIOC_PINS+7) /* GPIOC, PIN 7 */
+# define SAM3U_IRQ_PC8 (SAM3U_IRQ_GPIOC_PINS+8) /* GPIOC, PIN 8 */
+# define SAM3U_IRQ_PC9 (SAM3U_IRQ_GPIOC_PINS+9) /* GPIOC, PIN 9 */
+# define SAM3U_IRQ_PC10 (SAM3U_IRQ_GPIOC_PINS+10) /* GPIOC, PIN 10 */
+# define SAM3U_IRQ_PC11 (SAM3U_IRQ_GPIOC_PINS+11) /* GPIOC, PIN 11 */
+# define SAM3U_IRQ_PC12 (SAM3U_IRQ_GPIOC_PINS+12) /* GPIOC, PIN 12 */
+# define SAM3U_IRQ_PC13 (SAM3U_IRQ_GPIOC_PINS+13) /* GPIOC, PIN 13 */
+# define SAM3U_IRQ_PC14 (SAM3U_IRQ_GPIOC_PINS+14) /* GPIOC, PIN 14 */
+# define SAM3U_IRQ_PC15 (SAM3U_IRQ_GPIOC_PINS+15) /* GPIOC, PIN 15 */
+# define SAM3U_IRQ_PC16 (SAM3U_IRQ_GPIOC_PINS+16) /* GPIOC, PIN 16 */
+# define SAM3U_IRQ_PC17 (SAM3U_IRQ_GPIOC_PINS+17) /* GPIOC, PIN 17 */
+# define SAM3U_IRQ_PC18 (SAM3U_IRQ_GPIOC_PINS+18) /* GPIOC, PIN 18 */
+# define SAM3U_IRQ_PC19 (SAM3U_IRQ_GPIOC_PINS+19) /* GPIOC, PIN 19 */
+# define SAM3U_IRQ_PC20 (SAM3U_IRQ_GPIOC_PINS+20) /* GPIOC, PIN 20 */
+# define SAM3U_IRQ_PC21 (SAM3U_IRQ_GPIOC_PINS+21) /* GPIOC, PIN 21 */
+# define SAM3U_IRQ_PC22 (SAM3U_IRQ_GPIOC_PINS+22) /* GPIOC, PIN 22 */
+# define SAM3U_IRQ_PC23 (SAM3U_IRQ_GPIOC_PINS+23) /* GPIOC, PIN 23 */
+# define SAM3U_IRQ_PC24 (SAM3U_IRQ_GPIOC_PINS+24) /* GPIOC, PIN 24 */
+# define SAM3U_IRQ_PC25 (SAM3U_IRQ_GPIOC_PINS+25) /* GPIOC, PIN 25 */
+# define SAM3U_IRQ_PC26 (SAM3U_IRQ_GPIOC_PINS+26) /* GPIOC, PIN 26 */
+# define SAM3U_IRQ_PC27 (SAM3U_IRQ_GPIOC_PINS+27) /* GPIOC, PIN 27 */
+# define SAM3U_IRQ_PC28 (SAM3U_IRQ_GPIOC_PINS+28) /* GPIOC, PIN 28 */
+# define SAM3U_IRQ_PC29 (SAM3U_IRQ_GPIOC_PINS+29) /* GPIOC, PIN 29 */
+# define SAM3U_IRQ_PC30 (SAM3U_IRQ_GPIOC_PINS+30) /* GPIOC, PIN 30 */
+# define SAM3U_IRQ_PC31 (SAM3U_IRQ_GPIOC_PINS+31) /* GPIOC, PIN 31 */
+# define SAM3U_NGPIOAIRQS 32
+#else
+# define SAM3U_NGPIOCIRQS 0
+#endif
+
+/* Total number of IRQ numbers */
+
+#define NR_IRQS (SAM3U_IRQ_EXTINT+SAM3U_IRQ_NEXTINT+\
+ SAM3U_NGPIOAIRQS+SAM3U_NGPIOBIRQS+SAM3U_NGPIOCIRQS)
+
+/****************************************************************************************
+ * Public Types
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Inline functions
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Variables
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * 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_SAM3U_IRQ_H */
+
diff --git a/nuttx/arch/arm/include/serial.h b/nuttx/arch/arm/include/serial.h
new file mode 100644
index 000000000..844f78a2b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <sys/types.h>
+#include <nuttx/fs/ioctl.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#endif /* __ARCH_ARM_INCLUDE_SERIAL_H */
diff --git a/nuttx/arch/arm/include/stdarg.h b/nuttx/arch/arm/include/stdarg.h
new file mode 100644
index 000000000..653d34a6f
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/nuttx/arch/arm/include/stm32/chip.h b/nuttx/arch/arm/include/stm32/chip.h
new file mode 100644
index 000000000..d01929e1c
--- /dev/null
+++ b/nuttx/arch/arm/include/stm32/chip.h
@@ -0,0 +1,568 @@
+/************************************************************************************
+ * arch/arm/include/stm32/chip.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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.
+ */
+
+/* STM32 F100 Value Line ************************************************************/
+
+#if defined(CONFIG_ARCH_CHIP_STM32F100C8) || defined(CONFIG_ARCH_CHIP_STM32F100CB) \
+ || defined(CONFIG_ARCH_CHIP_STM32F100R8) || defined(CONFIG_ARCH_CHIP_STM32F100RB) \
+ || defined(CONFIG_ARCH_CHIP_STM32F100V8) || defined(CONFIG_ARCH_CHIP_STM32F100VB)
+# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# define CONFIG_STM32_MEDIUMDENSITY 1 /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# undef CONFIG_STM32_HIGHDENSITY /* 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_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,3,4 with DMA */
+# define STM32_NBTIM 0 /* No basic timers */
+# define STM32_NDMA 2 /* DMA1-2 */
+# 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_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_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 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_STM32F103RET6)
+# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# define CONFIG_STM32_HIGHDENSITY 1 /* 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_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 generall timers TIM2,3,4,5 with 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_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_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_STM32F103VCT6) || defined(CONFIG_ARCH_CHIP_STM32F103VET6)
+# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# define CONFIG_STM32_HIGHDENSITY 1 /* 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_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,3,4,5 */
+# 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_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_NCRC 1 /* CRC */
+# define STM32_NTHERNET 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_STM32F103ZET6)
+# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# define CONFIG_STM32_HIGHDENSITY 1 /* 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_STM32F40XX /* STM32F405xx and STM32407xx families */
+# define STM32_NFSMC 1 /* FSMC */
+# define STM32_NATIM 1 /* One advanced timer TIM1 */
+# define STM32_NGTIM 4 /* 16-bit generall timers TIM2,3,4,5 with DMA */
+# define STM32_NBTIM 0 /* No basic timers */
+# define STM32_NDMA 2 /* DMA1-2 */
+# 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 /* CAN1 */
+# define STM32_NSDIO 1 /* SDIO */
+# 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_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_STM32F105VBT7)
+# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# undef CONFIG_STM32_HIGHDENSITY /* 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_STM32F40XX /* STM32F405xx and STM32407xx */
+# define STM32_NFSMC 1 /* FSMC */
+# define STM32_NATIM 1 /* One advanced timers TIM1 */
+# define STM32_NGTIM 4 /* 16-bit generall timers TIM2,3,4,5 with 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_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_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)
+# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# undef CONFIG_STM32_HIGHDENSITY /* 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_STM32F40XX /* STM32F405xx and STM32407xx */
+# define STM32_NFSMC 1 /* FSMC */
+# define STM32_NATIM 1 /* One advanced timers TIM1 */
+# define STM32_NGTIM 4 /* 16-bit generall timers TIM2,3,4,5 with 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_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_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_STM32F207IG) /* UFBGA-176 1024Kb FLASH 128Kb SRAM */
+# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# undef CONFIG_STM32_HIGHDENSITY /* 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_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_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_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 F4 Family ******************************************************************/
+#elif defined(CONFIG_ARCH_CHIP_STM32F405RG) /* LQFP 64 10x10x1.4 1024Kb FLASH 192Kb SRAM */
+# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# undef CONFIG_STM32_HIGHDENSITY /* 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_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_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_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_STM32F10XX /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# undef CONFIG_STM32_HIGHDENSITY /* 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_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_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_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_STM32F10XX /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# undef CONFIG_STM32_HIGHDENSITY /* 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_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_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_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_STM32F10XX /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# undef CONFIG_STM32_HIGHDENSITY /* 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_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_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_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_STM32F10XX /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# undef CONFIG_STM32_HIGHDENSITY /* 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_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_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_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_STM32F10XX /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# undef CONFIG_STM32_HIGHDENSITY /* 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_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_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_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_STM32F10XX /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# undef CONFIG_STM32_HIGHDENSITY /* 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_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_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_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_STM32F10XX /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# undef CONFIG_STM32_HIGHDENSITY /* 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_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_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_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_STM32F10XX /* STM32F10xxx family */
+# undef CONFIG_STM32_LOWDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
+# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
+# undef CONFIG_STM32_HIGHDENSITY /* 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_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_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_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) */
+
+#else
+# error "Unsupported STM32 chip"
+#endif
+
+#endif /* __ARCH_ARM_INCLUDE_STM32_CHIP_H */
+
diff --git a/nuttx/arch/arm/include/stm32/irq.h b/nuttx/arch/arm/include/stm32/irq.h
new file mode 100644
index 000000000..842183420
--- /dev/null
+++ b/nuttx/arch/arm/include/stm32/irq.h
@@ -0,0 +1,117 @@
+/************************************************************************************
+ * arch/arm/include/stm32s/irq.h
+ *
+ * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+#include <nuttx/irq.h>
+#include <arch/stm32/chip.h>
+
+/************************************************************************************
+ * 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_INTERRUPTS (16) /* Vector number of the first external interrupt */
+
+#if defined(CONFIG_STM32_STM32F10XX)
+# include <arch/stm32/stm32f10xxx_irq.h>
+#elif defined(CONFIG_STM32_STM32F20XX)
+# include <arch/stm32/stm32f20xxx_irq.h>
+#elif defined(CONFIG_STM32_STM32F40XX)
+# include <arch/stm32/stm32f40xxx_irq.h>
+#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/nuttx/arch/arm/include/stm32/stm32f10xxx_irq.h b/nuttx/arch/arm/include/stm32/stm32f10xxx_irq.h
new file mode 100644
index 000000000..67f4ba436
--- /dev/null
+++ b/nuttx/arch/arm/include/stm32/stm32f10xxx_irq.h
@@ -0,0 +1,287 @@
+/************************************************************************************
+ * arch/arm/include/stm32s/stm32f10xxx_irq.h
+ *
+ * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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_STM32F10XXX_IRQ_H
+#define __ARCH_ARM_INCLUDE_STM32F10XXX_IRQ_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+
+/************************************************************************************
+ * 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)
+ */
+
+#if defined(CONFIG_STM32_VALUELINE) && defined(CONFIG_STM32_MEDIUMDENSITY)
+# 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 */
+ /* 19-22: reserved */
+# 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 (TIM16 global interrupt) */
+# define STM32_IRQ_TIM1TRGCOM (42) /* 26: TIM1 Trigger and Commutation interrupts (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 alarm through EXTI line interrupt */
+# define STM32_IRQ_CEC (58) /* 42: CEC global interrupt */
+# if defined(CONFIG_STM32_HIGHDENSITY)
+# 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 */
+ /* 46-47: reserved */
+# define STM32_IRQ_FSMC (64) /* 48: FSMC global interrupt */
+ /* 49: reserved */
+# define STM32_IRQ_TIM5 (66) /* 50: TIM5 global interrupt */
+# define STM32_IRQ_SPI3 (67) /* 51: SPI1 global interrupt */
+# define STM32_IRQ_UART4 (68) /* 52: USART2 global interrupt */
+# define STM32_IRQ_UART5 (69) /* 53: USART3 global interrupt */
+# else
+ /* 43-53: reserved */
+# endif
+# 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 global interrupt */
+# define NR_IRQS (76)
+#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_IRQS (84)
+#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_IRQS (76)
+#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_STM32F10XXX_IRQ_H */
+
diff --git a/nuttx/arch/arm/include/stm32/stm32f20xxx_irq.h b/nuttx/arch/arm/include/stm32/stm32f20xxx_irq.h
new file mode 100644
index 000000000..d88c5d070
--- /dev/null
+++ b/nuttx/arch/arm/include/stm32/stm32f20xxx_irq.h
@@ -0,0 +1,182 @@
+/****************************************************************************************************
+ * arch/arm/include/stm32s/stm32f20xxx_irq.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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_STM32F20XXX_IRQ_H
+#define __ARCH_ARM_INCLUDE_STM32F20XXX_IRQ_H
+
+/****************************************************************************************************
+ * Included Files
+ ****************************************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+
+/****************************************************************************************************
+ * 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_INTERRUPTS+0) /* 0: Window Watchdog interrupt */
+#define STM32_IRQ_PVD (STM32_IRQ_INTERRUPTS+1) /* 1: PVD through EXTI Line detection interrupt */
+#define STM32_IRQ_TAMPER (STM32_IRQ_INTERRUPTS+2) /* 2: Tamper and time stamp interrupts */
+#define STM32_IRQ_TIMESTAMP (STM32_IRQ_INTERRUPTS+2) /* 2: Tamper and time stamp interrupts */
+#define STM32_IRQ_RTC_WKUP (STM32_IRQ_INTERRUPTS+3) /* 3: RTC global interrupt */
+#define STM32_IRQ_FLASH (STM32_IRQ_INTERRUPTS+4) /* 4: Flash global interrupt */
+#define STM32_IRQ_RCC (STM32_IRQ_INTERRUPTS+5) /* 5: RCC global interrupt */
+#define STM32_IRQ_EXTI0 (STM32_IRQ_INTERRUPTS+6) /* 6: EXTI Line 0 interrupt */
+#define STM32_IRQ_EXTI1 (STM32_IRQ_INTERRUPTS+7) /* 7: EXTI Line 1 interrupt */
+#define STM32_IRQ_EXTI2 (STM32_IRQ_INTERRUPTS+8) /* 8: EXTI Line 2 interrupt */
+#define STM32_IRQ_EXTI3 (STM32_IRQ_INTERRUPTS+9) /* 9: EXTI Line 3 interrupt */
+#define STM32_IRQ_EXTI4 (STM32_IRQ_INTERRUPTS+10) /* 10: EXTI Line 4 interrupt */
+#define STM32_IRQ_DMA1S0 (STM32_IRQ_INTERRUPTS+11) /* 11: DMA1 Stream 0 global interrupt */
+#define STM32_IRQ_DMA1S1 (STM32_IRQ_INTERRUPTS+12) /* 12: DMA1 Stream 1 global interrupt */
+#define STM32_IRQ_DMA1S2 (STM32_IRQ_INTERRUPTS+13) /* 13: DMA1 Stream 2 global interrupt */
+#define STM32_IRQ_DMA1S3 (STM32_IRQ_INTERRUPTS+14) /* 14: DMA1 Stream 3 global interrupt */
+#define STM32_IRQ_DMA1S4 (STM32_IRQ_INTERRUPTS+15) /* 15: DMA1 Stream 4 global interrupt */
+#define STM32_IRQ_DMA1S5 (STM32_IRQ_INTERRUPTS+16) /* 16: DMA1 Stream 5 global interrupt */
+#define STM32_IRQ_DMA1S6 (STM32_IRQ_INTERRUPTS+17) /* 17: DMA1 Stream 6 global interrupt */
+#define STM32_IRQ_ADC (STM32_IRQ_INTERRUPTS+18) /* 18: ADC1, ADC2, and ADC3 global interrupt */
+#define STM32_IRQ_CAN1TX (STM32_IRQ_INTERRUPTS+19) /* 19: CAN1 TX interrupts */
+#define STM32_IRQ_CAN1RX0 (STM32_IRQ_INTERRUPTS+20) /* 20: CAN1 RX0 interrupts */
+#define STM32_IRQ_CAN1RX1 (STM32_IRQ_INTERRUPTS+21) /* 21: CAN1 RX1 interrupt */
+#define STM32_IRQ_CAN1SCE (STM32_IRQ_INTERRUPTS+22) /* 22: CAN1 SCE interrupt */
+#define STM32_IRQ_EXTI95 (STM32_IRQ_INTERRUPTS+23) /* 23: EXTI Line[9:5] interrupts */
+#define STM32_IRQ_TIM1BRK (STM32_IRQ_INTERRUPTS+24) /* 24: TIM1 Break interrupt */
+#define STM32_IRQ_TIM9 (STM32_IRQ_INTERRUPTS+24) /* 24: TIM9 global interrupt */
+#define STM32_IRQ_TIM1UP (STM32_IRQ_INTERRUPTS+25) /* 25: TIM1 Update interrupt */
+#define STM32_IRQ_TIM10 (STM32_IRQ_INTERRUPTS+25) /* 25: TIM10 global interrupt */
+#define STM32_IRQ_TIM1TRGCOM (STM32_IRQ_INTERRUPTS+26) /* 26: TIM1 Trigger and Commutation interrupts */
+#define STM32_IRQ_TIM11 (STM32_IRQ_INTERRUPTS+26) /* 26: TIM11 global interrupt */
+#define STM32_IRQ_TIM1CC (STM32_IRQ_INTERRUPTS+27) /* 27: TIM1 Capture Compare interrupt */
+#define STM32_IRQ_TIM2 (STM32_IRQ_INTERRUPTS+28) /* 28: TIM2 global interrupt */
+#define STM32_IRQ_TIM3 (STM32_IRQ_INTERRUPTS+29) /* 29: TIM3 global interrupt */
+#define STM32_IRQ_TIM4 (STM32_IRQ_INTERRUPTS+30) /* 30: TIM4 global interrupt */
+#define STM32_IRQ_I2C1EV (STM32_IRQ_INTERRUPTS+31) /* 31: I2C1 event interrupt */
+#define STM32_IRQ_I2C1ER (STM32_IRQ_INTERRUPTS+32) /* 32: I2C1 error interrupt */
+#define STM32_IRQ_I2C2EV (STM32_IRQ_INTERRUPTS+33) /* 33: I2C2 event interrupt */
+#define STM32_IRQ_I2C2ER (STM32_IRQ_INTERRUPTS+34) /* 34: I2C2 error interrupt */
+#define STM32_IRQ_SPI1 (STM32_IRQ_INTERRUPTS+35) /* 35: SPI1 global interrupt */
+#define STM32_IRQ_SPI2 (STM32_IRQ_INTERRUPTS+36) /* 36: SPI2 global interrupt */
+#define STM32_IRQ_USART1 (STM32_IRQ_INTERRUPTS+37) /* 37: USART1 global interrupt */
+#define STM32_IRQ_USART2 (STM32_IRQ_INTERRUPTS+38) /* 38: USART2 global interrupt */
+#define STM32_IRQ_USART3 (STM32_IRQ_INTERRUPTS+39) /* 39: USART3 global interrupt */
+#define STM32_IRQ_EXTI1510 (STM32_IRQ_INTERRUPTS+40) /* 40: EXTI Line[15:10] interrupts */
+#define STM32_IRQ_RTCALRM (STM32_IRQ_INTERRUPTS+41) /* 41: RTC alarm through EXTI line interrupt */
+#define STM32_IRQ_OTGFSWKUP (STM32_IRQ_INTERRUPTS+42) /* 42: USB On-The-Go FS Wakeup through EXTI line interrupt */
+#define STM32_IRQ_TIM8BRK (STM32_IRQ_INTERRUPTS+43) /* 43: TIM8 Break interrupt */
+#define STM32_IRQ_TIM12 (STM32_IRQ_INTERRUPTS+43) /* 43: TIM12 global interrupt */
+#define STM32_IRQ_TIM8UP (STM32_IRQ_INTERRUPTS+44) /* 44: TIM8 Update interrupt */
+#define STM32_IRQ_TIM13 (STM32_IRQ_INTERRUPTS+44) /* 44: TIM13 global interrupt */
+#define STM32_IRQ_TIM8TRGCOM (STM32_IRQ_INTERRUPTS+45) /* 45: TIM8 Trigger and Commutation interrupts */
+#define STM32_IRQ_TIM14 (STM32_IRQ_INTERRUPTS+45) /* 45: TIM14 global interrupt */
+#define STM32_IRQ_TIM8CC (STM32_IRQ_INTERRUPTS+46) /* 46: TIM8 Capture Compare interrupt */
+#define STM32_IRQ_DMA1S7 (STM32_IRQ_INTERRUPTS+47) /* 47: DMA1 Stream 7 global interrupt */
+#define STM32_IRQ_FSMC (STM32_IRQ_INTERRUPTS+48) /* 48: FSMC global interrupt */
+#define STM32_IRQ_SDIO (STM32_IRQ_INTERRUPTS+49) /* 49: SDIO global interrupt */
+#define STM32_IRQ_TIM5 (STM32_IRQ_INTERRUPTS+50) /* 50: TIM5 global interrupt */
+#define STM32_IRQ_SPI3 (STM32_IRQ_INTERRUPTS+51) /* 51: SPI3 global interrupt */
+#define STM32_IRQ_UART4 (STM32_IRQ_INTERRUPTS+52) /* 52: UART4 global interrupt */
+#define STM32_IRQ_UART5 (STM32_IRQ_INTERRUPTS+53) /* 53: UART5 global interrupt */
+#define STM32_IRQ_TIM6 (STM32_IRQ_INTERRUPTS+54) /* 54: TIM6 global interrupt */
+#define STM32_IRQ_DAC (STM32_IRQ_INTERRUPTS+54) /* 54: DAC1 and DAC2 underrun error interrupts */
+#define STM32_IRQ_TIM7 (STM32_IRQ_INTERRUPTS+55) /* 55: TIM7 global interrupt */
+#define STM32_IRQ_DMA2S0 (STM32_IRQ_INTERRUPTS+56) /* 56: DMA2 Stream 0 global interrupt */
+#define STM32_IRQ_DMA2S1 (STM32_IRQ_INTERRUPTS+57) /* 57: DMA2 Stream 1 global interrupt */
+#define STM32_IRQ_DMA2S2 (STM32_IRQ_INTERRUPTS+58) /* 58: DMA2 Stream 2 global interrupt */
+#define STM32_IRQ_DMA2S3 (STM32_IRQ_INTERRUPTS+59) /* 59: DMA2 Stream 3 global interrupt */
+#define STM32_IRQ_DMA2S4 (STM32_IRQ_INTERRUPTS+60) /* 60: DMA2 Stream 4 global interrupt */
+#define STM32_IRQ_ETH (STM32_IRQ_INTERRUPTS+61) /* 61: Ethernet global interrupt */
+#define STM32_IRQ_ETHWKUP (STM32_IRQ_INTERRUPTS+62) /* 62: Ethernet Wakeup through EXTI line interrupt */
+#define STM32_IRQ_CAN2TX (STM32_IRQ_INTERRUPTS+63) /* 63: CAN2 TX interrupts */
+#define STM32_IRQ_CAN2RX0 (STM32_IRQ_INTERRUPTS+64) /* 64: CAN2 RX0 interrupts */
+#define STM32_IRQ_CAN2RX1 (STM32_IRQ_INTERRUPTS+65) /* 65: CAN2 RX1 interrupt */
+#define STM32_IRQ_CAN2SCE (STM32_IRQ_INTERRUPTS+66) /* 66: CAN2 SCE interrupt */
+#define STM32_IRQ_OTGFS (STM32_IRQ_INTERRUPTS+67) /* 67: USB On The Go FS global interrupt */
+#define STM32_IRQ_DMA2S5 (STM32_IRQ_INTERRUPTS+68) /* 68: DMA2 Stream 5 global interrupt */
+#define STM32_IRQ_DMA2S6 (STM32_IRQ_INTERRUPTS+69) /* 69: DMA2 Stream 6 global interrupt */
+#define STM32_IRQ_DMA2S7 (STM32_IRQ_INTERRUPTS+70) /* 70: DMA2 Stream 7 global interrupt */
+#define STM32_IRQ_USART6 (STM32_IRQ_INTERRUPTS+71) /* 71: USART6 global interrupt */
+#define STM32_IRQ_I2C3EV (STM32_IRQ_INTERRUPTS+72) /* 72: I2C3 event interrupt */
+#define STM32_IRQ_I2C3ER (STM32_IRQ_INTERRUPTS+73) /* 73: I2C3 error interrupt */
+#define STM32_IRQ_OTGHSEP1OUT (STM32_IRQ_INTERRUPTS+74) /* 74: USB On The Go HS End Point 1 Out global interrupt */
+#define STM32_IRQ_OTGHSEP1IN (STM32_IRQ_INTERRUPTS+75) /* 75: USB On The Go HS End Point 1 In global interrupt */
+#define STM32_IRQ_OTGHSWKUP (STM32_IRQ_INTERRUPTS+76) /* 76: USB On The Go HS Wakeup through EXTI interrupt */
+#define STM32_IRQ_OTGHS (STM32_IRQ_INTERRUPTS+77) /* 77: USB On The Go HS global interrupt */
+#define STM32_IRQ_DCMI (STM32_IRQ_INTERRUPTS+78) /* 78: DCMI global interrupt */
+#define STM32_IRQ_CRYP (STM32_IRQ_INTERRUPTS+79) /* 79: CRYP crypto global interrupt */
+#define STM32_IRQ_HASH (STM32_IRQ_INTERRUPTS+80) /* 80: Hash and Rng global interrupt */
+#define STM32_IRQ_RNG (STM32_IRQ_INTERRUPTS+80) /* 80: Hash and Rng global interrupt */
+
+#define NR_IRQS (STM32_IRQ_INTERRUPTS+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_STM32F40XXX_IRQ_H */
+
diff --git a/nuttx/arch/arm/include/stm32/stm32f40xxx_irq.h b/nuttx/arch/arm/include/stm32/stm32f40xxx_irq.h
new file mode 100644
index 000000000..cd97b9c9d
--- /dev/null
+++ b/nuttx/arch/arm/include/stm32/stm32f40xxx_irq.h
@@ -0,0 +1,185 @@
+/****************************************************************************************************
+ * arch/arm/include/stm32s/stm32f40xxx_irq.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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_STM32F40XXX_IRQ_H
+#define __ARCH_ARM_INCLUDE_STM32F40XXX_IRQ_H
+
+/****************************************************************************************************
+ * Included Files
+ ****************************************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+
+/****************************************************************************************************
+ * 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_INTERRUPTS+0) /* 0: Window Watchdog interrupt */
+#define STM32_IRQ_PVD (STM32_IRQ_INTERRUPTS+1) /* 1: PVD through EXTI Line detection interrupt */
+#define STM32_IRQ_TAMPER (STM32_IRQ_INTERRUPTS+2) /* 2: Tamper and time stamp interrupts */
+#define STM32_IRQ_TIMESTAMP (STM32_IRQ_INTERRUPTS+2) /* 2: Tamper and time stamp interrupts */
+#define STM32_IRQ_RTC_WKUP (STM32_IRQ_INTERRUPTS+3) /* 3: RTC global interrupt */
+#define STM32_IRQ_FLASH (STM32_IRQ_INTERRUPTS+4) /* 4: Flash global interrupt */
+#define STM32_IRQ_RCC (STM32_IRQ_INTERRUPTS+5) /* 5: RCC global interrupt */
+#define STM32_IRQ_EXTI0 (STM32_IRQ_INTERRUPTS+6) /* 6: EXTI Line 0 interrupt */
+#define STM32_IRQ_EXTI1 (STM32_IRQ_INTERRUPTS+7) /* 7: EXTI Line 1 interrupt */
+#define STM32_IRQ_EXTI2 (STM32_IRQ_INTERRUPTS+8) /* 8: EXTI Line 2 interrupt */
+#define STM32_IRQ_EXTI3 (STM32_IRQ_INTERRUPTS+9) /* 9: EXTI Line 3 interrupt */
+#define STM32_IRQ_EXTI4 (STM32_IRQ_INTERRUPTS+10) /* 10: EXTI Line 4 interrupt */
+#define STM32_IRQ_DMA1S0 (STM32_IRQ_INTERRUPTS+11) /* 11: DMA1 Stream 0 global interrupt */
+#define STM32_IRQ_DMA1S1 (STM32_IRQ_INTERRUPTS+12) /* 12: DMA1 Stream 1 global interrupt */
+#define STM32_IRQ_DMA1S2 (STM32_IRQ_INTERRUPTS+13) /* 13: DMA1 Stream 2 global interrupt */
+#define STM32_IRQ_DMA1S3 (STM32_IRQ_INTERRUPTS+14) /* 14: DMA1 Stream 3 global interrupt */
+#define STM32_IRQ_DMA1S4 (STM32_IRQ_INTERRUPTS+15) /* 15: DMA1 Stream 4 global interrupt */
+#define STM32_IRQ_DMA1S5 (STM32_IRQ_INTERRUPTS+16) /* 16: DMA1 Stream 5 global interrupt */
+#define STM32_IRQ_DMA1S6 (STM32_IRQ_INTERRUPTS+17) /* 17: DMA1 Stream 6 global interrupt */
+#define STM32_IRQ_ADC (STM32_IRQ_INTERRUPTS+18) /* 18: ADC1, ADC2, and ADC3 global interrupt */
+#define STM32_IRQ_CAN1TX (STM32_IRQ_INTERRUPTS+19) /* 19: CAN1 TX interrupts */
+#define STM32_IRQ_CAN1RX0 (STM32_IRQ_INTERRUPTS+20) /* 20: CAN1 RX0 interrupts */
+#define STM32_IRQ_CAN1RX1 (STM32_IRQ_INTERRUPTS+21) /* 21: CAN1 RX1 interrupt */
+#define STM32_IRQ_CAN1SCE (STM32_IRQ_INTERRUPTS+22) /* 22: CAN1 SCE interrupt */
+#define STM32_IRQ_EXTI95 (STM32_IRQ_INTERRUPTS+23) /* 23: EXTI Line[9:5] interrupts */
+#define STM32_IRQ_TIM1BRK (STM32_IRQ_INTERRUPTS+24) /* 24: TIM1 Break interrupt */
+#define STM32_IRQ_TIM9 (STM32_IRQ_INTERRUPTS+24) /* 24: TIM9 global interrupt */
+#define STM32_IRQ_TIM1UP (STM32_IRQ_INTERRUPTS+25) /* 25: TIM1 Update interrupt */
+#define STM32_IRQ_TIM10 (STM32_IRQ_INTERRUPTS+25) /* 25: TIM10 global interrupt */
+#define STM32_IRQ_TIM1TRGCOM (STM32_IRQ_INTERRUPTS+26) /* 26: TIM1 Trigger and Commutation interrupts */
+#define STM32_IRQ_TIM11 (STM32_IRQ_INTERRUPTS+26) /* 26: TIM11 global interrupt */
+#define STM32_IRQ_TIM1CC (STM32_IRQ_INTERRUPTS+27) /* 27: TIM1 Capture Compare interrupt */
+#define STM32_IRQ_TIM2 (STM32_IRQ_INTERRUPTS+28) /* 28: TIM2 global interrupt */
+#define STM32_IRQ_TIM3 (STM32_IRQ_INTERRUPTS+29) /* 29: TIM3 global interrupt */
+#define STM32_IRQ_TIM4 (STM32_IRQ_INTERRUPTS+30) /* 30: TIM4 global interrupt */
+#define STM32_IRQ_I2C1EV (STM32_IRQ_INTERRUPTS+31) /* 31: I2C1 event interrupt */
+#define STM32_IRQ_I2C1ER (STM32_IRQ_INTERRUPTS+32) /* 32: I2C1 error interrupt */
+#define STM32_IRQ_I2C2EV (STM32_IRQ_INTERRUPTS+33) /* 33: I2C2 event interrupt */
+#define STM32_IRQ_I2C2ER (STM32_IRQ_INTERRUPTS+34) /* 34: I2C2 error interrupt */
+#define STM32_IRQ_SPI1 (STM32_IRQ_INTERRUPTS+35) /* 35: SPI1 global interrupt */
+#define STM32_IRQ_SPI2 (STM32_IRQ_INTERRUPTS+36) /* 36: SPI2 global interrupt */
+#define STM32_IRQ_USART1 (STM32_IRQ_INTERRUPTS+37) /* 37: USART1 global interrupt */
+#define STM32_IRQ_USART2 (STM32_IRQ_INTERRUPTS+38) /* 38: USART2 global interrupt */
+#define STM32_IRQ_USART3 (STM32_IRQ_INTERRUPTS+39) /* 39: USART3 global interrupt */
+#define STM32_IRQ_EXTI1510 (STM32_IRQ_INTERRUPTS+40) /* 40: EXTI Line[15:10] interrupts */
+#define STM32_IRQ_RTCALRM (STM32_IRQ_INTERRUPTS+41) /* 41: RTC alarm through EXTI line interrupt */
+#define STM32_IRQ_OTGFSWKUP (STM32_IRQ_INTERRUPTS+42) /* 42: USB On-The-Go FS Wakeup through EXTI line interrupt */
+#define STM32_IRQ_TIM8BRK (STM32_IRQ_INTERRUPTS+43) /* 43: TIM8 Break interrupt */
+#define STM32_IRQ_TIM12 (STM32_IRQ_INTERRUPTS+43) /* 43: TIM12 global interrupt */
+#define STM32_IRQ_TIM8UP (STM32_IRQ_INTERRUPTS+44) /* 44: TIM8 Update interrupt */
+#define STM32_IRQ_TIM13 (STM32_IRQ_INTERRUPTS+44) /* 44: TIM13 global interrupt */
+#define STM32_IRQ_TIM8TRGCOM (STM32_IRQ_INTERRUPTS+45) /* 45: TIM8 Trigger and Commutation interrupts */
+#define STM32_IRQ_TIM14 (STM32_IRQ_INTERRUPTS+45) /* 45: TIM14 global interrupt */
+#define STM32_IRQ_TIM8CC (STM32_IRQ_INTERRUPTS+46) /* 46: TIM8 Capture Compare interrupt */
+#define STM32_IRQ_DMA1S7 (STM32_IRQ_INTERRUPTS+47) /* 47: DMA1 Stream 7 global interrupt */
+#define STM32_IRQ_FSMC (STM32_IRQ_INTERRUPTS+48) /* 48: FSMC global interrupt */
+#define STM32_IRQ_SDIO (STM32_IRQ_INTERRUPTS+49) /* 49: SDIO global interrupt */
+#define STM32_IRQ_TIM5 (STM32_IRQ_INTERRUPTS+50) /* 50: TIM5 global interrupt */
+#define STM32_IRQ_SPI3 (STM32_IRQ_INTERRUPTS+51) /* 51: SPI3 global interrupt */
+#define STM32_IRQ_UART4 (STM32_IRQ_INTERRUPTS+52) /* 52: UART4 global interrupt */
+#define STM32_IRQ_UART5 (STM32_IRQ_INTERRUPTS+53) /* 53: UART5 global interrupt */
+#define STM32_IRQ_TIM6 (STM32_IRQ_INTERRUPTS+54) /* 54: TIM6 global interrupt */
+#define STM32_IRQ_DAC (STM32_IRQ_INTERRUPTS+54) /* 54: DAC1 and DAC2 underrun error interrupts */
+#define STM32_IRQ_TIM7 (STM32_IRQ_INTERRUPTS+55) /* 55: TIM7 global interrupt */
+#define STM32_IRQ_DMA2S0 (STM32_IRQ_INTERRUPTS+56) /* 56: DMA2 Stream 0 global interrupt */
+#define STM32_IRQ_DMA2S1 (STM32_IRQ_INTERRUPTS+57) /* 57: DMA2 Stream 1 global interrupt */
+#define STM32_IRQ_DMA2S2 (STM32_IRQ_INTERRUPTS+58) /* 58: DMA2 Stream 2 global interrupt */
+#define STM32_IRQ_DMA2S3 (STM32_IRQ_INTERRUPTS+59) /* 59: DMA2 Stream 3 global interrupt */
+#define STM32_IRQ_DMA2S4 (STM32_IRQ_INTERRUPTS+60) /* 60: DMA2 Stream 4 global interrupt */
+#define STM32_IRQ_ETH (STM32_IRQ_INTERRUPTS+61) /* 61: Ethernet global interrupt */
+#define STM32_IRQ_ETHWKUP (STM32_IRQ_INTERRUPTS+62) /* 62: Ethernet Wakeup through EXTI line interrupt */
+#define STM32_IRQ_CAN2TX (STM32_IRQ_INTERRUPTS+63) /* 63: CAN2 TX interrupts */
+#define STM32_IRQ_CAN2RX0 (STM32_IRQ_INTERRUPTS+64) /* 64: CAN2 RX0 interrupts */
+#define STM32_IRQ_CAN2RX1 (STM32_IRQ_INTERRUPTS+65) /* 65: CAN2 RX1 interrupt */
+#define STM32_IRQ_CAN2SCE (STM32_IRQ_INTERRUPTS+66) /* 66: CAN2 SCE interrupt */
+#define STM32_IRQ_OTGFS (STM32_IRQ_INTERRUPTS+67) /* 67: USB On The Go FS global interrupt */
+#define STM32_IRQ_DMA2S5 (STM32_IRQ_INTERRUPTS+68) /* 68: DMA2 Stream 5 global interrupt */
+#define STM32_IRQ_DMA2S6 (STM32_IRQ_INTERRUPTS+69) /* 69: DMA2 Stream 6 global interrupt */
+#define STM32_IRQ_DMA2S7 (STM32_IRQ_INTERRUPTS+70) /* 70: DMA2 Stream 7 global interrupt */
+#define STM32_IRQ_USART6 (STM32_IRQ_INTERRUPTS+71) /* 71: USART6 global interrupt */
+#define STM32_IRQ_I2C3EV (STM32_IRQ_INTERRUPTS+72) /* 72: I2C3 event interrupt */
+#define STM32_IRQ_I2C3ER (STM32_IRQ_INTERRUPTS+73) /* 73: I2C3 error interrupt */
+#define STM32_IRQ_OTGHSEP1OUT (STM32_IRQ_INTERRUPTS+74) /* 74: USB On The Go HS End Point 1 Out global interrupt */
+#define STM32_IRQ_OTGHSEP1IN (STM32_IRQ_INTERRUPTS+75) /* 75: USB On The Go HS End Point 1 In global interrupt */
+#define STM32_IRQ_OTGHSWKUP (STM32_IRQ_INTERRUPTS+76) /* 76: USB On The Go HS Wakeup through EXTI interrupt */
+#define STM32_IRQ_OTGHS (STM32_IRQ_INTERRUPTS+77) /* 77: USB On The Go HS global interrupt */
+#define STM32_IRQ_DCMI (STM32_IRQ_INTERRUPTS+78) /* 78: DCMI global interrupt */
+#define STM32_IRQ_CRYP (STM32_IRQ_INTERRUPTS+79) /* 79: CRYP crypto global interrupt */
+#define STM32_IRQ_HASH (STM32_IRQ_INTERRUPTS+80) /* 80: Hash and Rng global interrupt */
+#define STM32_IRQ_RNG (STM32_IRQ_INTERRUPTS+80) /* 80: Hash and Rng global interrupt */
+#define STM32_IRQ_FPU (STM32_IRQ_INTERRUPTS+81) /* 81: FPU global interrupt */
+
+#define NR_IRQS (STM32_IRQ_INTERRUPTS+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_STM32F40XXX_IRQ_H */
+
diff --git a/nuttx/arch/arm/include/str71x/irq.h b/nuttx/arch/arm/include/str71x/irq.h
new file mode 100644
index 000000000..5ce85416a
--- /dev/null
+++ b/nuttx/arch/arm/include/str71x/irq.h
@@ -0,0 +1,151 @@
+/************************************************************************************
+ * arch/arm/include/str71x/irq.h
+ *
+ * Copyright (C) 2008-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/include/syscall.h b/nuttx/arch/arm/include/syscall.h
new file mode 100644
index 000000000..8b438200a
--- /dev/null
+++ b/nuttx/arch/arm/include/syscall.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+ * arch/arm/include/syscall.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4)
+# include <arch/armv7-m/syscall.h>
+#else
+# include <arch/arm/syscall.h>
+#endif
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/include/types.h b/nuttx/arch/arm/include/types.h
new file mode 100644
index 000000000..c06b28950
--- /dev/null
+++ b/nuttx/arch/arm/include/types.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+ * arch/arm/include/types.h
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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 irqsave(). For
+ * ARM, a 32 register value is returned, for the thumb2, Cortex-M3, the 16-bit
+ * primask register value is returned,
+ */
+
+#ifdef __thumb2__
+typedef unsigned short irqstate_t;
+#else /* __thumb2__ */
+typedef unsigned int irqstate_t;
+#endif /* __thumb2__ */
+
+#endif /* __ASSEMBLY__ */
+
+/****************************************************************************
+ * Global Function Prototypes
+ ****************************************************************************/
+
+#endif /* __ARCH_ARM_INCLUDE_TYPES_H */
diff --git a/nuttx/arch/arm/include/watchdog.h b/nuttx/arch/arm/include/watchdog.h
new file mode 100644
index 000000000..43fbac2be
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <nuttx/fs/ioctl.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#endif /* __ARCH_ARM_INCLUDE_WATCHDOG_H */
diff --git a/nuttx/arch/arm/src/Makefile b/nuttx/arch/arm/src/Makefile
new file mode 100644
index 000000000..74be6c18d
--- /dev/null
+++ b/nuttx/arch/arm/src/Makefile
@@ -0,0 +1,157 @@
+############################################################################
+# arch/arm/src/Makefile
+#
+# Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (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
+
+ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src
+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
+ARCH_SUBDIR = arm
+endif
+endif
+
+ifeq ($(WINTOOL),y)
+ NUTTX = "${shell cygpath -w $(TOPDIR)/nuttx}"
+ CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/chip}" \
+ -I "${shell cygpath -w $(ARCH_SRCDIR)/common}" \
+ -I "${shell cygpath -w $(ARCH_SRCDIR)/$(ARCH_SUBDIR)}" \
+ -I "${shell cygpath -w $(TOPDIR)/sched}"
+else
+ NUTTX = $(TOPDIR)/nuttx
+ CFLAGS += -I$(ARCH_SRCDIR)/chip -I$(ARCH_SRCDIR)/common \
+ -I$(ARCH_SRCDIR)/$(ARCH_SUBDIR) -I$(TOPDIR)/sched
+endif
+
+HEAD_OBJ = $(HEAD_ASRC:.S=$(OBJEXT))
+
+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 ($(WINTOOL),y)
+ LIBPATHS = ${shell for path in $(LINKLIBS); do dir=`dirname $(TOPDIR)/$$path`;echo "-L\"`cygpath -w $$dir`\"";done}
+ LIBPATHS += -L"${shell cygpath -w $(BOARDDIR)}"
+else
+ LIBPATHS = $(addprefix -L$(TOPDIR)/,$(dir $(LINKLIBS)))
+ LIBPATHS += -L"$(BOARDDIR)"
+endif
+LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(LINKLIBS))))
+
+BOARDDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src/board
+
+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)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $@, $${obj}); \
+ done ; )
+
+board/libboard$(LIBEXT):
+ @$(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES)
+
+nuttx: $(HEAD_OBJ) board/libboard$(LIBEXT)
+ @echo "LD: nuttx"
+ @$(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) -o $(NUTTX)$(EXEEXT) $(HEAD_OBJ) $(EXTRA_OBJS) \
+ --start-group $(LDLIBS) -lboard $(EXTRA_LIBS) $(LIBGCC) --end-group
+ @$(NM) $(NUTTX)$(EXEEXT) | \
+ grep -v '\(compiled\)\|\(\$(OBJEXT)$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \
+ sort > $(TOPDIR)/System.map
+
+# 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_head: board/libboard$(LIBEXT) $(HEAD_OBJ)
+ifneq ($(HEAD_OBJ),)
+ @if [ -d "$(EXPORT_DIR)/startup" ]; then \
+ cp -f $(HEAD_OBJ) "$(EXPORT_DIR)/startup"; \
+ else \
+ echo "$(EXPORT_DIR)/startup does not exist"; \
+ exit 1; \
+ fi
+endif
+
+# Dependencies
+
+.depend: Makefile chip/Make.defs $(SRCS)
+ @if [ -e board/Makefile ]; then \
+ $(MAKE) -C board TOPDIR="$(TOPDIR)" depend ; \
+ fi
+ @$(MKDEP) --dep-path chip --dep-path common --dep-path $(ARCH_SUBDIR) \
+ $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @if [ -e board/Makefile ]; then \
+ $(MAKE) -C board TOPDIR="$(TOPDIR)" clean ; \
+ fi
+ @rm -f libarch$(LIBEXT) *~ .*.swp
+ $(call CLEAN)
+
+distclean: clean
+ @if [ -e board/Makefile ]; then \
+ $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean ; \
+ fi
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/nuttx/arch/arm/src/arm/arm.h b/nuttx/arch/arm/src/arm/arm.h
new file mode 100644
index 000000000..2ad31fc46
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/arm.h
@@ -0,0 +1,451 @@
+/************************************************************************************
+ * arch/arm/src/arm/arm.h
+ *
+ * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/arm/pg_macros.h b/nuttx/arch/arm/src/arm/pg_macros.h
new file mode 100644
index 000000000..dc65a5d06
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+#include <nuttx/page.h>
+
+#include "arm.h"
+
+/****************************************************************************
+ * 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 asfollows:
+ *
+ * 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/nuttx/arch/arm/src/arm/up_allocpage.c b/nuttx/arch/arm/src/arm/up_allocpage.c
new file mode 100644
index 000000000..0284e48bc
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/sched.h>
+
+#ifdef CONFIG_PAGING
+
+#include <nuttx/page.h>
+
+#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 _TCB *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/nuttx/arch/arm/src/arm/up_assert.c b/nuttx/arch/arm/src/arm/up_assert.c
new file mode 100644
index 000000000..023e6e22d
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_assert.c
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_assert.c
+ *
+ * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Output debug info if stack dump is selected -- even if
+ * debug is not selected.
+ */
+
+#ifdef CONFIG_ARCH_STACKDUMP
+# undef lldbg
+# define lldbg lib_lowprintf
+#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 lib_lowprintf() 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()
+#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: up_dumpstate
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_STACKDUMP
+static void up_dumpstate(void)
+{
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+ 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_heapbase - 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_userstack;
+ 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_userstack;
+ 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();
+}
+#else
+# define up_dumpstate()
+#endif
+
+/****************************************************************************
+ * Name: _up_assert
+ ****************************************************************************/
+
+static void _up_assert(int errorcode) /* __attribute__ ((noreturn)) */
+{
+ /* Are we in an interrupt handler or the idle task? */
+
+ if (current_regs || ((_TCB*)g_readytorun.head)->pid == 0)
+ {
+ (void)irqsave();
+ for(;;)
+ {
+#ifdef CONFIG_ARCH_LEDS
+ up_ledon(LED_PANIC);
+ up_mdelay(250);
+ up_ledoff(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
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+#endif
+
+ up_ledon(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();
+ _up_assert(EXIT_FAILURE);
+}
+
+/****************************************************************************
+ * Name: up_assert_code
+ ****************************************************************************/
+
+void up_assert_code(const uint8_t *filename, int lineno, int errorcode)
+{
+#ifdef CONFIG_PRINT_TASKNAME
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+#endif
+
+ up_ledon(LED_ASSERTION);
+
+#ifdef CONFIG_PRINT_TASKNAME
+ lldbg("Assertion failed at file:%s line: %d task: %s error code: %d\n",
+ filename, lineno, rtcb->name, errorcode);
+#else
+ lldbg("Assertion failed at file:%s line: %d error code: %d\n",
+ filename, lineno, errorcode);
+#endif
+ up_dumpstate();
+ _up_assert(errorcode);
+}
diff --git a/nuttx/arch/arm/src/arm/up_blocktask.c b/nuttx/arch/arm/src/arm/up_blocktask.c
new file mode 100644
index 000000000..f72a02465
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_blocktask.c
@@ -0,0 +1,167 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_blocktask.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdbool.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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(_TCB *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))
+ {
+ PANIC(OSERR_BADBLOCKSTATE);
+ }
+ else
+ {
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+ 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);
+
+ /* If there are any pending tasks, then add them to the g_readytorun
+ * task list now
+ */
+
+ if (g_pendingtasks.head)
+ {
+ switch_needed |= sched_mergepending();
+ }
+
+ /* Now, perform the context switch if one is needed */
+
+ if (switch_needed)
+ {
+ /* 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 g_readytorun task list.
+ */
+
+ rtcb = (_TCB*)g_readytorun.head;
+
+ /* Then switch contexts */
+
+ up_restorestate(rtcb->xcp.regs);
+ }
+
+ /* Copy the user C context into the TCB at the (old) head of the
+ * g_readytorun 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 g_readytorun task list.
+ */
+
+ rtcb = (_TCB*)g_readytorun.head;
+
+ /* Then switch contexts */
+
+ up_fullcontextrestore(rtcb->xcp.regs);
+ }
+ }
+ }
+}
diff --git a/nuttx/arch/arm/src/arm/up_cache.S b/nuttx/arch/arm/src/arm/up_cache.S
new file mode 100644
index 000000000..1d459e693
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_cache.S
@@ -0,0 +1,74 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_cache.S
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include "up_internal.h"
+#include "up_arch.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+#define CACHE_DLINESIZE 32
+
+/****************************************************************************
+ * Assembly Macros
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_flushicache
+ ****************************************************************************/
+
+/* Esure coherency between the Icache and the Dcache in the region described
+ * by r0=start and r1=end.
+ */
+ .globl up_flushicache
+ .type up_flushicache,%function
+up_flushicache:
+ 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 up_flushicache, .-up_flushicache
+ .end
+
diff --git a/nuttx/arch/arm/src/arm/up_checkmapping.c b/nuttx/arch/arm/src/arm/up_checkmapping.c
new file mode 100644
index 000000000..ca8c3a032
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/sched.h>
+#include <nuttx/page.h>
+
+#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 _TCB *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/nuttx/arch/arm/src/arm/up_copystate.c b/nuttx/arch/arm/src/arm/up_copystate.c
new file mode 100644
index 000000000..c76ee8e70
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_copystate.c
@@ -0,0 +1,82 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_copystate.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+
+#include "os_internal.h"
+#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/nuttx/arch/arm/src/arm/up_dataabort.c b/nuttx/arch/arm/src/arm/up_dataabort.c
new file mode 100644
index 000000000..f01941968
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_dataabort.c
@@ -0,0 +1,201 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_dataabort.c
+ *
+ * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+
+#include "os_internal.h"
+#include "up_internal.h"
+
+#ifdef CONFIG_PAGING
+# include <nuttx/page.h>
+# include "arm.h"
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Output debug info if stack dump is selected -- even if
+ * debug is not selected.
+ */
+
+#ifdef CONFIG_ARCH_STACKDUMP
+# undef lldbg
+# define lldbg lib_lowprintf
+#endif
+
+/****************************************************************************
+ * 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)
+{
+ FAR _TCB *tcb = (FAR _TCB *)g_readytorun.head;
+#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(OSERR_ERREXCEPTION);
+}
+
+#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(OSERR_ERREXCEPTION);
+}
+
+#endif /* CONFIG_PAGING */
diff --git a/nuttx/arch/arm/src/arm/up_doirq.c b/nuttx/arch/arm/src/arm/up_doirq.c
new file mode 100644
index 000000000..c82587fff
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_doirq.c
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_doirq.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <assert.h>
+
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void up_doirq(int irq, uint32_t *regs)
+{
+ up_ledon(LED_INIRQ);
+#ifdef CONFIG_SUPPRESS_INTERRUPTS
+ PANIC(OSERR_ERREXCEPTION);
+#else
+ uint32_t *savestate;
+
+ /* Nested interrupts are not supported in this implementation. If you want
+ * implemented nested interrupts, you would have to (1) change the way that
+ * current regs is handled and (2) the design associated with
+ * CONFIG_ARCH_INTERRUPTSTACK.
+ */
+
+ /* 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;
+
+ /* Mask and acknowledge the interrupt */
+
+ up_maskack_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;
+
+ /* Unmask the last interrupt (global interrupts are still disabled) */
+
+ up_enable_irq(irq);
+#endif
+ up_ledoff(LED_INIRQ);
+}
diff --git a/nuttx/arch/arm/src/arm/up_fullcontextrestore.S b/nuttx/arch/arm/src/arm/up_fullcontextrestore.S
new file mode 100644
index 000000000..44573a5f4
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/irq.h>
+#include "up_internal.h"
+
+/**************************************************************************
+ * Private Definitions
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Types
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Function Prototypes
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * 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/nuttx/arch/arm/src/arm/up_head.S b/nuttx/arch/arm/src/arm/up_head.S
new file mode 100644
index 000000000..91d67fd15
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_head.S
@@ -0,0 +1,638 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_head.S
+ *
+ * Copyright (C) 2007, 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include "arm.h"
+#include "chip.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+#ifdef CONFIG_PAGING
+# include <nuttx/page.h>
+# 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 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 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 CONFIG_DRAM_START == CONFIG_DRAM_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
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* RX_NSECTIONS determines the number of 1Mb sections to map for the
+ * Read/eXecute address region. This is based on CONFIG_DRAM_SIZE. For most
+ * ARM9 architectures, CONFIG_DRAM_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_DRAM_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, 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.
+ */
+
+#ifdef 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 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 */
+
+ /* Create a virtual single section mapping for the first MB of the .text
+ * address space. Now, we have the first 1MB mapping to both phyical 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 additinal 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
+ /* Now setup the pagetables for our normal SDRAM mappings mapped 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 & 0xff000000) >> 18
+ bic r2, r3, #0x00f00000
+ str r2, [r0]
+
+ add r0, r0, #(NUTTX_START_VADDR & 0x00f00000) >> 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
+
+ /* Finally branch to the OS entry point */
+
+ mov lr, #0
+ b 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_heapbase below.
+ */
+
+.Linitparms:
+ .long _sbss
+ .long _ebss
+ .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4
+
+#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
+ .size .Lvstart, .-.Lvstart
+
+ /* Data section variables */
+
+ /* This global variable is unsigned long g_heapbase and is
+ * exported from here only because of its coupling to .Linitparms
+ * above.
+ */
+
+ .data
+ .align 4
+ .globl g_heapbase
+ .type g_heapbase, object
+g_heapbase:
+ .long _ebss+CONFIG_IDLETHREAD_STACKSIZE
+ .size g_heapbase, .-g_heapbase
+ .end
+
diff --git a/nuttx/arch/arm/src/arm/up_initialstate.c b/nuttx/arch/arm/src/arm/up_initialstate.c
new file mode 100644
index 000000000..fb672a2ac
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <string.h>
+
+#include <nuttx/arch.h>
+
+#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(_TCB *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_NUTTX_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/nuttx/arch/arm/src/arm/up_nommuhead.S b/nuttx/arch/arm/src/arm/up_nommuhead.S
new file mode 100644
index 000000000..aac95b73a
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_nommuhead.S
@@ -0,0 +1,167 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_nommuhead.S
+ *
+ * Copyright (C) 2007, 2009-2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#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, 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. */
+
+#ifdef CONFIG_BOOT_RUNFROMFLASH
+
+ adr r3, LC2
+ 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 up_ledinit
+#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_heapbase
+ * below.
+ */
+
+LC0: .long _sbss
+ .long _ebss
+ .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4
+
+#ifdef CONFIG_BOOT_RUNFROMFLASH
+LC2: .long _eronly /* Where .data defaults are stored in FLASH */
+ .long _sdata /* Where .data needs to reside in SDRAM */
+ .long _edata
+#endif
+ .size __start, .-__start
+
+ /* This global variable is unsigned long g_heapbase and is
+ * exported from here only because of its coupling to LCO
+ * above.
+ */
+
+ .data
+ .align 4
+ .globl g_heapbase
+ .type g_heapbase, object
+g_heapbase:
+ .long _ebss+CONFIG_IDLETHREAD_STACKSIZE
+ .size g_heapbase, .-g_heapbase
+
+ .end
+
diff --git a/nuttx/arch/arm/src/arm/up_pginitialize.c b/nuttx/arch/arm/src/arm/up_pginitialize.c
new file mode 100644
index 000000000..5470f73e3
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <debug.h>
+
+#include <nuttx/sched.h>
+#include <nuttx/page.h>
+
+#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/nuttx/arch/arm/src/arm/up_prefetchabort.c b/nuttx/arch/arm/src/arm/up_prefetchabort.c
new file mode 100644
index 000000000..9af644fc0
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_prefetchabort.c
@@ -0,0 +1,154 @@
+/****************************************************************************
+ * arch/arm/src/src/up_prefetchabort.c
+ *
+ * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#ifdef CONFIG_PAGING
+# include <nuttx/page.h>
+#endif
+
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Debug ********************************************************************/
+
+/* Output debug info if stack dump is selected -- even if
+ * debug is not selected.
+ */
+
+#ifdef CONFIG_ARCH_STACKDUMP
+# undef lldbg
+# define lldbg lib_lowprintf
+#endif
+
+/****************************************************************************
+ * 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.
+ */
+
+ FAR _TCB *tcb = (FAR _TCB *)g_readytorun.head;
+ 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(OSERR_ERREXCEPTION);
+ }
+}
diff --git a/nuttx/arch/arm/src/arm/up_releasepending.c b/nuttx/arch/arm/src/arm/up_releasepending.c
new file mode 100644
index 000000000..8adeeb26d
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_releasepending.c
@@ -0,0 +1,132 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_releasepending.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sched.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+
+ slldbg("From TCB=%p\n", rtcb);
+
+ /* Merge the g_pendingtasks list into the g_readytorun task list */
+
+ /* sched_lock(); */
+ if (sched_mergepending())
+ {
+ /* The currently active task has changed! We will need to
+ * switch contexts. First check if we are 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 g_readytorun task list.
+ */
+
+ rtcb = (_TCB*)g_readytorun.head;
+ slldbg("New Active Task TCB=%p\n", rtcb);
+
+ /* Then switch contexts */
+
+ 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 g_readytorun task list.
+ */
+
+ rtcb = (_TCB*)g_readytorun.head;
+ slldbg("New Active Task TCB=%p\n", rtcb);
+
+ /* Then switch contexts */
+
+ up_fullcontextrestore(rtcb->xcp.regs);
+ }
+ }
+}
diff --git a/nuttx/arch/arm/src/arm/up_reprioritizertr.c b/nuttx/arch/arm/src/arm/up_reprioritizertr.c
new file mode 100644
index 000000000..02bc39d62
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_reprioritizertr.c
@@ -0,0 +1,187 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_reprioritizertr.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sched.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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(_TCB *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(OSERR_BADREPRIORITIZESTATE);
+ }
+ else
+ {
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+ 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();
+ }
+
+ /* 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 g_readytorun task list.
+ */
+
+ rtcb = (_TCB*)g_readytorun.head;
+ slldbg("New Active Task TCB=%p\n", rtcb);
+
+ /* Then switch contexts */
+
+ up_restorestate(rtcb->xcp.regs);
+ }
+
+ /* Copy the exception context into the TCB at the (old) head of the
+ * g_readytorun 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 g_readytorun task list.
+ */
+
+ rtcb = (_TCB*)g_readytorun.head;
+ slldbg("New Active Task TCB=%p\n", rtcb);
+
+ /* Then switch contexts */
+
+ up_fullcontextrestore(rtcb->xcp.regs);
+ }
+ }
+ }
+}
diff --git a/nuttx/arch/arm/src/arm/up_saveusercontext.S b/nuttx/arch/arm/src/arm/up_saveusercontext.S
new file mode 100644
index 000000000..43487cc42
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/irq.h>
+#include "up_internal.h"
+
+/**************************************************************************
+ * Private Definitions
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Types
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Function Prototypes
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * 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/nuttx/arch/arm/src/arm/up_schedulesigaction.c b/nuttx/arch/arm/src/arm/up_schedulesigaction.c
new file mode 100644
index 000000000..a76438f94
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_schedulesigaction.c
@@ -0,0 +1,204 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_schedulesigaction.c
+ *
+ * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "arm.h"
+#include "os_internal.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(_TCB *tcb, sig_deliver_t sigdeliver)
+{
+ /* Refuse to handle nested signal actions */
+
+ sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
+
+ if (!tcb->xcp.sigdeliver)
+ {
+ irqstate_t flags;
+
+ /* Make sure that interrupts are disabled */
+
+ flags = irqsave();
+
+ /* 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", g_readytorun.head, current_regs);
+
+ if (tcb == (_TCB*)g_readytorun.head)
+ {
+ /* 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 at g_readytorun.head!
+ */
+
+ 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;
+ }
+
+ irqrestore(flags);
+ }
+}
+
+#endif /* !CONFIG_DISABLE_SIGNALS */
diff --git a/nuttx/arch/arm/src/arm/up_sigdeliver.c b/nuttx/arch/arm/src/arm/up_sigdeliver.c
new file mode 100644
index 000000000..868449448
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_sigdeliver.c
@@ -0,0 +1,139 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_sigdeliver.c
+ *
+ * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "os_internal.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)
+{
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+ 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;
+
+ up_ledon(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_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 */
+
+ irqrestore(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)irqsave();
+ rtcb->pterrno = saved_errno;
+
+ /* Then restore the correct state for this thread of execution. */
+
+ up_ledoff(LED_SIGNAL);
+ up_fullcontextrestore(regs);
+}
+
+#endif /* !CONFIG_DISABLE_SIGNALS */
+
diff --git a/nuttx/arch/arm/src/arm/up_syscall.c b/nuttx/arch/arm/src/arm/up_syscall.c
new file mode 100644
index 000000000..1bcd66502
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_syscall.c
@@ -0,0 +1,96 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_syscall.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Output debug info if stack dump is selected -- even if
+ * debug is not selected.
+ */
+
+#ifdef CONFIG_ARCH_STACKDUMP
+# undef lldbg
+# define lldbg lib_lowprintf
+#endif
+
+/****************************************************************************
+ * 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(OSERR_ERREXCEPTION);
+}
diff --git a/nuttx/arch/arm/src/arm/up_unblocktask.c b/nuttx/arch/arm/src/arm/up_unblocktask.c
new file mode 100644
index 000000000..633dc4e82
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_unblocktask.c
@@ -0,0 +1,159 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_unblocktask.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sched.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "clock_internal.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 taks, executed.
+ *
+ ****************************************************************************/
+
+void up_unblock_task(_TCB *tcb)
+{
+ /* Verify that the context switch can be performed */
+
+ if ((tcb->task_state < FIRST_BLOCKED_STATE) ||
+ (tcb->task_state > LAST_BLOCKED_STATE))
+ {
+ PANIC(OSERR_BADUNBLOCKSTATE);
+ }
+ else
+ {
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+
+ /* Remove the task from the blocked task list */
+
+ sched_removeblocked(tcb);
+
+ /* Reset its timeslice. This is only meaningful for round
+ * robin tasks but it doesn't here to do it for everything
+ */
+
+#if CONFIG_RR_INTERVAL > 0
+ tcb->timeslice = CONFIG_RR_INTERVAL / MSEC_PER_TICK;
+#endif
+
+ /* Add the task in the correct location in the prioritized
+ * g_readytorun task list
+ */
+
+ if (sched_addreadytorun(tcb))
+ {
+ /* The currently active task has changed! We need to do
+ * a context switch to the new task.
+ *
+ * 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 g_readytorun task list.
+ */
+
+ rtcb = (_TCB*)g_readytorun.head;
+
+ /* Then switch contexts */
+
+ 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
+ * g_readytorun task list.
+ */
+
+ rtcb = (_TCB*)g_readytorun.head;
+
+ /* Then switch contexts */
+
+ up_fullcontextrestore(rtcb->xcp.regs);
+ }
+ }
+ }
+}
diff --git a/nuttx/arch/arm/src/arm/up_undefinedinsn.c b/nuttx/arch/arm/src/arm/up_undefinedinsn.c
new file mode 100644
index 000000000..d61abe11b
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_undefinedinsn.c
@@ -0,0 +1,81 @@
+/****************************************************************************
+ * arch/arm/src/arm/up_undefinedinsn.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <stdint.h>
+#include <debug.h>
+
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Output debug info if stack dump is selected -- even if
+ * debug is not selected.
+ */
+
+#ifdef CONFIG_ARCH_STACKDUMP
+# undef lldbg
+# define lldbg lib_lowprintf
+#endif
+
+/****************************************************************************
+ * 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(OSERR_UNDEFINEDINSN);
+}
diff --git a/nuttx/arch/arm/src/arm/up_va2pte.c b/nuttx/arch/arm/src/arm/up_va2pte.c
new file mode 100644
index 000000000..eb5a4c56b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/sched.h>
+#include <nuttx/page.h>
+
+#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/nuttx/arch/arm/src/arm/up_vectoraddrexcptn.S b/nuttx/arch/arm/src/arm/up_vectoraddrexcptn.S
new file mode 100644
index 000000000..ba5787cb9
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_vectoraddrexcptn.S
@@ -0,0 +1,83 @@
+/************************************************************************************
+ * arch/arm/src/src/up_vectoraddrexceptn.S
+ *
+ * Copyright (C) 2008-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <nuttx/irq.h>
+#include "up_arch.h"
+
+/************************************************************************************
+ * Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Global 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/nuttx/arch/arm/src/arm/up_vectors.S b/nuttx/arch/arm/src/arm/up_vectors.S
new file mode 100644
index 000000000..bcf9c37d0
--- /dev/null
+++ b/nuttx/arch/arm/src/arm/up_vectors.S
@@ -0,0 +1,446 @@
+/************************************************************************************
+ * arch/arm/src/arm/up_vectors.S
+ *
+ * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <nuttx/irq.h>
+
+#include "arm.h"
+#include "up_arch.h"
+
+/************************************************************************************
+ * Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Global 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 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 up_stackbase
+#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 modr 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 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
+ .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 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
+ .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 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
+ .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: up_interruptstack/g_userstack
+ ************************************************************************************/
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ .bss
+ .align 4
+ .globl g_userstack
+ .type g_userstack, object
+up_interruptstack:
+ .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4)
+g_userstack:
+up_stackbase:
+ .skip 4
+ .size g_userstack, 4
+ .size up_interruptstack, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
+#endif
+ .end
diff --git a/nuttx/arch/arm/src/arm/up_vectortab.S b/nuttx/arch/arm/src/arm/up_vectortab.S
new file mode 100644
index 000000000..8eae70055
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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/nuttx/arch/arm/src/armv7-m/exc_return.h b/nuttx/arch/arm/src/armv7-m/exc_return.h
new file mode 100644
index 000000000..cffbd3e2e
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/exc_return.h
@@ -0,0 +1,117 @@
+/************************************************************************************
+ * arch/arm/src/armv7-m/exc_return.h
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_CORTEXM_EXC_RETURN_H
+#define __ARCH_ARM_SRC_COMMON_CORTEXM_EXC_RETURN_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+/************************************************************************************
+ * 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.
+ */
+
+#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
+
+/* In the kernel build is not selected, then all threads run in privileged thread
+ * mode.
+ */
+
+#ifdef CONFIG_NUTTX_KERNEL
+# define EXC_RETURN 0xfffffff9
+#endif
+
+/************************Th************************************************************
+ * Inline Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_COMMON_CORTEXM_EXC_RETURN_H */
+
diff --git a/nuttx/arch/arm/src/armv7-m/mpu.h b/nuttx/arch/arm/src/armv7-m/mpu.h
new file mode 100644
index 000000000..8d4cd1829
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/mpu.h
@@ -0,0 +1,509 @@
+/************************************************************************************
+ * arch/arm/src/armv7-m/mpu.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_CORTEXM_MPU_H
+#define __ARCH_ARM_SRC_COMMON_CORTEXM_MPU_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifndef __ASSEMBLY__
+# include <sys/types.h>
+# include <stdint.h>
+# include <stdbool.h>
+# include <debug.h>
+
+# 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 */
+
+/* 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 regsion */
+#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 */
+
+#define MPU_RNR_MASK (0xff)
+
+/* 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 (21) /* Bits 19-21: TEX Address Permisson */
+#define MPU_RASR_ATTR__MASK (7 << MPU_RASR_ATTR_SHIFT)
+#define MPU_RASR_S (1 << 18) /* Bit 18: Shareable */
+#define MPU_RASR_C (1 << 17) /* Bit 17: Cacheable */
+#define MPU_RASR_B (1 << 16) /* Bit 16: Bufferable */
+#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 */
+
+/************************************************************************************
+ * Global 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
+ *
+ ****************************************************************************/
+
+EXTERN unsigned int mpu_allocregion(void);
+
+/****************************************************************************
+ * Name: mpu_log2regionsize
+ *
+ * Description:
+ * Determine the smallest value of l2size (log base 2 size) such that the
+ * following is true:
+ *
+ * size <= (1 << l2size)
+ *
+ ****************************************************************************/
+
+EXTERN uint8_t mpu_log2regionsize(size_t size);
+
+/****************************************************************************
+ * 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_log2regionsize()
+ *
+ ****************************************************************************/
+
+EXTERN uint32_t mpu_subregion(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_userflash
+ *
+ * Description:
+ * Configure a region for user program flash
+ *
+ ****************************************************************************/
+
+static inline void mpu_userflash(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_log2regionsize(size);
+ subregions = mpu_subregion(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_privflash
+ *
+ * Description:
+ * Configure a region for privileged program flash
+ *
+ ****************************************************************************/
+
+static inline void mpu_privflash(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_log2regionsize(size);
+ subregions = mpu_subregion(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_userintsram
+ *
+ * Description:
+ * Configure a region as user internal SRAM
+ *
+ ****************************************************************************/
+
+static inline void mpu_userintsram(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_log2regionsize(size);
+ subregions = mpu_subregion(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_privintsram
+ *
+ * Description:
+ * Configure a region as privileged internal SRAM
+ *
+ ****************************************************************************/
+
+static inline void mpu_privintsram(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_log2regionsize(size);
+ subregions = mpu_subregion(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_userextsram
+ *
+ * Description:
+ * Configure a region as user external SRAM
+ *
+ ****************************************************************************/
+
+static inline void mpu_userextsram(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_log2regionsize(size);
+ subregions = mpu_subregion(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_privextsram
+ *
+ * Description:
+ * Configure a region as privileged external SRAM
+ *
+ ****************************************************************************/
+
+static inline void mpu_privextsram(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_log2regionsize(size);
+ subregions = mpu_subregion(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_log2regionsize(size);
+ subregions = mpu_subregion(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_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_COMMON_CORTEXM_MPU_H */
+
diff --git a/nuttx/arch/arm/src/armv7-m/nvic.h b/nuttx/arch/arm/src/armv7-m/nvic.h
new file mode 100644
index 000000000..1d30c5f7c
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/nvic.h
@@ -0,0 +1,531 @@
+/********************************************************************************************
+ * arch/arm/src/armv7-m/nvic.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/********************************************************************************************
+ * 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_AIRC_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_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_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_AIRC (ARMV7M_NVIC_BASE + NVIC_AIRC_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_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_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 4-0: Number of interrupt intputs / 32 */
+#define NVIC_ICTR_INTLINESNUM_MASK (0x1f << 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 */
+
+/* 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)
+
+/* 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 */
+
+/* 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 */
+
+/********************************************************************************************
+ * Public Types
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Data
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Function Prototypes
+ ********************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_COMMON_ARMV7_M_NVIC_H */
diff --git a/nuttx/arch/arm/src/armv7-m/psr.h b/nuttx/arch/arm/src/armv7-m/psr.h
new file mode 100644
index 000000000..b8b33c80f
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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/nuttx/arch/arm/src/armv7-m/svcall.h b/nuttx/arch/arm/src/armv7-m/svcall.h
new file mode 100644
index 000000000..9a4db89b1
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/svcall.h
@@ -0,0 +1,94 @@
+/************************************************************************************
+ * arch/arm/src/armv7-m/svcall.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_CORTEXM_SVCALL_H
+#define __ARCH_ARM_SRC_COMMON_CORTEXM_SVCALL_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifdef CONFIG_NUTTX_KERNEL
+# include <syscall.h>
+#endif
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Configuration ********************************************************************/
+/* This logic uses three system calls {0,1,2} for context switching. The first three
+ * syscall values must be reserved.
+ */
+
+#ifdef CONFIG_NUTTX_KERNEL
+# ifndef CONFIG_SYS_RESERVED
+# error "CONFIG_SYS_RESERVED must be defined to the value 3"
+# elif CONFIG_SYS_RESERVED != 3
+# error "CONFIG_SYS_RESERVED must have the value 3"
+# endif
+#endif
+
+/* Cortex M3 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) __attribute__ ((noreturn));
+ */
+
+#define SYS_restore_context (1)
+
+/* SYS call 2:
+ *
+ * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs);
+ */
+
+#define SYS_switch_context (2)
+
+/************************************************************************************
+ * Inline Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_COMMON_CORTEXM_SVCALL_H */
+
diff --git a/nuttx/arch/arm/src/armv7-m/up_assert.c b/nuttx/arch/arm/src/armv7-m/up_assert.c
new file mode 100644
index 000000000..2662cbe37
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_assert.c
@@ -0,0 +1,334 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_assert.c
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Output debug info if stack dump is selected -- even if
+ * debug is not selected.
+ */
+
+#ifdef CONFIG_ARCH_STACKDUMP
+# undef lldbg
+# define lldbg lib_lowprintf
+#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 lib_lowprintf() 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()
+#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]);
+ lldbg("xPSR: %08x PRIMASK: %08x\n",
+ current_regs[REG_XPSR], current_regs[REG_PRIMASK]);
+ }
+}
+#else
+# define up_registerdump()
+#endif
+
+/****************************************************************************
+ * Name: up_dumpstate
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_STACKDUMP
+static void up_dumpstate(void)
+{
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+ 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_heapbase - 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 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);
+
+ /* 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);
+
+ /* 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();
+}
+#else
+# define up_dumpstate()
+#endif
+
+/****************************************************************************
+ * Name: _up_assert
+ ****************************************************************************/
+
+static void _up_assert(int errorcode) /* __attribute__ ((noreturn)) */
+{
+ /* Are we in an interrupt handler or the idle task? */
+
+ if (current_regs || ((_TCB*)g_readytorun.head)->pid == 0)
+ {
+ (void)irqsave();
+ for(;;)
+ {
+#ifdef CONFIG_ARCH_LEDS
+ up_ledon(LED_PANIC);
+ up_mdelay(250);
+ up_ledoff(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
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+#endif
+
+ up_ledon(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();
+ _up_assert(EXIT_FAILURE);
+}
+
+/****************************************************************************
+ * Name: up_assert_code
+ ****************************************************************************/
+
+void up_assert_code(const uint8_t *filename, int lineno, int errorcode)
+{
+#ifdef CONFIG_PRINT_TASKNAME
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+#endif
+
+ up_ledon(LED_ASSERTION);
+#ifdef CONFIG_PRINT_TASKNAME
+ lldbg("Assertion failed at file:%s line: %d task: %s error code: %d\n",
+ filename, lineno, rtcb->name, errorcode);
+#else
+ lldbg("Assertion failed at file:%s line: %d error code: %d\n",
+ filename, lineno, errorcode);
+#endif
+ up_dumpstate();
+ _up_assert(errorcode);
+}
diff --git a/nuttx/arch/arm/src/armv7-m/up_blocktask.c b/nuttx/arch/arm/src/armv7-m/up_blocktask.c
new file mode 100644
index 000000000..896476ed2
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_blocktask.c
@@ -0,0 +1,167 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_blocktask.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdbool.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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(_TCB *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))
+ {
+ PANIC(OSERR_BADBLOCKSTATE);
+ }
+ else
+ {
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+ 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);
+
+ /* If there are any pending tasks, then add them to the g_readytorun
+ * task list now
+ */
+
+ if (g_pendingtasks.head)
+ {
+ switch_needed |= sched_mergepending();
+ }
+
+ /* Now, perform the context switch if one is needed */
+
+ if (switch_needed)
+ {
+ /* 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 g_readytorun task list.
+ */
+
+ rtcb = (_TCB*)g_readytorun.head;
+
+ /* Then switch contexts */
+
+ 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.
+ */
+
+ _TCB *nexttcb = (_TCB*)g_readytorun.head;
+ 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/nuttx/arch/arm/src/armv7-m/up_copystate.c b/nuttx/arch/arm/src/armv7-m/up_copystate.c
new file mode 100644
index 000000000..e9eede8f9
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_copystate.c
@@ -0,0 +1,86 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_copystate.c
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+
+#include "os_internal.h"
+#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 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/nuttx/arch/arm/src/armv7-m/up_doirq.c b/nuttx/arch/arm/src/armv7-m/up_doirq.c
new file mode 100644
index 000000000..375054fba
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_doirq.c
@@ -0,0 +1,123 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_doirq.c
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "os_internal.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)
+{
+ up_ledon(LED_INIRQ);
+#ifdef CONFIG_SUPPRESS_INTERRUPTS
+ PANIC(OSERR_ERREXCEPTION);
+#else
+ uint32_t *savestate;
+
+ /* Nested interrupts are not supported in this implementation. If you want
+ * implemented nested interrupts, you would have to (1) change the way that
+ * current regs is handled and (2) the design associated with
+ * CONFIG_ARCH_INTERRUPTSTACK.
+ */
+
+ /* 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;
+
+ /* Mask and acknowledge the interrupt */
+
+ up_maskack_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;
+
+ /* Unmask the last interrupt (global interrupts are still disabled) */
+
+ up_enable_irq(irq);
+#endif
+ up_ledoff(LED_INIRQ);
+ return regs;
+}
diff --git a/nuttx/arch/arm/src/armv7-m/up_exception.S b/nuttx/arch/arm/src/armv7-m/up_exception.S
new file mode 100644
index 000000000..31d8dbb0c
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_exception.S
@@ -0,0 +1,237 @@
+/************************************************************************************
+ * arch/arm/src/stm32/up_exception.S
+ * arch/arm/src/chip/up_exception.S
+ *
+ * Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012 Michael Smith. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <arch/irq.h>
+#include "exc_return.h"
+
+#include "chip.h"
+
+/************************************************************************************
+ * Global 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 */
+ ite eq /* next two instructions conditional */
+ mrseq r1, msp /* R1=The main stack pointer */
+ mrsne r1, psp /* R1=The process stack pointer */
+
+ mov r2, r1 /* 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) */
+ mrs r3, primask /* R3=Current PRIMASK setting */
+
+#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.
+ *
+ * XXX we could do all this saving lazily on the context switch side if we knew where to put
+ * the registers.
+ */
+
+ vstmdb r1!, {s16-s31} /* Save the non-volatile FP context */
+
+#endif
+
+ stmdb r1!, {r2-r11,r14} /* Save the remaining registers plus the SP/PRIMASK values */
+
+ /* 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 sp, =g_intstackbase
+ 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 1f /* 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 2f /* Re-join common logic */
+
+1:
+ /* 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
+
+2:
+ /* The EXC_RETURN value tells us whether we are returning on the MSP or PSP
+ */
+
+ 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 */
+
+ /* Restore the interrupt state */
+
+ msr primask, r3 /* Restore 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: up_interruptstack/g_intstackbase
+ *
+ * Description:
+ * Shouldn't happen
+ *
+ ************************************************************************************/
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ .bss
+ .global g_intstackbase
+ .align 4
+up_interruptstack:
+ .skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
+g_intstackbase:
+ .size up_interruptstack, .-up_interruptstack
+#endif
+
+ .end
+
diff --git a/nuttx/arch/arm/src/armv7-m/up_fpu.S b/nuttx/arch/arm/src/armv7-m/up_fpu.S
new file mode 100644
index 000000000..707420f06
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_fpu.S
@@ -0,0 +1,286 @@
+/************************************************************************************
+ * arch/arm/src/armv7-m/stm32_fpu.S
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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-m3 -mfloat-abi=hard -mfpu=vfp -meabi=5
+ */
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <arch/irq.h>
+
+#ifdef CONFIG_ARCH_FPU
+
+/************************************************************************************
+ * Preprocessor Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Global 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/nuttx/arch/arm/src/armv7-m/up_fullcontextrestore.S b/nuttx/arch/arm/src/armv7-m/up_fullcontextrestore.S
new file mode 100755
index 000000000..3ce51c9cd
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_fullcontextrestore.S
@@ -0,0 +1,95 @@
+/************************************************************************************
+ * arch/arm/src/armv7-m/up_fullcontextrestore.S
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <arch/irq.h>
+
+#include "nvic.h"
+#include "svcall.h"
+
+/************************************************************************************
+ * Preprocessor Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Global 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) __attribute__ ((noreturn));
+ *
+ * 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/nuttx/arch/arm/src/armv7-m/up_hardfault.c b/nuttx/arch/arm/src/armv7-m/up_hardfault.c
new file mode 100644
index 000000000..cb3ce9e8a
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_hardfault.c
@@ -0,0 +1,144 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_hardfault.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#include "up_arch.h"
+#include "os_internal.h"
+#include "nvic.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Debug output from this file may interfere with context switching! */
+
+#undef DEBUG_HARDFAULTS /* Define to debug hard faults */
+
+#ifdef DEBUG_HARDFAULTS
+# define hfdbg(format, arg...) lldbg(format, ##arg)
+#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;
+ uint16_t *pc;
+ uint16_t insn;
+
+ /* Get the value of the program counter where the fault occurred */
+
+ pc = (uint16_t*)regs[REG_PC] - 1;
+ if ((void*)pc >= (void*)&_stext && (void*)pc < (void*)&_etext)
+ {
+ /* Fetch the instruction that caused the Hard fault */
+
+ 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);
+ }
+ }
+
+ /* Dump some hard fault info */
+
+ hfdbg("\nHard Fault:\n");
+ hfdbg(" IRQ: %d regs: %p\n", irq, regs);
+ hfdbg(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x\n",
+ getbasepri(), getprimask(), getipsr());
+ 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]);
+ hfdbg(" PSR=%08x\n", regs[REG_XPSR]);
+
+ (void)irqsave();
+ lldbg("PANIC!!! Hard fault: %08x\n", getreg32(NVIC_HFAULTS));
+ PANIC(OSERR_UNEXPECTEDISR);
+ return OK;
+}
diff --git a/nuttx/arch/arm/src/armv7-m/up_initialstate.c b/nuttx/arch/arm/src/armv7-m/up_initialstate.c
new file mode 100644
index 000000000..81a4dc9ea
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_initialstate.c
@@ -0,0 +1,192 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_initialstate.c
+ *
+ * Copyright (C) 2009, 2011-2 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <nuttx/arch.h>
+
+#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(_TCB *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] = 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;
+ }
+
+ /* 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.
+ */
+
+#ifdef CONFIG_NXFLAT
+ tcb->entry.main = (main_t)((uint32_t)tcb->entry.main | 1);
+#endif
+#endif /* CONFIG_PIC */
+
+#ifdef CONFIG_ARMV7M_CMNVECTOR
+ /* 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.
+ *
+ * If FPU support is not configured, set the bit that indicates that
+ * the context does not include the volatile FP registers.
+ */
+
+ xcp->regs[REG_EXC_RETURN] = EXC_RETURN_BASE | EXC_RETURN_THREAD_MODE;
+
+#ifndef CONFIG_ARCH_FPU
+
+ xcp->regs[REG_EXC_RETURN] |= EXC_RETURN_STD_CONTEXT;
+
+#else
+
+ xcp->regs[REG_FPSCR] = 0; // XXX initial FPSCR should be configurable
+ xcp->regs[REG_FPReserved] = 0;
+
+#endif
+
+#ifdef CONFIG_NUTTX_KERNEL
+ if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
+ {
+ /* It is a normal task or a pthread. Set user mode */
+
+ xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PROCESS_STACK;
+ }
+#endif
+
+#else /* CONFIG_ARMV7M_CMNVECTOR */
+
+ /* 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_NUTTX_KERNEL
+ if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)
+ {
+ /* It is a kernel thread.. set privileged thread mode */
+
+ xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ }
+ else
+ {
+ /* It is a normal task or a pthread. Set user mode */
+
+ xcp->regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ }
+#endif
+#endif /* CONFIG_ARMV7M_CMNVECTOR */
+
+ /* Enable or disable interrupts, based on user configuration */
+
+#ifdef CONFIG_SUPPRESS_INTERRUPTS
+ xcp->regs[REG_PRIMASK] = 1;
+#endif
+}
diff --git a/nuttx/arch/arm/src/armv7-m/up_memfault.c b/nuttx/arch/arm/src/armv7-m/up_memfault.c
new file mode 100644
index 000000000..ab93c7697
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_memfault.c
@@ -0,0 +1,110 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_memfault.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#include "up_arch.h"
+#include "os_internal.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, arg...) lldbg(format, ##arg)
+#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)irqsave();
+ 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(" 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]);
+ mfdbg(" PSR=%08x\n", regs[REG_XPSR]);
+
+ PANIC(OSERR_UNEXPECTEDISR);
+ return OK;
+}
diff --git a/nuttx/arch/arm/src/armv7-m/up_mpu.c b/nuttx/arch/arm/src/armv7-m/up_mpu.c
new file mode 100644
index 000000000..4bb3f21d9
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_mpu.c
@@ -0,0 +1,176 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_mpu.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+
+#include "mpu.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* This set represents 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 array is indexed by the number of subregions: 0 means no sub-
+ * regions (0xff), and 0 means all subregions but one (0x00).
+ */
+
+static const void uint8_t g_regionmap[9] =
+{
+ 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00
+};
+
+/* The next available region number */
+
+static uint8_t g_region;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mpu_allocregion
+ *
+ * Description:
+ * Allocate the next region
+ *
+ * Assumptions:
+ * - Regions are never deallocated
+ * - Regions are only allocated early in initialization, so nothing
+ * special is require;
+ *
+ ****************************************************************************/
+
+unsigned int mpu_allocregion(void)
+{
+ return (unsigned int)g_region++;
+}
+
+/****************************************************************************
+ * Name: mpu_log2regionsize
+ *
+ * Description:
+ * Determine the smallest value of l2size (log base 2 size) such that the
+ * following is true:
+ *
+ * size <= (1 << l2size)
+ *
+ ****************************************************************************/
+
+uint8_t mpu_log2regionsize(size_t size)
+{
+ /* The minimum permitted region size is 16 bytes (log2(16) = 4. */
+
+ uint32_t l2size;
+ for (l2size = 4; l2size < 32 && size > (1 << l2size); size++);
+ 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_log2regionsize()
+ *
+ ****************************************************************************/
+
+uint32_t mpu_subregion(size_t size, uint8_t l2size)
+{
+ unsigned int nsrs
+ uint32_t asize;
+ uint32_t mask;
+
+ /* Eight subregions are support. 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(lsize > 3 && size <= (1 << l2size));
+
+ /* 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 0x03
+ * 0x0c40 0x01ff 0x0e00 9 7 0x01
+ */
+
+ if (l2size < 32)
+ {
+ mask = ((1 << lsize)-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 >> (lsize-3); /* Number of subregions */
+ return g_regionmap[nsrs];
+}
+
+
+
diff --git a/nuttx/arch/arm/src/armv7-m/up_releasepending.c b/nuttx/arch/arm/src/armv7-m/up_releasepending.c
new file mode 100644
index 000000000..2f0d4dc39
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_releasepending.c
@@ -0,0 +1,129 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_releasepending.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sched.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+
+ slldbg("From TCB=%p\n", rtcb);
+
+ /* Merge the g_pendingtasks list into the g_readytorun task list */
+
+ /* sched_lock(); */
+ if (sched_mergepending())
+ {
+ /* The currently active task has changed! We will need to switch
+ * contexts. First check if we are 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 g_readytorun task list.
+ */
+
+ rtcb = (_TCB*)g_readytorun.head;
+ slldbg("New Active Task TCB=%p\n", rtcb);
+
+ /* Then switch contexts */
+
+ 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.
+ */
+
+ _TCB *nexttcb = (_TCB*)g_readytorun.head;
+ 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/nuttx/arch/arm/src/armv7-m/up_reprioritizertr.c b/nuttx/arch/arm/src/armv7-m/up_reprioritizertr.c
new file mode 100644
index 000000000..f1c961b15
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_reprioritizertr.c
@@ -0,0 +1,182 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_reprioritizertr.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sched.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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(_TCB *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 ||
+ priority < SCHED_PRIORITY_MIN ||
+ priority > SCHED_PRIORITY_MAX)
+ {
+ PANIC(OSERR_BADREPRIORITIZESTATE);
+ }
+ else
+ {
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+ 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();
+ }
+
+ /* 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 g_readytorun task list.
+ */
+
+ rtcb = (_TCB*)g_readytorun.head;
+ slldbg("New Active Task TCB=%p\n", rtcb);
+
+ /* Then switch contexts */
+
+ 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.
+ */
+
+ _TCB *nexttcb = (_TCB*)g_readytorun.head;
+ 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/nuttx/arch/arm/src/armv7-m/up_saveusercontext.S b/nuttx/arch/arm/src/armv7-m/up_saveusercontext.S
new file mode 100755
index 000000000..06eb183d2
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_saveusercontext.S
@@ -0,0 +1,104 @@
+/************************************************************************************
+ * arch/arm/src/armv7-m/up_saveusercontext.S
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <arch/irq.h>
+
+#include "nvic.h"
+#include "svcall.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Global 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/nuttx/arch/arm/src/armv7-m/up_schedulesigaction.c b/nuttx/arch/arm/src/armv7-m/up_schedulesigaction.c
new file mode 100644
index 000000000..9e6dbd14b
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_schedulesigaction.c
@@ -0,0 +1,208 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_schedulesigaction.c
+ *
+ * Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "psr.h"
+#include "os_internal.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(_TCB *tcb, sig_deliver_t sigdeliver)
+{
+ /* Refuse to handle nested signal actions */
+
+ sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
+
+ if (!tcb->xcp.sigdeliver)
+ {
+ irqstate_t flags;
+
+ /* Make sure that interrupts are disabled */
+
+ flags = irqsave();
+
+ /* 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", g_readytorun.head, current_regs);
+
+ if (tcb == (_TCB*)g_readytorun.head)
+ {
+ /* 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 at g_readytorun.head!
+ */
+
+ 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_primask = current_regs[REG_PRIMASK];
+ tcb->xcp.saved_xpsr = current_regs[REG_XPSR];
+
+ /* Then set up to vector to the trampoline with interrupts
+ * disabled
+ */
+
+ current_regs[REG_PC] = (uint32_t)up_sigdeliver;
+ current_regs[REG_PRIMASK] = 1;
+ current_regs[REG_XPSR] = ARMV7M_XPSR_T;
+
+ /* 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_primask = tcb->xcp.regs[REG_PRIMASK];
+ tcb->xcp.saved_xpsr = tcb->xcp.regs[REG_XPSR];
+
+ /* Then set up to vector to the trampoline with interrupts
+ * disabled
+ */
+
+ tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver;
+ tcb->xcp.regs[REG_PRIMASK] = 1;
+ tcb->xcp.regs[REG_XPSR] = ARMV7M_XPSR_T;
+ }
+
+ irqrestore(flags);
+ }
+}
+
+#endif /* !CONFIG_DISABLE_SIGNALS */
diff --git a/nuttx/arch/arm/src/armv7-m/up_sigdeliver.c b/nuttx/arch/arm/src/armv7-m/up_sigdeliver.c
new file mode 100644
index 000000000..38673c41d
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_sigdeliver.c
@@ -0,0 +1,142 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_sigdeliver.c
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "os_internal.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)
+{
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+ 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;
+
+ up_ledon(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_PRIMASK] = rtcb->xcp.saved_primask;
+ regs[REG_XPSR] = rtcb->xcp.saved_xpsr;
+
+ /* 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 */
+
+ irqrestore((uint16_t)regs[REG_PRIMASK]);
+
+ /* 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)irqsave();
+ rtcb->pterrno = saved_errno;
+
+ /* Then restore the correct state for this thread of
+ * execution.
+ */
+
+ up_ledoff(LED_SIGNAL);
+ up_fullcontextrestore(regs);
+}
+
+#endif /* !CONFIG_DISABLE_SIGNALS */
+
diff --git a/nuttx/arch/arm/src/armv7-m/up_svcall.c b/nuttx/arch/arm/src/armv7-m/up_svcall.c
new file mode 100644
index 000000000..5a4d64fe2
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_svcall.c
@@ -0,0 +1,363 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_svcall.c
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+#include <nuttx/sched.h>
+
+#ifdef CONFIG_NUTTX_KERNEL
+# include <syscall.h>
+#endif
+
+#include "svcall.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+/* Configuration ************************************************************/
+
+#undef SYSCALL_INTERRUPTIBLE
+#if defined(CONFIG_NUTTX_KERNEL)
+# if CONFIG_ARCH_INTERRUPTSTACK > 3
+# warning "CONFIG_ARCH_INTERRUPTSTACK and CONFIG_NUTTX_KERNEL are incompatible"
+# warning "options as currently implemented. Interrupts will have to be disabled"
+# warning "during SYScall processing to avoid un-handled nested interrupts"
+# else
+# define SYSCALL_INTERRUPTIBLE 1
+# endif
+#endif
+
+/* 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_SCHED
+ *
+ * And you must explicitly define DEBUG_SVCALL below:
+ */
+
+#undef DEBUG_SVCALL /* Define to debug SVCall */
+#ifdef DEBUG_SVCALL
+# define svcdbg(format, arg...) slldbg(format, ##arg)
+#else
+# define svcdbg(x...)
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: dispatch_syscall
+ *
+ * Description:
+ * Dispatch a system call to the appropriate handling logic.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NUTTX_KERNEL
+static inline void dispatch_syscall(uint32_t *regs)
+{
+ uint32_t cmd = regs[REG_R0];
+ FAR _TCB *rtcb = sched_self();
+ uintptr_t ret = (uintptr_t)ERROR;
+
+ /* Verify the the SYS call number is within range */
+
+ if (cmd < SYS_maxsyscall)
+ {
+ /* Report error and return ERROR */
+
+ slldbg("ERROR: Bad SYS call: %d\n", cmd);
+ }
+ else
+ {
+ /* The index into the syscall table is offset by the number of architecture-
+ * specific reserved entries at the beginning of the SYS call number space.
+ */
+
+ int index = cmd - CONFIG_SYS_RESERVED;
+
+ /* Enable interrupts while the SYSCALL executes */
+
+#ifdef SYSCALL_INTERRUPTIBLE
+ irqenable();
+#endif
+
+ /* Call the correct stub for each SYS call, based on the number of parameters */
+
+ svcdbg("Calling stub%d at %p\n", index, g_stubloopkup[index].stub0);
+
+ switch (g_stubnparms[index])
+ {
+ /* No parameters */
+
+ case 0:
+ ret = g_stublookup[index].stub0();
+ break;
+
+ /* Number of parameters: 1 */
+
+ case 1:
+ ret = g_stublookup[index].stub1(regs[REG_R1]);
+ break;
+
+ /* Number of parameters: 2 */
+
+ case 2:
+ ret = g_stublookup[index].stub2(regs[REG_R1], regs[REG_R2]);
+ break;
+
+ /* Number of parameters: 3 */
+
+ case 3:
+ ret = g_stublookup[index].stub3(regs[REG_R1], regs[REG_R2],
+ regs[REG_R3]);
+ break;
+
+ /* Number of parameters: 4 */
+
+ case 4:
+ ret = g_stublookup[index].stub4(regs[REG_R1], regs[REG_R2],
+ regs[REG_R3], regs[REG_R4]);
+ break;
+
+ /* Number of parameters: 5 */
+
+ case 5:
+ ret = g_stublookup[index].stub5(regs[REG_R1], regs[REG_R2],
+ regs[REG_R3], regs[REG_R4],
+ regs[REG_R5]);
+ break;
+
+ /* Number of parameters: 6 */
+
+ case 6:
+ ret = g_stublookup[index].stub6(regs[REG_R1], regs[REG_R2],
+ regs[REG_R3], regs[REG_R4],
+ regs[REG_R5], regs[REG_R6]);
+ break;
+
+ /* Unsupported number of paramters. Report error and return ERROR */
+
+ default:
+ slldbg("ERROR: Bad SYS call %d number parameters %d\n",
+ cmd, g_stubnparms[index]);
+ break;
+ }
+
+#ifdef SYSCALL_INTERRUPTIBLE
+ irqdisable();
+#endif
+ }
+
+ /* Set up the return value. First, check if a context switch occurred.
+ * In this case, regs will no longer be the same as current_regs. In
+ * the case of a context switch, we will have to save the return value
+ * in the TCB where it can be returned later when the task is restarted.
+ */
+
+ if (regs != current_regs)
+ {
+ regs = rtcb->xcp.regs;
+ }
+
+ /* Then return the result in R0 */
+
+ svcdbg("Return value regs: %p value: %d\n", regs, ret);
+ regs[REG_R0] = (uint32_t)ret;
+}
+#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;
+
+ DEBUGASSERT(regs && regs == current_regs);
+
+ /* The SVCall software interrupt is called with R0 = system call command
+ * and R1..R7 = variable number of arguments depending on the system call.
+ */
+
+ svcdbg("SVCALL Entry: regs: %p cmd: %d\n", regs, regs[REG_R0]);
+ 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(" PSR=%08x\n", regs[REG_XPSR]);
+
+ /* Handle the SVCall according to the command in R0 */
+
+ switch (regs[REG_R0])
+ {
+ /* 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)
+ up_savefpu((uint32_t*)regs[REG_R1]);
+#endif
+ }
+ break;
+
+ /* R0=SYS_restore_context: This a restore context command:
+ *
+ * void up_fullcontextrestore(uint32_t *restoreregs) __attribute__ ((noreturn));
+ *
+ * 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 = 1
+ * 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)
+ up_savefpu((uint32_t*)regs[REG_R1]);
+#endif
+ current_regs = (uint32_t*)regs[REG_R2];
+ }
+ break;
+
+ /* 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_NUTTX_KERNEL
+ dispatch_syscall(regs);
+#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 (regs != current_regs)
+ {
+ svcdbg("SVCall Return: Context switch!\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]);
+ svcdbg(" PSR=%08x\n", current_regs[REG_XPSR]);
+ }
+ else
+ {
+ svcdbg("SVCall Return: %d\n", regs[REG_R0]);
+ }
+
+ return OK;
+}
diff --git a/nuttx/arch/arm/src/armv7-m/up_switchcontext.S b/nuttx/arch/arm/src/armv7-m/up_switchcontext.S
new file mode 100755
index 000000000..762e2066e
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_switchcontext.S
@@ -0,0 +1,97 @@
+/************************************************************************************
+ * arch/arm/src/armv7-m/up_switchcontext.S
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <arch/irq.h>
+
+#include "nvic.h"
+#include "svcall.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Global 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) */
+
+ /* This call should not return */
+
+ bx lr /* Unnecessary ... will not return */
+ .size up_switchcontext, .-up_switchcontext
+ .end
+
diff --git a/nuttx/arch/arm/src/armv7-m/up_unblocktask.c b/nuttx/arch/arm/src/armv7-m/up_unblocktask.c
new file mode 100644
index 000000000..da10f0376
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-m/up_unblocktask.c
@@ -0,0 +1,157 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/up_unblocktask.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sched.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "clock_internal.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 taks, executed.
+ *
+ ****************************************************************************/
+
+void up_unblock_task(_TCB *tcb)
+{
+ /* Verify that the context switch can be performed */
+
+ if ((tcb->task_state < FIRST_BLOCKED_STATE) ||
+ (tcb->task_state > LAST_BLOCKED_STATE))
+ {
+ PANIC(OSERR_BADUNBLOCKSTATE);
+ }
+ else
+ {
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+
+ /* Remove the task from the blocked task list */
+
+ sched_removeblocked(tcb);
+
+ /* Reset its timeslice. This is only meaningful for round
+ * robin tasks but it doesn't here to do it for everything
+ */
+
+#if CONFIG_RR_INTERVAL > 0
+ tcb->timeslice = CONFIG_RR_INTERVAL / MSEC_PER_TICK;
+#endif
+
+ /* Add the task in the correct location in the prioritized
+ * g_readytorun task list
+ */
+
+ if (sched_addreadytorun(tcb))
+ {
+ /* The currently active task has changed! We need to do
+ * a context switch to the new task.
+ *
+ * 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 g_readytorun task list.
+ */
+
+ rtcb = (_TCB*)g_readytorun.head;
+
+ /* Then switch contexts */
+
+ 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.
+ */
+
+ _TCB *nexttcb = (_TCB*)g_readytorun.head;
+ 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/nuttx/arch/arm/src/armv7-m/up_vectors.c b/nuttx/arch/arm/src/armv7-m/up_vectors.c
new file mode 100644
index 000000000..b85ac9246
--- /dev/null
+++ b/nuttx/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 <nuttx/config.h>
+
+#include "chip.h"
+
+/************************************************************************************
+ * Preprocessor 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 [ ... ] 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 + ARMV7M_PERIPHERAL_INTERRUPTS)] = (unsigned)&exception_common
+ };
diff --git a/nuttx/arch/arm/src/c5471/Kconfig b/nuttx/arch/arm/src/c5471/Kconfig
new file mode 100644
index 000000000..06363ad7d
--- /dev/null
+++ b/nuttx/arch/arm/src/c5471/Kconfig
@@ -0,0 +1,6 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+comment "C5471 Configuration Options"
diff --git a/nuttx/arch/arm/src/c5471/Make.defs b/nuttx/arch/arm/src/c5471/Make.defs
new file mode 100644
index 000000000..d1c2cf0ac
--- /dev/null
+++ b/nuttx/arch/arm/src/c5471/Make.defs
@@ -0,0 +1,49 @@
+############################################################################
+# c5471/Make.defs
+#
+# Copyright (C) 2007 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# 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
+CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
+ up_createstack.c up_dataabort.c up_mdelay.c up_udelay.c up_doirq.c \
+ up_exit.c up_idle.c up_initialize.c up_initialstate.c \
+ up_interruptcontext.c up_prefetchabort.c up_releasepending.c \
+ up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c \
+ up_sigdeliver.c up_syscall.c up_unblocktask.c \
+ up_undefinedinsn.c up_usestack.c
+
+CHIP_ASRCS = c5471_lowputc.S c5471_vectors.S
+CHIP_CSRCS = c5471_irq.c c5471_serial.c c5471_timerisr.c c5471_watchdog.c \
+ c5471_ethernet.c
diff --git a/nuttx/arch/arm/src/c5471/c5471_ethernet.c b/nuttx/arch/arm/src/c5471/c5471_ethernet.c
new file mode 100644
index 000000000..142e0f084
--- /dev/null
+++ b/nuttx/arch/arm/src/c5471/c5471_ethernet.c
@@ -0,0 +1,2178 @@
+/****************************************************************************
+ * arch/arm/src/c5471/c5471_ethernet.c
+ *
+ * Copyright (C) 2007, 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Based one a C5471 Linux driver and released under this BSD license with
+ * special permisson 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 <nuttx/config.h>
+#if defined(CONFIG_NET)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <debug.h>
+#include <wdog.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+
+#include <net/ethernet.h>
+#include <nuttx/net/uip/uip.h>
+#include <nuttx/net/uip/uip-arp.h>
+#include <nuttx/net/uip/uip-arch.h>
+
+#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.
+ */
+
+/* CONFIG_C5471_ETHERNET_PHY may be set to one of the following values to
+ * select the PHY (or left undefined if there is no PHY)
+ */
+
+#ifndef ETHERNET_PHY_LU3X31T_T64
+# define ETHERNET_PHY_LU3X31T_T64 1
+#endif
+#ifndef ETHERNET_PHY_AC101L
+# define ETHERNET_PHY_AC101L 2
+#endif
+
+/* Mode of operation defaults to AUTONEGOTIATION */
+
+#if defined(CONFIG_NET_C5471_AUTONEGOTIATION)
+# undef CONFIG_NET_C5471_BASET100
+# undef CONFIG_NET_C5471_BASET10
+#elif defined(CONFIG_NET_C5471_BASET100)
+# undef CONFIG_NET_C5471_AUTONEGOTIATION
+# undef CONFIG_NET_C5471_BASET10
+#elif defined(CONFIG_NET_C5471_BASET10)
+# undef CONFIG_NET_C5471_AUTONEGOTIATION
+# undef CONFIG_NET_C5471_BASET100
+#else
+# define CONFIG_NET_C5471_AUTONEGOTIATION 1
+# undef CONFIG_NET_C5471_BASET100
+# undef CONFIG_NET_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)
+#define C5471_POLLHSEC (1*2)
+
+/* 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 uip_eth_hdr *)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 uip_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_uiptxpoll(struct uip_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 uip_driver_s *dev);
+static int c5471_ifdown(struct uip_driver_s *dev);
+static int c5471_txavail(struct uip_driver_s *dev);
+#ifdef CONFIG_NET_IGMP
+static int c5471_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
+static int c5471_rmmac(struct uip_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 (CONFIG_C5471_ETHERNET_PHY == ETHERNET_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_NET_C5471_AUTONEGOTIATION
+ ndbg("Setting PHY Transceiver for Autonegotiation\n");
+ c5471_mdwrite(0, MD_PHY_CONTROL_REG, MODE_AUTONEG);
+#endif
+#ifdef CONFIG_NET_C5471_BASET100
+ ndbg("Setting PHY Transceiver for 100BaseT FullDuplex\n");
+ c5471_mdwrite(0, MD_PHY_CONTROL_REG, MODE_100MBIT_FULLDUP);
+#endif
+#ifdef CONFIG_NET_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 (CONFIG_C5471_ETHERNET_PHY == ETHERNET_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()
+# if defined(CONFIG_C5471_ETHERNET_PHY)
+# error "CONFIG_C5471_ETHERNET_PHY value not recognized"
+# else
+# warning "CONFIG_C5471_ETHERNET_PHY not defined -- assumed NO PHY"
+# endif
+#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 uip_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_uiptxpoll
+ *
+ * Description:
+ * The transmitter is available, check if uIP has any outgoing packets ready
+ * to send. This is a callback from uip_poll(). uip_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_uiptxpoll(struct uip_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)
+ {
+ uip_arp_out(&c5471->c_dev);
+ 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 uip_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_BUFSIZE + 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_BUFSIZE)
+ {
+ /* 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);
+
+ /* We only accept IP packets of the configured type and ARP packets */
+
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(UIP_ETHTYPE_IP6))
+#else
+ if (BUF->type == HTONS(UIP_ETHTYPE_IP))
+#endif
+ {
+ uip_arp_ipin(dev);
+ uip_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)
+ {
+ uip_arp_out(dev);
+ c5471_transmit(c5471);
+ }
+ }
+ else if (BUF->type == HTONS(UIP_ETHTYPE_ARP))
+ {
+ uip_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);
+ }
+ }
+ }
+#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)uip_poll(&c5471->c_dev, c5471_uiptxpoll);
+}
+
+/****************************************************************************
+ * 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)uip_poll(&c5471->c_dev, c5471_uiptxpoll);
+}
+
+/****************************************************************************
+ * 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)uip_timer(&c5471->c_dev, c5471_uiptxpoll, C5471_POLLHSEC);
+ }
+
+ /* 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 uip_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);
+
+ /* 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 uip_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 = irqsave();
+ 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;
+ irqrestore(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 uip_driver_s *dev)
+{
+ struct c5471_driver_s *c5471 = (struct c5471_driver_s *)dev->d_private;
+ irqstate_t flags;
+
+ ndbg("Polling\n");
+ flags = irqsave();
+
+ /* 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)uip_poll(&c5471->c_dev, c5471_uiptxpoll);
+ }
+ }
+
+ irqrestore(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 uip_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 uip_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 (CONFIG_C5471_ETHERNET_PHY == ETHERNET_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 uip_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);
+}
+
+#endif /* CONFIG_NET */
+
diff --git a/nuttx/arch/arm/src/c5471/c5471_irq.c b/nuttx/arch/arm/src/c5471/c5471_irq.c
new file mode 100644
index 000000000..49930f60f
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <nuttx/irq.h>
+
+#include "arm.h"
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define ILR_EDGESENSITIVE 0x00000020
+#define ILR_PRIORITY 0x0000001E
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/****************************************************************************
+ * 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
+ irqrestore(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_maskack_irq
+ *
+ * Description:
+ * Mask the IRQ and acknowledge it
+ *
+ ****************************************************************************/
+
+void up_maskack_irq(int irq)
+{
+ uint32_t reg = getreg32(INT_CTRL_REG);
+
+ /* Mask the interrupt */
+
+ reg = getreg32(MASK_IT_REG);
+ putreg32(reg | (1 << irq), MASK_IT_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/nuttx/arch/arm/src/c5471/c5471_lowputc.S b/nuttx/arch/arm/src/c5471/c5471_lowputc.S
new file mode 100644
index 000000000..b56483b87
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+/**************************************************************************
+ * Private Definitions
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Types
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Function Prototypes
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * 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/nuttx/arch/arm/src/c5471/c5471_serial.c b/nuttx/arch/arm/src/c5471/c5471_serial.c
new file mode 100644
index 000000000..ac86537ac
--- /dev/null
+++ b/nuttx/arch/arm/src/c5471/c5471_serial.c
@@ -0,0 +1,869 @@
+/****************************************************************************
+ * c5471/c5471_serial.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <arch/serial.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.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 Variables
+ ****************************************************************************/
+
+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,
+ .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(OSERR_INTERNAL);
+ }
+ 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)
+ {
+ 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;
+
+ case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
+ {
+ irqstate_t flags = irqsave();
+ up_enablebreaks(priv);
+ irqrestore(flags);
+ }
+ break;
+
+ case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
+ {
+ irqstate_t flags;
+ flags = irqsave();
+ up_disablebreaks(priv);
+ irqrestore(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/nuttx/arch/arm/src/c5471/c5471_timerisr.c b/nuttx/arch/arm/src/c5471/c5471_timerisr.c
new file mode 100644
index 000000000..1a221674d
--- /dev/null
+++ b/nuttx/arch/arm/src/c5471/c5471_timerisr.c
@@ -0,0 +1,128 @@
+/************************************************************
+ * c5471/c5471_timerisr.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "clock_internal.h"
+#include "up_internal.h"
+
+/************************************************************
+ * Pre-processor Definitions
+ ************************************************************/
+
+/* We want the general purpose timer running at the rate
+ * MSEC_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
+ ************************************************************/
+
+/************************************************************
+ * Global 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_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize
+ * the timer interrupt.
+ *
+ ************************************************************/
+
+void up_timerinit(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 MSEC_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/nuttx/arch/arm/src/c5471/c5471_vectors.S b/nuttx/arch/arm/src/c5471/c5471_vectors.S
new file mode 100644
index 000000000..aa514b03f
--- /dev/null
+++ b/nuttx/arch/arm/src/c5471/c5471_vectors.S
@@ -0,0 +1,485 @@
+/************************************************************************************
+ * arch/arm/src/c5471/c5471_vectors.S
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <nuttx/irq.h>
+
+#include "arm.h"
+#include "chip.h"
+#include "up_arch.h"
+
+/************************************************************************************
+ * Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Global 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 up_stackbase
+#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: up_interruptstack/g_userstack
+ *
+ * Description:
+ * Shouldn't happen
+ *
+ ************************************************************************************/
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ .bss
+ .align 4
+ .globl g_userstack
+ .type g_userstack, object
+up_interruptstack:
+ .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4)
+g_userstack:
+up_stackbase:
+ .skip 4
+ .size g_userstack, 4
+ .size up_interruptstack, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
+#endif
+ .end
diff --git a/nuttx/arch/arm/src/c5471/c5471_watchdog.c b/nuttx/arch/arm/src/c5471/c5471_watchdog.c
new file mode 100644
index 000000000..83563def7
--- /dev/null
+++ b/nuttx/arch/arm/src/c5471/c5471_watchdog.c
@@ -0,0 +1,397 @@
+/**************************************************************************
+ * c5471/c5471_watchdog.c
+ *
+ * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/fs/fs.h>
+#include <nuttx/irq.h>
+#include <arch/watchdog.h>
+
+#include "chip.h"
+#include "up_arch.h"
+
+/**************************************************************************
+ * 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 *filp, 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 *filp, 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/nuttx/arch/arm/src/c5471/chip.h b/nuttx/arch/arm/src/c5471/chip.h
new file mode 100644
index 000000000..d465ba834
--- /dev/null
+++ b/nuttx/arch/arm/src/c5471/chip.h
@@ -0,0 +1,371 @@
+/****************************************************************************
+ * c5471/chip.h
+ *
+ * Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/calypso/Kconfig b/nuttx/arch/arm/src/calypso/Kconfig
new file mode 100644
index 000000000..65726a609
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/Kconfig
@@ -0,0 +1,6 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+comment "Calypso Configuration Options"
diff --git a/nuttx/arch/arm/src/calypso/Make.defs b/nuttx/arch/arm/src/calypso/Make.defs
new file mode 100644
index 000000000..1552f17d1
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/Make.defs
@@ -0,0 +1,53 @@
+############################################################################
+# calypso/Make.defs
+#
+# Copyright (C) 2007 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Copyright (C) 2011 Stefan Richter. All rights reserved.
+# Author: Stefan Richter <ichgeh@l--putt.de>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# 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 \
+ up_nommuhead.S
+CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
+ up_createstack.c up_dataabort.c up_mdelay.c up_udelay.c up_doirq.c \
+ up_exit.c up_idle.c up_initialstate.c up_initialize.c \
+ up_interruptcontext.c up_prefetchabort.c up_releasepending.c \
+ up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c \
+ up_sigdeliver.c up_syscall.c up_unblocktask.c \
+ up_undefinedinsn.c up_usestack.c calypso_power.c
+
+CHIP_ASRCS = calypso_lowputc.S
+CHIP_CSRCS = calypso_irq.c calypso_timer.c calypso_heap.c \
+ calypso_serial.c calypso_spi.c clock.c calypso_uwire.c
diff --git a/nuttx/arch/arm/src/calypso/calypso_armio.c b/nuttx/arch/arm/src/calypso/calypso_armio.c
new file mode 100644
index 000000000..56f049f94
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_armio.c
@@ -0,0 +1,104 @@
+/****************************************************************************
+ * Driver for shared features of ARMIO modules
+ *
+ * Copyright (C) 2011 Stefan Richter. All rights reserved.
+ * Author: Stefan Richter <ichgeh@l--putt.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+
+#include <arch/calypso/memory.h>
+#include <arch/calypso/armio.h>
+
+#include "up_arch.h"
+
+/****************************************************************************
+ * 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)
+
+
+/****************************************************************************
+ * ARMIO interrupt handler
+ * forward keypad events
+ * forward GPIO events
+ ****************************************************************************/
+
+static int kbd_gpio_irq(int irq, uint32_t *regs)
+{
+ calypso_kbd_irq();
+
+ return 0;
+}
+
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/calypso/calypso_head.S b/nuttx/arch/arm/src/calypso/calypso_head.S
new file mode 100644
index 000000000..eb83b6851
--- /dev/null
+++ b/nuttx/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/nuttx/arch/arm/src/calypso/calypso_heap.c b/nuttx/arch/arm/src/calypso/calypso_heap.c
new file mode 100644
index 000000000..095fd1a5a
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_heap.c
@@ -0,0 +1,102 @@
+/****************************************************************************
+ * arch/arm/src/calypso/calypso_heap.c
+ * Initialize memory interfaces of Calypso MCU
+ *
+ * (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2011 Stefan Richter <ichgeh@l--putt.de>
+ *
+ * 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 <nuttx/config.h>
+#include <nuttx/mm.h>
+
+#include <sys/types.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include <arch/calypso/clock.h>
+#include <arch/calypso/timer.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Preprocessor 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);
+
+ mm_addregion((FAR void*)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE);
+
+}
+#endif
diff --git a/nuttx/arch/arm/src/calypso/calypso_irq.c b/nuttx/arch/arm/src/calypso/calypso_irq.c
new file mode 100644
index 000000000..fa818df40
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_irq.c
@@ -0,0 +1,313 @@
+/****************************************************************************
+ * arch/arm/src/calypso/calypso_irq.c
+ * Driver for Calypso IRQ controller
+ *
+ * (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2011 by Stefan Richter <ichgeh@l--putt.de>
+ *
+ * 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 <nuttx/config.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/calypso/memory.h>
+
+#include "arm.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) ((void *)BASE_ADDR_IRQ + (x))
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+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)
+{
+ uint16_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
+ irqrestore(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; // XXX: what's the return???
+}
+#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 *)&num;
+
+ /* 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/nuttx/arch/arm/src/calypso/calypso_lowputc.S b/nuttx/arch/arm/src/calypso/calypso_lowputc.S
new file mode 100644
index 000000000..16e5ef4c1
--- /dev/null
+++ b/nuttx/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 <ichgeh@l--putt.de>
+ *
+ * based on: c5471/c5471_lowputc.S
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+/**************************************************************************
+ * Private Definitions
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Types
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Function Prototypes
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * 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/nuttx/arch/arm/src/calypso/calypso_power.c b/nuttx/arch/arm/src/calypso/calypso_power.c
new file mode 100644
index 000000000..f85d6890e
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_power.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <nuttx/spi.h>
+
+int board_power_off(void)
+{
+ uint16_t tx;
+ struct spi_dev_s *spi = up_spiinitialize(0);
+
+ SPI_SETBITS(spi, 16);
+
+ tx = (1 << 6) | (1 << 1);
+ SPI_SNDBLOCK(spi, &tx, 1);
+
+ tx = (1 << 6) | (30 << 1);
+ SPI_SNDBLOCK(spi, &tx, 1);
+
+ return 0;
+}
diff --git a/nuttx/arch/arm/src/calypso/calypso_serial.c b/nuttx/arch/arm/src/calypso/calypso_serial.c
new file mode 100644
index 000000000..62e20409b
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_serial.c
@@ -0,0 +1,962 @@
+/****************************************************************************
+ * arch/arm/src/calypso/calypso_serial.c
+ *
+ * Copyright (C) 2011 Stefan Richter. All rights reserved.
+ * Author: Stefan Richter <ichgeh@l--putt.de>
+ *
+ * based on c5471/c5471_serial.c
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <arch/serial.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.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 Variables
+ ****************************************************************************/
+
+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,
+ .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;
+ }
+
+#if 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 <stdio.h>
+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(OSERR_INTERNAL);
+ }
+ 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)
+ {
+ 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;
+
+ case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
+ {
+ irqstate_t flags = irqsave();
+ up_enablebreaks(priv);
+ irqrestore(flags);
+ }
+ break;
+
+ case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
+ {
+ irqstate_t flags;
+ flags = irqsave();
+ up_disablebreaks(priv);
+ irqrestore(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/nuttx/arch/arm/src/calypso/calypso_spi.c b/nuttx/arch/arm/src/calypso/calypso_spi.c
new file mode 100644
index 000000000..d412fe791
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_spi.c
@@ -0,0 +1,232 @@
+/****************************************************************************
+ * arch/arm/src/calypso/calypso_spi.c
+ * SPI driver for TI Calypso
+ *
+ * Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>
+ * Copyright (C) 2011 Stefan Richter <ichgeh@l--putt.de>
+ *
+ * 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 <nuttx/config.h>
+#include <nuttx/spi.h>
+
+#include <debug.h>
+
+#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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ sem_t exclsem; /* Mutual exclusion of devices */
+#endif
+};
+
+/* STUBS! */
+#ifndef CONFIG_SPI_OWNBUS
+static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
+#endif
+
+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 =
+{
+#ifndef CONFIG_SPI_OWNBUS
+ .lock = spi_lock,
+#endif
+ .select = spi_select,
+ .setfrequency = spi_setfrequency,
+ .setmode = spi_setmode,
+ .setbits = spi_setbits,
+ .status = 0,
+#ifdef CONFIG_SPI_CMDDATA
+ .cmddata = ,
+#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,
+};
+
+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;
+}
+
+FAR struct spi_dev_s *up_spiinitialize(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/nuttx/arch/arm/src/calypso/calypso_spi.h b/nuttx/arch/arm/src/calypso/calypso_spi.h
new file mode 100644
index 000000000..cb44a6291
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_spi.h
@@ -0,0 +1,30 @@
+#ifndef ___ARCH_ARM_SRC_CALYPSO_CALYPSO_SPI_H
+#define ___ARCH_ARM_SRC_CALYPSO_CALYPSO_SPI_H
+
+#define BASE_ADDR_SPI 0xfffe3000
+#define SPI_REG(n) (BASE_ADDR_SPI+(n))
+
+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,
+};
+
+#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 */
+
+#endif /* ___ARCH_ARM_SRC_CALYPSO_CALYPSO_SPI_H */
diff --git a/nuttx/arch/arm/src/calypso/calypso_timer.c b/nuttx/arch/arm/src/calypso/calypso_timer.c
new file mode 100644
index 000000000..39eca0307
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_timer.c
@@ -0,0 +1,207 @@
+/****************************************************************************
+ * arch/arm/src/calypso/calypso_timer.c
+ * Calypso DBB internal Timer Driver
+ *
+ * (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2011 by Stefan Richter <ichgeh@l--putt.de>
+ *
+ * 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 <stdio.h>
+#include <stdint.h>
+#include <nuttx/arch.h>
+
+#include <arch/calypso/defines.h>
+#include <arch/calypso/memory.h>
+#include <arch/calypso/timer.h>
+
+#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 %u\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));
+}
+
+/************************************************************
+ * Global 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_timerinit
+ *
+ * Description:
+ * Setup Calypso HW timer 2 to cause system ticks.
+ *
+ * This function is called during start-up to initialize
+ * the timer interrupt.
+ *
+ ************************************************************/
+
+void up_timerinit(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/nuttx/arch/arm/src/calypso/calypso_uwire.c b/nuttx/arch/arm/src/calypso/calypso_uwire.c
new file mode 100644
index 000000000..234cd07e2
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_uwire.c
@@ -0,0 +1,152 @@
+/****************************************************************************
+ * arch/arm/src/calypso/calypso_uwire.c
+ * Driver for Calypso uWire Master Controller
+ *
+ * (C) 2010 by Sylvain Munaut <tnt@246tNt.com>
+ *
+ * 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 <stdint.h>
+#include <stdio.h>
+#include <debug.h>
+
+#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/nuttx/arch/arm/src/calypso/chip.h b/nuttx/arch/arm/src/calypso/chip.h
new file mode 100644
index 000000000..c607fc718
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/chip.h
@@ -0,0 +1,211 @@
+/****************************************************************************
+ * calypso/chip.h
+ *
+ * Copyright (C) 2011 Stefan Richter. All rights reserved.
+ * Author: Stefan Richter <ichgeh@l--putt.de>
+ *
+ * based on: c5471/chip.h
+ * Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/calypso/clock.c b/nuttx/arch/arm/src/calypso/clock.c
new file mode 100644
index 000000000..3c753cd86
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/clock.c
@@ -0,0 +1,220 @@
+/****************************************************************************
+ * arch/arm/src/calypso/clock.c
+ * Driver for Calypso clock management
+ *
+ * (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ *
+ * 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 <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdio.h>
+
+//#define DEBUG
+#include <arch/calypso/debug.h>
+
+#include <arch/calypso/memory.h>
+#include <arch/calypso/clock.h>
+
+#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/nuttx/arch/arm/src/common/up_allocateheap.c b/nuttx/arch/arm/src/common/up_allocateheap.c
new file mode 100644
index 000000000..d4b763196
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_allocateheap.c
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * arch/arm/src/common/up_allocateheap.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Private Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_allocate_heap
+ *
+ * Description:
+ * The heap may be statically allocated by
+ * defining CONFIG_HEAP_BASE and CONFIG_HEAP_SIZE. If these
+ * are not defined, then this function will be called to
+ * dynamically set aside the heap region.
+ *
+ ****************************************************************************/
+
+void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
+{
+ up_ledon(LED_HEAPALLOCATE);
+ *heap_start = (FAR void*)g_heapbase;
+ *heap_size = CONFIG_DRAM_END - g_heapbase;
+}
diff --git a/nuttx/arch/arm/src/common/up_arch.h b/nuttx/arch/arm/src/common/up_arch.h
new file mode 100644
index 000000000..af29bbf65
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_arch.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+ * arch/arm/src/common/up_arch.h
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#ifndef __ASSEMBLY__
+# include <stdint.h>
+#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 */
+
+EXTERN void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits);
+EXTERN void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits);
+EXTERN 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/nuttx/arch/arm/src/common/up_checkstack.c b/nuttx/arch/arm/src/common/up_checkstack.c
new file mode 100644
index 000000000..ac8d9e7b9
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_checkstack.c
@@ -0,0 +1,147 @@
+/****************************************************************************
+ * arch/arm/src/common/up_checkstack.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_check_stack
+ *
+ * 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 _TCB *tcb)
+{
+ FAR uint32_t *ptr;
+ size_t mark;
+
+ /* 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 *)tcb->stack_alloc_ptr, mark = tcb->adj_stack_size/4;
+ *ptr == 0xDEADBEEF && 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 > tcb->adj_stack_size/4)
+ {
+ int i, j;
+
+ ptr = (FAR uint32_t *)tcb->stack_alloc_ptr;
+ for (i = 0; i < tcb->adj_stack_size; i += 4*64)
+ {
+ for (j = 0; j < 64; j++)
+ {
+ int ch;
+ if (*ptr++ == 0xDEADBEEF)
+ {
+ ch = '.';
+ }
+ else
+ {
+ ch = 'X';
+ }
+ up_putc(ch);
+ }
+ up_putc('\n');
+ }
+ }
+#endif
+
+ /* Return our guess about how much stack space was used */
+
+ return mark*4;
+}
+
+size_t up_check_stack(void)
+{
+ return up_check_tcbstack((FAR _TCB*)g_readytorun.head);
+}
+
+size_t up_check_stack_remain(void)
+{
+ return ((FAR _TCB*)g_readytorun.head)->adj_stack_size - up_check_tcbstack((FAR _TCB*)g_readytorun.head);
+}
+
+#endif /* CONFIG_DEBUG && CONFIG_DEBUG_STACK */
diff --git a/nuttx/arch/arm/src/common/up_createstack.c b/nuttx/arch/arm/src/common/up_createstack.c
new file mode 100644
index 000000000..3d6dfef45
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_createstack.c
@@ -0,0 +1,197 @@
+/****************************************************************************
+ * arch/arm/src/common/up_createstack.c
+ *
+ * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: memset32
+ *
+ * On most larger then 8 bit archs this will need to be word aligned so
+ * so maybe some checks should be put in place?
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK)
+static void *memset32(void *s, uint32_t c, size_t n)
+{
+ uint32_t *p = (uint32_t *)s;
+ while (n-- > 0) *p++ = c;
+ return s;
+}
+#endif
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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:
+ * 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.
+ ****************************************************************************/
+
+int up_create_stack(_TCB *tcb, size_t stack_size)
+{
+ if (tcb->stack_alloc_ptr &&
+ tcb->adj_stack_size != stack_size)
+ {
+ sched_free(tcb->stack_alloc_ptr);
+ tcb->stack_alloc_ptr = NULL;
+ }
+
+ if (!tcb->stack_alloc_ptr)
+ {
+#ifdef CONFIG_DEBUG
+ tcb->stack_alloc_ptr = (uint32_t*)kzalloc(stack_size);
+#else
+ tcb->stack_alloc_ptr = (uint32_t*)kmalloc(stack_size);
+#endif
+ }
+
+ if (tcb->stack_alloc_ptr)
+ {
+ 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 _TCB */
+
+ tcb->adj_stack_ptr = (uint32_t*)top_of_stack;
+ tcb->adj_stack_size = size_of_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.
+ */
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK)
+ memset32(tcb->stack_alloc_ptr, 0xDEADBEEF, tcb->adj_stack_size/4);
+#endif
+
+ up_ledon(LED_STACKCREATED);
+ return OK;
+ }
+
+ return ERROR;
+}
+
diff --git a/nuttx/arch/arm/src/common/up_etherstub.c b/nuttx/arch/arm/src/common/up_etherstub.c
new file mode 100644
index 000000000..407e7b45b
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_etherstub.c
@@ -0,0 +1,86 @@
+/****************************************************************************
+ * arch/arm/src/common/up_etherstub.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * 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/up_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 cornercase 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 cornercase would occur if, for example,
+ * only a USB network interface is being used or perhaps if a SLIP is
+ * being used).
+ *
+ * In the long run, it might be better to have some kind of CONFIG_NO_ETHERNET
+ * to suppress the call to up_netinitialize() in up_initialize(). Then
+ * this stub would not be needed.
+ *
+ ****************************************************************************/
+
+void up_netinitialize(void)
+{
+}
diff --git a/nuttx/arch/arm/src/common/up_exit.c b/nuttx/arch/arm/src/common/up_exit.c
new file mode 100644
index 000000000..6f6d54f76
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_exit.c
@@ -0,0 +1,174 @@
+/****************************************************************************
+ * common/up_exit.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sched.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "up_internal.h"
+
+#ifdef CONFIG_DUMP_ON_EXIT
+#include <nuttx/fs/fs.h>
+#endif
+
+/****************************************************************************
+ * 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 _TCB *tcb, FAR void *arg)
+{
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NFILE_STREAMS > 0
+ 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
+ if (tcb->filelist)
+ {
+ sdbg(" filelist refcount=%d\n",
+ tcb->filelist->fl_crefs);
+
+ for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
+ {
+ struct inode *inode = tcb->filelist->fl_files[i].f_inode;
+ if (inode)
+ {
+ sdbg(" fd=%d refcount=%d\n",
+ i, inode->i_crefs);
+ }
+ }
+ }
+#endif
+
+#if CONFIG_NFILE_STREAMS > 0
+ if (tcb->streams)
+ {
+ sdbg(" streamlist refcount=%d\n",
+ tcb->streams->sl_crefs);
+
+ for (i = 0; i < CONFIG_NFILE_STREAMS; i++)
+ {
+ struct file_struct *filep = &tcb->streams->sl_streams[i];
+ if (filep->fs_filedes >= 0)
+ {
+#if CONFIG_STDIO_BUFFER_SIZE > 0
+ sdbg(" fd=%d nbytes=%d\n",
+ filep->fs_filedes,
+ filep->fs_bufpos - filep->fs_bufstart);
+#else
+ sdbg(" fd=%d\n", filep->fs_filedes);
+#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)
+{
+ _TCB* tcb;
+
+ /* Disable interrupts. They will be restored when the next
+ * task is started.
+ */
+
+ (void)irqsave();
+
+ slldbg("TCB=%p exitting\n", g_readytorun.head);
+
+#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_deletecurrent();
+
+ /* Now, perform the context switch to the new ready-to-run task at the
+ * head of the list.
+ */
+
+ tcb = (_TCB*)g_readytorun.head;
+
+ /* Then switch contexts */
+
+ up_fullcontextrestore(tcb->xcp.regs);
+}
+
diff --git a/nuttx/arch/arm/src/common/up_idle.c b/nuttx/arch/arm/src/common/up_idle.c
new file mode 100644
index 000000000..187af76e7
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_idle.c
@@ -0,0 +1,91 @@
+/****************************************************************************
+ * arch/arm/src/common/up_idle.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <nuttx/arch.h>
+#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 */
+
+#if 0
+ asm("WFI"); /* For example */
+#endif
+#endif
+}
+
diff --git a/nuttx/arch/arm/src/common/up_initialize.c b/nuttx/arch/arm/src/common/up_initialize.c
new file mode 100644
index 000000000..094835c29
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_initialize.c
@@ -0,0 +1,191 @@
+/****************************************************************************
+ * arch/arm/src/common/up_initialize.c
+ *
+ * Copyright (C) 2007-2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/ramlog.h>
+
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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 */
+
+ 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 power management subsystem. This MCU-specific function
+ * must be called *very* early in the intialization 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 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_timerinit();
+#endif
+
+ /* Register devices */
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+ devnull_register(); /* Standard /dev/null */
+#endif
+
+ /* Initialize the console device driver */
+
+#if defined(USE_SERIALDRIVER)
+ up_serialinit();
+#elif defined(CONFIG_DEV_LOWCONSOLE)
+ lowconsole_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
+
+ /* Initialize the network */
+
+ up_netinitialize();
+
+ /* Initialize USB -- device and/or host */
+
+ up_usbinitialize();
+ up_ledon(LED_IRQSENABLED);
+}
diff --git a/nuttx/arch/arm/src/common/up_internal.h b/nuttx/arch/arm/src/common/up_internal.h
new file mode 100644
index 000000000..45cb1dcc0
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_internal.h
@@ -0,0 +1,393 @@
+/****************************************************************************
+ * common/up_internal.h
+ *
+ * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+# include <sys/types.h>
+# include <stdint.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 */
+
+/* Determine which (if any) console driver to use */
+
+#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
+
+/* 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-M3 model, the state is copied from the stack to the TCB, but only
+ * a referenced is passed to get the state from the TCB.
+ */
+
+#if defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4)
+# if defined(CONFIG_ARCH_FPU) && !defined(CONFIG_ARMV7M_CMNVECTOR)
+# define up_savestate(regs) \
+ do { \
+ up_copystate(regs, (uint32_t*)current_regs); \
+ up_savefpu(regs); \
+ } \
+ while (0)
+# else
+# define up_savestate(regs) up_copystate(regs, (uint32_t*)current_regs)
+# endif
+# define up_restorestate(regs) (current_regs = regs)
+#else
+# define up_savestate(regs) up_copystate(regs, (uint32_t*)current_regs)
+# define up_restorestate(regs) up_copystate((uint32_t*)current_regs, regs)
+#endif
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+typedef void (*up_vector_t)(void);
+#endif
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+#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 *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_DRAM_END
+ */
+
+extern const uint32_t g_heapbase;
+
+/* Address of the saved user stack pointer */
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+#if defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4)
+extern uint32_t g_intstackbase;
+# else
+extern uint32_t g_userstack;
+# endif
+#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_BOOT_RAMFUNCS
+
+# define __ramfunc__ __attribute__ ((section(".ramfunc")))
+
+/* Functions decleared 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 start address in RAM */
+
+#endif /* CONFIG_BOOT_RAMFUNCS */
+#endif /* __ASSEMBLY__ */
+
+/****************************************************************************
+ * Inline Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/* Low level initialization provided by board-level logic ******************/
+
+extern void up_boot(void);
+
+/* Context switching */
+
+extern void up_copystate(uint32_t *dest, uint32_t *src);
+extern void up_decodeirq(uint32_t *regs);
+extern int up_saveusercontext(uint32_t *saveregs);
+extern void up_fullcontextrestore(uint32_t *restoreregs) __attribute__ ((noreturn));
+extern void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs);
+
+/* Signal handling **********************************************************/
+
+extern void up_sigdeliver(void);
+
+/* Power management *********************************************************/
+
+#ifdef CONFIG_PM
+extern void up_pminitialize(void);
+#else
+# define up_pminitialize()
+#endif
+
+/* Interrupt handling *******************************************************/
+
+extern void up_irqinitialize(void);
+extern void up_maskack_irq(int irq);
+
+#if defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4)
+
+extern uint32_t *up_doirq(int irq, uint32_t *regs);
+extern int up_svcall(int irq, FAR void *context);
+extern int up_hardfault(int irq, FAR void *context);
+extern int up_memfault(int irq, FAR void *context);
+
+#else /* CONFIG_ARCH_CORTEXM3 || CONFIG_ARCH_CORTEXM4 */
+
+extern void up_doirq(int irq, uint32_t *regs);
+#ifdef CONFIG_PAGING
+extern void up_pginitialize(void);
+extern uint32_t *up_va2pte(uintptr_t vaddr);
+extern void up_dataabort(uint32_t *regs, uint32_t far, uint32_t fsr);
+#else /* CONFIG_PAGING */
+# define up_pginitialize()
+extern void up_dataabort(uint32_t *regs);
+#endif /* CONFIG_PAGING */
+extern void up_prefetchabort(uint32_t *regs);
+extern void up_syscall(uint32_t *regs);
+extern void up_undefinedinsn(uint32_t *regs);
+
+#endif /* CONFIG_ARCH_CORTEXM3 || CONFIG_ARCH_CORTEXM4 */
+
+extern void up_vectorundefinsn(void);
+extern void up_vectorswi(void);
+extern void up_vectorprefetch(void);
+extern void up_vectordata(void);
+extern void up_vectoraddrexcptn(void);
+extern void up_vectorirq(void);
+extern void up_vectorfiq(void);
+
+/* Floating point unit ******************************************************/
+
+#ifdef CONFIG_ARCH_FPU
+extern void up_savefpu(uint32_t *regs);
+extern void up_restorefpu(const uint32_t *regs);
+#else
+# define up_savefpu(regs)
+# define up_restorefpu(regs)
+#endif
+
+/* System timer *************************************************************/
+
+extern void up_timerinit(void);
+extern int up_timerisr(int irq, uint32_t *regs);
+
+/* Low level serial output **************************************************/
+
+extern void up_lowputc(char ch);
+extern void up_puts(const char *str);
+extern void up_lowputs(const char *str);
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+extern void up_earlyserialinit(void);
+extern void up_serialinit(void);
+#else
+# define up_earlyserialinit()
+# define up_serialinit()
+#endif
+
+/* Defined in drivers/lowconsole.c */
+
+#ifdef CONFIG_DEV_LOWCONSOLE
+extern void lowconsole_init(void);
+#else
+# define lowconsole_init()
+#endif
+
+/* DMA **********************************************************************/
+
+#ifdef CONFIG_ARCH_DMA
+extern void weak_function up_dmainitialize(void);
+#endif
+
+/* Memory management ********************************************************/
+
+#if CONFIG_MM_REGIONS > 1
+void up_addregion(void);
+#else
+# define up_addregion()
+#endif
+
+/* Watchdog timer ***********************************************************/
+
+extern void up_wdtinit(void);
+
+/* LED interfaces provided by board-level logic *****************************/
+
+#ifdef CONFIG_ARCH_LEDS
+extern void up_ledinit(void);
+extern void up_ledon(int led);
+extern void up_ledoff(int led);
+#else
+# define up_ledinit()
+# define up_ledon(led)
+# define up_ledoff(led)
+#endif
+
+/* Networking ***************************************************************/
+
+/* Defined in board/up_network.c for board-specific ethernet implementations,
+ * or chip/xyx_ethernet.c for chip-specific ethernet implementations, or
+ * common/up_etherstub.c for a cornercase where the network is enabled yet
+ * there is no ethernet driver to be initialized.
+ */
+
+#ifdef CONFIG_NET
+extern void up_netinitialize(void);
+#else
+# define up_netinitialize()
+#endif
+
+/* USB **********************************************************************/
+
+#ifdef CONFIG_USBDEV
+extern void up_usbinitialize(void);
+extern void up_usbuninitialize(void);
+#else
+# define up_usbinitialize()
+# define up_usbuninitialize()
+#endif
+
+/****************************************************************************
+ * Name: up_check_stack
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK)
+extern size_t up_check_stack(void);
+extern size_t up_check_tcbstack(FAR _TCB);
+extern size_t up_check_tcbstack_remain(FAR _TCB);
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ARCH_ARM_SRC_COMMON_UP_INTERNAL_H */
diff --git a/nuttx/arch/arm/src/common/up_interruptcontext.c b/nuttx/arch/arm/src/common/up_interruptcontext.c
new file mode 100644
index 000000000..0039692bc
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_interruptcontext.c
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * arch/arm/src/common/up_interruptcontext.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdbool.h>
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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/nuttx/arch/arm/src/common/up_lowputs.c b/nuttx/arch/arm/src/common/up_lowputs.c
new file mode 100644
index 000000000..890167e0e
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_lowputs.c
@@ -0,0 +1,74 @@
+/****************************************************************************
+ * arch/arm/src/common/up_lowputs.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#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/nuttx/arch/arm/src/common/up_mdelay.c b/nuttx/arch/arm/src/common/up_mdelay.c
new file mode 100644
index 000000000..2c0447620
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_mdelay.c
@@ -0,0 +1,90 @@
+/****************************************************************************
+ * arch/arm/src/common/up_mdelay.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <nuttx/arch.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/common/up_modifyreg16.c b/nuttx/arch/arm/src/common/up_modifyreg16.c
new file mode 100644
index 000000000..32ebd6f96
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_modifyreg16.c
@@ -0,0 +1,85 @@
+/****************************************************************************
+ * arch/arm/src/common/up_modifyreg16.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+#include <nuttx/arch.h>
+
+#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 = irqsave();
+ regval = getreg16(addr);
+ regval &= ~clearbits;
+ regval |= setbits;
+ putreg16(regval, addr);
+ irqrestore(flags);
+}
diff --git a/nuttx/arch/arm/src/common/up_modifyreg32.c b/nuttx/arch/arm/src/common/up_modifyreg32.c
new file mode 100644
index 000000000..a87873284
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_modifyreg32.c
@@ -0,0 +1,85 @@
+/****************************************************************************
+ * arch/arm/src/common/up_modifyreg32.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+#include <nuttx/arch.h>
+
+#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 = irqsave();
+ regval = getreg32(addr);
+ regval &= ~clearbits;
+ regval |= setbits;
+ putreg32(regval, addr);
+ irqrestore(flags);
+}
diff --git a/nuttx/arch/arm/src/common/up_modifyreg8.c b/nuttx/arch/arm/src/common/up_modifyreg8.c
new file mode 100644
index 000000000..92ed48eff
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_modifyreg8.c
@@ -0,0 +1,85 @@
+/****************************************************************************
+ * arch/arm/src/common/up_modifyreg8.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+#include <nuttx/arch.h>
+
+#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 = irqsave();
+ regval = getreg8(addr);
+ regval &= ~clearbits;
+ regval |= setbits;
+ putreg8(regval, addr);
+ irqrestore(flags);
+}
diff --git a/nuttx/arch/arm/src/common/up_puts.c b/nuttx/arch/arm/src/common/up_puts.c
new file mode 100644
index 000000000..f56dbf07e
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_puts.c
@@ -0,0 +1,75 @@
+/****************************************************************************
+ * arch/arm/src/common/up_puts.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <nuttx/arch.h>
+
+#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/nuttx/arch/arm/src/common/up_releasestack.c b/nuttx/arch/arm/src/common/up_releasestack.c
new file mode 100644
index 000000000..82f5db88f
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_releasestack.c
@@ -0,0 +1,79 @@
+/****************************************************************************
+ * arch/arm/src/common/up_releasestack.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sched.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_release_stack
+ *
+ * Description:
+ * A task has been stopped. Free all stack
+ * related resources retained int the defunct TCB.
+ *
+ ****************************************************************************/
+
+void up_release_stack(_TCB *dtcb)
+{
+ if (dtcb->stack_alloc_ptr)
+ {
+ sched_free(dtcb->stack_alloc_ptr);
+ dtcb->stack_alloc_ptr = NULL;
+ }
+
+ dtcb->adj_stack_size = 0;
+}
diff --git a/nuttx/arch/arm/src/common/up_udelay.c b/nuttx/arch/arm/src/common/up_udelay.c
new file mode 100644
index 000000000..8fcb93522
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_udelay.c
@@ -0,0 +1,129 @@
+/****************************************************************************
+ * arch/arm/src/common/up_udelay.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <sys/types.h>
+#include <nuttx/arch.h>
+
+/****************************************************************************
+ * 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 Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/common/up_usestack.c b/nuttx/arch/arm/src/common/up_usestack.c
new file mode 100644
index 000000000..a3f4f4816
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_usestack.c
@@ -0,0 +1,155 @@
+/****************************************************************************
+ * arch/arm/src/common/up_usestack.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/arch.h>
+
+#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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_use_stack
+ *
+ * Description:
+ * Setup up stack-related information in the TCB
+ * using pre-allocated stack memory
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+int up_use_stack(_TCB *tcb, void *stack, size_t stack_size)
+{
+ size_t top_of_stack;
+ size_t size_of_stack;
+
+ if (tcb->stack_alloc_ptr)
+ {
+ sched_free(tcb->stack_alloc_ptr);
+ }
+
+ /* Save the 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 _TCB */
+
+ tcb->adj_stack_ptr = (uint32_t*)top_of_stack;
+ tcb->adj_stack_size = size_of_stack;
+
+ return OK;
+}
diff --git a/nuttx/arch/arm/src/dm320/Kconfig b/nuttx/arch/arm/src/dm320/Kconfig
new file mode 100644
index 000000000..0255c5ff1
--- /dev/null
+++ b/nuttx/arch/arm/src/dm320/Kconfig
@@ -0,0 +1,6 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+comment "DM320 Configuration Options"
diff --git a/nuttx/arch/arm/src/dm320/Make.defs b/nuttx/arch/arm/src/dm320/Make.defs
new file mode 100644
index 000000000..957196672
--- /dev/null
+++ b/nuttx/arch/arm/src/dm320/Make.defs
@@ -0,0 +1,54 @@
+############################################################################
+# dm320/Make.defs
+#
+# Copyright (C) 2007, 2010 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# 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 \
+ up_vectors.S up_vectoraddrexcptn.S up_vectortab.S
+CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.c up_createstack.c \
+ up_dataabort.c up_mdelay.c up_udelay.c up_exit.c up_idle.c \
+ up_initialize.c up_initialstate.c up_interruptcontext.c \
+ up_prefetchabort.c up_releasepending.c up_releasestack.c \
+ up_reprioritizertr.c up_schedulesigaction.c \
+ up_sigdeliver.c up_syscall.c up_unblocktask.c \
+ up_undefinedinsn.c up_usestack.c
+
+CHIP_ASRCS = dm320_lowputc.S dm320_restart.S
+CHIP_CSRCS = dm320_allocateheap.c dm320_boot.c dm320_decodeirq.c \
+ dm320_irq.c dm320_serial.c dm320_timerisr.c dm320_framebuffer.c
+
+ifeq ($(CONFIG_USBDEV),y)
+CHIP_CSRCS += dm320_usbdev.c
+endif
diff --git a/nuttx/arch/arm/src/dm320/chip.h b/nuttx/arch/arm/src/dm320/chip.h
new file mode 100644
index 000000000..7ac681e11
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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"
+
+/************************************************************************************
+ * Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Inline Functions
+ ************************************************************************************/
+
+#endif /* __DM320_CHIP_H */
diff --git a/nuttx/arch/arm/src/dm320/dm320_ahb.h b/nuttx/arch/arm/src/dm320/dm320_ahb.h
new file mode 100644
index 000000000..6a3654666
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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/nuttx/arch/arm/src/dm320/dm320_allocateheap.c b/nuttx/arch/arm/src/dm320/dm320_allocateheap.c
new file mode 100644
index 000000000..5d4b90093
--- /dev/null
+++ b/nuttx/arch/arm/src/dm320/dm320_allocateheap.c
@@ -0,0 +1,83 @@
+/************************************************************
+ * dm320/dm320_allocateheap.c
+ *
+ * Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * 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 <nuttx/config.h>
+#include <sys/types.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+/************************************************************
+ * Private Definitions
+ ************************************************************/
+
+/************************************************************
+ * Private Data
+ ************************************************************/
+
+/************************************************************
+ * Private Functions
+ ************************************************************/
+
+/************************************************************
+ * Public Functions
+ ************************************************************/
+
+/************************************************************
+ * Name: up_allocate_heap
+ *
+ * Description:
+ * The heap may be statically allocated by
+ * defining CONFIG_HEAP_BASE and CONFIG_HEAP_SIZE. If these
+ * are not defined, then this function will be called to
+ * dynamically set aside the heap region.
+ *
+ ************************************************************/
+
+void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
+{
+ up_ledon(LED_HEAPALLOCATE);
+ *heap_start = (FAR void*)g_heapbase;
+ *heap_size = (DM320_SDRAM_VADDR + CONFIG_DRAM_SIZE) - g_heapbase;
+}
diff --git a/nuttx/arch/arm/src/dm320/dm320_boot.c b/nuttx/arch/arm/src/dm320/dm320_boot.c
new file mode 100644
index 000000000..df749b6da
--- /dev/null
+++ b/nuttx/arch/arm/src/dm320/dm320_boot.c
@@ -0,0 +1,237 @@
+/************************************************************************************
+ * arch/arm/src/dm320/dm320_boot.c
+ *
+ * Copyright (C) 2007, 2009-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <stdint.h>
+
+#include "chip.h"
+#include "arm.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+/************************************************************************************
+ * 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 Variables
+ ************************************************************************************/
+
+extern uint32_t _vector_start; /* Beginning of vector block */
+extern uint32_t _vector_end; /* End+1 of vector block */
+
+/************************************************************************************
+ * Private Variables
+ ************************************************************************************/
+
+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
+ up_ledinit();
+#endif
+ /* Perform early serial initialization */
+
+#ifdef USE_EARLYSERIALINIT
+ up_earlyserialinit();
+#endif
+}
diff --git a/nuttx/arch/arm/src/dm320/dm320_busc.h b/nuttx/arch/arm/src/dm320/dm320_busc.h
new file mode 100644
index 000000000..8c3590946
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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/nuttx/arch/arm/src/dm320/dm320_clkc.h b/nuttx/arch/arm/src/dm320/dm320_clkc.h
new file mode 100644
index 000000000..7019b11dc
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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/nuttx/arch/arm/src/dm320/dm320_decodeirq.c b/nuttx/arch/arm/src/dm320/dm320_decodeirq.c
new file mode 100644
index 000000000..c7032c4b1
--- /dev/null
+++ b/nuttx/arch/arm/src/dm320/dm320_decodeirq.c
@@ -0,0 +1,129 @@
+/********************************************************************************
+ * arch/arm/src/dm320/dm320_decodeirq.c
+ * arch/arm/src/chip/dm320_decodeirq.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <assert.h>
+#include <debug.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+/********************************************************************************
+ * Pre-processor Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Funtions
+ ********************************************************************************/
+
+void up_decodeirq(uint32_t* regs)
+{
+#ifdef CONFIG_SUPPRESS_INTERRUPTS
+ lib_lowprintf("Unexpected IRQ\n");
+ current_regs = regs;
+ PANIC(OSERR_ERREXCEPTION);
+#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)
+ {
+ uint32_t *savestate;
+
+ /* Mask and acknowledge the interrupt */
+
+ up_maskack_irq(irq);
+
+ /* 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;
+
+ /* Unmask the last interrupt (global interrupts are still
+ * disabled).
+ */
+
+ up_enable_irq(irq);
+ }
+ }
+#endif
+}
diff --git a/nuttx/arch/arm/src/dm320/dm320_emif.h b/nuttx/arch/arm/src/dm320/dm320_emif.h
new file mode 100644
index 000000000..653e20fe0
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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/nuttx/arch/arm/src/dm320/dm320_framebuffer.c b/nuttx/arch/arm/src/dm320/dm320_framebuffer.c
new file mode 100644
index 000000000..1b1197d53
--- /dev/null
+++ b/nuttx/arch/arm/src/dm320/dm320_framebuffer.c
@@ -0,0 +1,1438 @@
+/****************************************************************************
+ * arch/arm/src/dm320/dm320_framebuffer.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/fb.h>
+#include <nuttx/nx/nxglib.h>
+
+#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 *)malloc(2 * DM320_VID0_FBLEN);
+ g_vid0ppbase = (FAR char*)g_vid0base + DM320_VID0_FBLEN;
+#else
+ g_vid0base = (FAR void *)malloc(DM320_VID0_FBLEN);
+#endif
+ if (!g_vid0base)
+ {
+ goto errout;
+ }
+#endif
+
+#ifndef CONFIG_DM320_VID1_DISABLE
+ g_vid1base = (FAR void *)malloc(DM320_VID1_FBLEN);
+ if (!g_vid1base)
+ {
+ goto errout;
+ }
+#endif
+
+#ifndef CONFIG_DM320_OSD0_DISABLE
+ g_osd0base = (FAR void *)malloc(DM320_OSD0_FBLEN);
+ if (!g_osd0base)
+ {
+ goto errout;
+ }
+#endif
+
+#ifndef CONFIG_DM320_OSD1_DISABLE
+ g_osd1base = (FAR void *)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)
+ {
+ 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)
+ {
+ free(g_vid1base);
+ g_vid1base = NULL;
+ }
+#endif
+
+#ifndef CONFIG_DM320_OSD0_DISABLE
+ if (g_osd0base != 0)
+ {
+ free(g_osd0base);
+ g_osd0base = NULL;
+ }
+#endif
+
+#ifndef CONFIG_DM320_OSD1_DISABLE
+ if (g_osd1base != 0)
+ {
+ 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 = irqsave();
+ 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
+
+ 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 = irqsave();
+ 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
+ irqrestore();
+
+ 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 = irqsave();
+ 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;
+ }
+
+ flags = irqsave();
+ putreg16(settings->size.w, DM320_OSD_CURXL);
+ putreg16(settings->size.h, DM320_OSD_CURYL);
+ restore_flags(flags);
+ }
+#endif
+
+ regval = getreg16(DM320_OSD_RECTCUR);
+ if ((settings->flags & FB_CUR_ENABLE) != 0)
+ {
+ regval |= 1;
+ }
+ else
+ {
+ regval &= ~1;
+ }
+ putreg16(regval, DM320_OSD_RECTCUR);
+ restore_flags(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/nuttx/arch/arm/src/dm320/dm320_gio.h b/nuttx/arch/arm/src/dm320/dm320_gio.h
new file mode 100644
index 000000000..4ad277047
--- /dev/null
+++ b/nuttx/arch/arm/src/dm320/dm320_gio.h
@@ -0,0 +1,175 @@
+/************************************************************************************
+ * dm320/dm320_gio.h
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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 <stdint.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/nuttx/arch/arm/src/dm320/dm320_intc.h b/nuttx/arch/arm/src/dm320/dm320_intc.h
new file mode 100644
index 000000000..f05febb2f
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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/nuttx/arch/arm/src/dm320/dm320_irq.c b/nuttx/arch/arm/src/dm320/dm320_irq.c
new file mode 100644
index 000000000..2fb41475d
--- /dev/null
+++ b/nuttx/arch/arm/src/dm320/dm320_irq.c
@@ -0,0 +1,249 @@
+/************************************************************************
+ * arch/arm/src/dm320/dm320_irq.c
+ *
+ * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <nuttx/irq.h>
+
+#include "arm.h"
+#include "chip.h"
+
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+/************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Data
+ ************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/************************************************************************
+ * 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
+ irqrestore(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_maskack_irq
+ *
+ * Description:
+ * Mask the IRQ and acknowledge it
+ *
+ ************************************************************************/
+
+void up_maskack_irq(int irq)
+{
+ /* Disable the interrupt by clearing the corresponding bit in
+ * the IRQ enable register. And acknowlege it by setting the
+ * corresponding bit in the IRQ status register.
+ */
+
+ if (irq < 16)
+ {
+ /* IRQs0-15 are controlled by the IRQ0 enable register
+ * Clear the associated enable bit to disable the interrupt
+ * Set the associated status bit to clear the interrupt
+ */
+
+ putreg16((getreg16(DM320_INTC_EINT0) & ~(1<< irq)), DM320_INTC_EINT0);
+ putreg16((1 << irq), DM320_INTC_IRQ0);
+ }
+ else if (irq < 32)
+ {
+ /* IRQs16-31 are controlled by the IRQ1 enable register
+ * Clear the associated enable bit to disable the interrupt
+ * Set the associated status bit to clear the interrupt
+ */
+
+ putreg16((getreg16(DM320_INTC_EINT1) & ~(1<< (irq-16))), DM320_INTC_EINT1);
+ putreg16((1 << (irq-16)), DM320_INTC_IRQ1);
+ }
+ else
+ {
+ /* IRQs32- are controlled by the IRQ2 enable register
+ * Clear the associated enable bit to disable the interrupt
+ * Set the associated status bit to clear the interrupt
+ */
+
+ putreg16((getreg16(DM320_INTC_EINT2) & ~(1<< (irq-32))), DM320_INTC_EINT2);
+ putreg16((1 << (irq-32)), DM320_INTC_IRQ2);
+ }
+}
diff --git a/nuttx/arch/arm/src/dm320/dm320_lowputc.S b/nuttx/arch/arm/src/dm320/dm320_lowputc.S
new file mode 100644
index 000000000..e60fa9527
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include "chip.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+/**************************************************************************
+ * Private Definitions
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Types
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Function Prototypes
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * 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/nuttx/arch/arm/src/dm320/dm320_memorymap.h b/nuttx/arch/arm/src/dm320/dm320_memorymap.h
new file mode 100644
index 000000000..a8aafbb71
--- /dev/null
+++ b/nuttx/arch/arm/src/dm320/dm320_memorymap.h
@@ -0,0 +1,263 @@
+/************************************************************************************
+ * dm320/dm320_memorymap.h
+ *
+ * Copyright (C) 2007, 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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 <nuttx/config.h>
+
+#include <arch/board/board.h>
+#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/<board>/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_DRAM_VSTART != 0x00000000
+# error "Invalid setting for CONFIG_DRAM_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)
+
+/* 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/nuttx/arch/arm/src/dm320/dm320_osd.h b/nuttx/arch/arm/src/dm320/dm320_osd.h
new file mode 100644
index 000000000..199651e69
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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/nuttx/arch/arm/src/dm320/dm320_restart.S b/nuttx/arch/arm/src/dm320/dm320_restart.S
new file mode 100644
index 000000000..7e25d8ff2
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * 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 <nuttx/config.h>
+
+#include "arm.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+/********************************************************************
+ * 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_DRAM_VSTART - CONFIG_DRAM_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/nuttx/arch/arm/src/dm320/dm320_serial.c b/nuttx/arch/arm/src/dm320/dm320_serial.c
new file mode 100644
index 000000000..15e4ecdf9
--- /dev/null
+++ b/nuttx/arch/arm/src/dm320/dm320_serial.c
@@ -0,0 +1,839 @@
+/****************************************************************************
+ * arch/arm/src/dm320/dm320_serial.c
+ * arch/arm/src/chip/dm320_serial.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <arch/serial.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.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 Variables
+ ****************************************************************************/
+
+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,
+ .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(OSERR_INTERNAL);
+ }
+ 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)
+ {
+ 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;
+
+ case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
+ {
+ irqstate_t flags = irqsave();
+ up_enablebreaks(priv, true);
+ irqrestore(flags);
+ }
+ break;
+
+ case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
+ {
+ irqstate_t flags;
+ flags = irqsave();
+ up_enablebreaks(priv, false);
+ irqrestore(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 */
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/dm320/dm320_timer.h b/nuttx/arch/arm/src/dm320/dm320_timer.h
new file mode 100644
index 000000000..2ef407906
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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/nuttx/arch/arm/src/dm320/dm320_timerisr.c b/nuttx/arch/arm/src/dm320/dm320_timerisr.c
new file mode 100644
index 000000000..59efa53d3
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "clock_internal.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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize the timer
+ * interrupt.
+ *
+ ****************************************************************************/
+
+void up_timerinit(void)
+{
+ up_disable_irq(DM320_IRQ_SYSTIMER);
+
+ /* Start timer0 running so that an interrupt is generated at
+ * the rate MSEC_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/nuttx/arch/arm/src/dm320/dm320_uart.h b/nuttx/arch/arm/src/dm320/dm320_uart.h
new file mode 100644
index 000000000..d66848941
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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 <stdint.h>
+#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/nuttx/arch/arm/src/dm320/dm320_usb.h b/nuttx/arch/arm/src/dm320/dm320_usb.h
new file mode 100644
index 000000000..6db7aef3d
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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/nuttx/arch/arm/src/dm320/dm320_usbdev.c b/nuttx/arch/arm/src/dm320/dm320_usbdev.c
new file mode 100644
index 000000000..c924db197
--- /dev/null
+++ b/nuttx/arch/arm/src/dm320/dm320_usbdev.c
@@ -0,0 +1,2579 @@
+/*******************************************************************************
+ * arch/arm/src/dm320/dm320_usbdev.c
+ *
+ * Copyright (C) 2008-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/usb/usb.h>
+#include <nuttx/usb/usbdev.h>
+#include <nuttx/usb/usbdev_trace.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#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 = irqsave();
+ privreq = dm320_rqdequeue(privep);
+ irqrestore(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(addrhi, 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_maskack_irq(DM320_IRQ_USB0); /* Clear USB controller interrupt */
+ up_maskack_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);
+ 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 = irqsave();
+ dm320_cancelrequests(privep);
+ dm320_epreset(privep->epphy);
+
+ irqrestore(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 *)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);
+ 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 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
+ 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 = irqsave();
+
+ /* 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;
+ }
+ }
+
+ irqrestore(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 = irqsave();
+ dm320_cancelrequests(privep);
+ irqrestore(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);
+
+ /* 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 = irqsave();
+ ret = dm320_getreg8(DM320_USB_FRAME2) << 8;
+ ret |= dm320_getreg8(DM320_USB_FRAME1);
+ irqrestore(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 = irqsave();
+ dm320_putreg8(USB_POWER_RESUME, DM320_USB_POWER);
+ irqrestore(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 = irqsave();
+ if (enable)
+ {
+ GIO_SET_OUTPUT(CONFIG_DM320_GIO_USBDPPULLUP); /* Set D+ pullup */
+ }
+ else
+ {
+ GIO_CLEAR_OUTPUT(CONFIG_DM320_GIO_USBDPPULLUP); /* Clear D+ pullup */
+ }
+
+ irqrestore(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/nuttx/arch/arm/src/imx/Kconfig b/nuttx/arch/arm/src/imx/Kconfig
new file mode 100644
index 000000000..879f50ef7
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/Kconfig
@@ -0,0 +1,6 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+comment "i.MX Configuration Options"
diff --git a/nuttx/arch/arm/src/imx/Make.defs b/nuttx/arch/arm/src/imx/Make.defs
new file mode 100644
index 000000000..3b2e6ad77
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/Make.defs
@@ -0,0 +1,54 @@
+############################################################################
+# arch/arm/src/imx/Make.defs
+#
+# Copyright (C) 2009 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (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 \
+ up_vectors.S up_vectoraddrexcptn.S up_vectortab.S
+CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.c up_createstack.c \
+ up_dataabort.c up_mdelay.c up_udelay.c up_exit.c up_idle.c \
+ up_initialize.c up_initialstate.c up_interruptcontext.c \
+ up_prefetchabort.c up_releasepending.c up_releasestack.c \
+ up_reprioritizertr.c up_schedulesigaction.c \
+ up_sigdeliver.c up_syscall.c up_unblocktask.c \
+ up_undefinedinsn.c up_usestack.c
+
+CHIP_ASRCS = imx_lowputc.S
+CHIP_CSRCS = imx_boot.c imx_gpio.c imx_allocateheap.c imx_irq.c \
+ imx_serial.c imx_timerisr.c imx_decodeirq.c imx_spi.c
+
+ifeq ($(CONFIG_USBDEV),y)
+CHIP_CSRCS += imx_usbdev.c
+endif
diff --git a/nuttx/arch/arm/src/imx/chip.h b/nuttx/arch/arm/src/imx/chip.h
new file mode 100644
index 000000000..94985efb6
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/chip.h
@@ -0,0 +1,65 @@
+/************************************************************************************
+ * arch/arm/src/imx/chip.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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"
+
+/************************************************************************************
+ * Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Inline Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_IMX_CHIP_H */
diff --git a/nuttx/arch/arm/src/imx/imx_aitc.h b/nuttx/arch/arm/src/imx/imx_aitc.h
new file mode 100644
index 000000000..5b83c5f46
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_aitc.h
@@ -0,0 +1,119 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_aitc.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/imx/imx_allocateheap.c b/nuttx/arch/arm/src/imx/imx_allocateheap.c
new file mode 100644
index 000000000..4831c8c8b
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_allocateheap.c
@@ -0,0 +1,118 @@
+/****************************************************************************
+ * arch/arm/src/imx/imx_allocateheap.c
+ * arch/arm/src/chip/imx_allocateheap.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/mm.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#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:
+ * The heap may be statically allocated by defining CONFIG_HEAP_BASE and
+ * CONFIG_HEAP_SIZE. If these are not defined, then this function will be
+ * called to dynamically set aside the heap region.
+ *
+ ****************************************************************************/
+
+void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
+{
+ up_ledon(LED_HEAPALLOCATE);
+ *heap_start = (FAR void*)g_heapbase;
+ *heap_size = (IMX_SDRAM_VSECTION + CONFIG_DRAM_SIZE) - g_heapbase;
+}
+
+/****************************************************************************
+ * 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_DRAM_NUTTXENTRY & 0xffff0000) != CONFIG_DRAM_VSTART
+ uint32_t start = CONFIG_DRAM_VSTART + 0x1000;
+ uint32_t end = (CONFIG_DRAM_NUTTXENTRY & 0xffff0000);
+ mm_addregion((FAR void*)start, end - start);
+# endif
+#endif
+
+ /* Check for any additional memory regions */
+
+#if defined(CONFIG_HEAP2_BASE) && defined(CONFIG_HEAP2_SIZE)
+ mm_addregion((FAR void*)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE);
+#endif
+}
+#endif
diff --git a/nuttx/arch/arm/src/imx/imx_boot.c b/nuttx/arch/arm/src/imx/imx_boot.c
new file mode 100644
index 000000000..53c656b2d
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_boot.c
@@ -0,0 +1,225 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_boot.c
+ * arch/arm/src/chip/imx_boot.c
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <stdint.h>
+
+#include "chip.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+/************************************************************************************
+ * 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 Variables
+ ************************************************************************************/
+
+extern uint32_t _vector_start; /* Beginning of vector block */
+extern uint32_t _vector_end; /* End+1 of vector block */
+
+/************************************************************************************
+ * Private Variables
+ ************************************************************************************/
+
+/* 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.
+ */
+
+extern void imx_boardinitialize(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_boardinitialize();
+
+ /* Set up the board-specific LEDs */
+
+#ifdef CONFIG_ARCH_LEDS
+ up_ledinit();
+#endif
+ /* Perform early serial initialization */
+
+#ifdef USE_EARLYSERIALINIT
+ up_earlyserialinit();
+#endif
+}
diff --git a/nuttx/arch/arm/src/imx/imx_cspi.h b/nuttx/arch/arm/src/imx/imx_cspi.h
new file mode 100644
index 000000000..1a60730d5
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_cspi.h
@@ -0,0 +1,210 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_cspi.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <stdint.h>
+# include <stdbool.h>
+# include <nuttx/spi.h>
+#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
+ ************************************************************************************/
+
+/* 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.h). All other methods (including up_spiinitialize()) 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 up_spiinitialize() in your low level initialization logic
+ * 4. The handle returned by up_spiinitialize() 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).
+ */
+
+EXTERN void imx_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t imx_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+#ifdef CONFIG_SPI_CMDDATA
+EXTERN 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/nuttx/arch/arm/src/imx/imx_decodeirq.c b/nuttx/arch/arm/src/imx/imx_decodeirq.c
new file mode 100644
index 000000000..ba37a60a2
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_decodeirq.c
@@ -0,0 +1,136 @@
+/********************************************************************************
+ * arch/arm/src/imx/imx_decodeirq.c
+ * arch/arm/src/chip/imx_decodeirq.c
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <assert.h>
+#include <debug.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+/********************************************************************************
+ * Pre-processor Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Funtions
+ ********************************************************************************/
+
+void up_decodeirq(uint32_t* regs)
+{
+#ifdef CONFIG_SUPPRESS_INTERRUPTS
+ lib_lowprintf("Unexpected IRQ\n");
+ current_regs = regs;
+ PANIC(OSERR_ERREXCEPTION);
+#else
+ uint32_t* savestate;
+ 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.
+ */
+
+ savestate = (uint32_t*)current_regs;
+ 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)
+ {
+ /* Mask and acknowledge the interrupt */
+
+ up_maskack_irq(irq);
+
+ /* Deliver the IRQ */
+
+ irq_dispatch(irq, regs);
+
+ /* Unmask the last interrupt (global interrupts are still
+ * disabled).
+ */
+
+ up_enable_irq(irq);
+ }
+ }
+ while (irq < NR_IRQS);
+
+ /* 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
+}
diff --git a/nuttx/arch/arm/src/imx/imx_dma.h b/nuttx/arch/arm/src/imx/imx_dma.h
new file mode 100644
index 000000000..2d5d553ce
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_dma.h
@@ -0,0 +1,250 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_dma.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/imx/imx_eim.h b/nuttx/arch/arm/src/imx/imx_eim.h
new file mode 100644
index 000000000..decd54e46
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_eim.h
@@ -0,0 +1,85 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_eim.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/imx/imx_gpio.c b/nuttx/arch/arm/src/imx/imx_gpio.c
new file mode 100644
index 000000000..94e87fdfe
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_gpio.c
@@ -0,0 +1,122 @@
+/****************************************************************************
+ * arch/arm/src/imx/imx_gpio.c
+ * arch/arm/src/chip/imx_gpio.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "imx_gpio.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/imx/imx_gpio.h b/nuttx/arch/arm/src/imx/imx_gpio.h
new file mode 100644
index 000000000..dcdf9c68e
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_gpio.h
@@ -0,0 +1,562 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_gpio.h
+ * arch/arm/src/chip/imx_gpio.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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_GPIO_H
+#define __ARCH_ARM_IMX_GPIO_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#ifndef __ASSEMBLY__
+# include <stdint.h>
+#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_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 */
+
+extern void imxgpio_configoutput(int port, int bit, int value);
+extern void imxgpio_configinput(int port, int bit);
+
+extern void imxgpio_configpfoutput(int port, int bit);
+extern void imxgpio_configpfinput(int port, int bit);
+
+#endif
+
+#endif /* __ARCH_ARM_IMX_GPIOHELPERS_H */
diff --git a/nuttx/arch/arm/src/imx/imx_i2c.h b/nuttx/arch/arm/src/imx/imx_i2c.h
new file mode 100644
index 000000000..8b1c065e2
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_i2c.h
@@ -0,0 +1,69 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_i2c.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/imx/imx_irq.c b/nuttx/arch/arm/src/imx/imx_irq.c
new file mode 100644
index 000000000..6715a4ad7
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_irq.c
@@ -0,0 +1,145 @@
+/****************************************************************************
+ * arch/arm/src/imc/imx_irq.c
+ * arch/arm/src/chip/imx_irq.c
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <nuttx/irq.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/****************************************************************************
+ * 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 */
+
+ irqrestore(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);
+}
+
+/****************************************************************************
+ * Name: up_maskack_irq
+ *
+ * Description:
+ * Mask the IRQ and acknowledge it
+ *
+ ****************************************************************************/
+
+void up_maskack_irq(int irq)
+{
+ up_disable_irq(irq);
+}
diff --git a/nuttx/arch/arm/src/imx/imx_lowputc.S b/nuttx/arch/arm/src/imx/imx_lowputc.S
new file mode 100644
index 000000000..b0c8163a3
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_lowputc.S
@@ -0,0 +1,130 @@
+/**************************************************************************
+ * arch/arm/src/imx/imx_lowputc.S
+ * arch/arm/src/chip/imx_lowputc.S
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include "chip.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+/**************************************************************************
+ * Private Definitions
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Types
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Function Prototypes
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * 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/nuttx/arch/arm/src/imx/imx_memorymap.h b/nuttx/arch/arm/src/imx/imx_memorymap.h
new file mode 100644
index 000000000..fd23aafc3
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_memorymap.h
@@ -0,0 +1,258 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_memorymap.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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"
+
+/************************************************************************************
+ * 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_DRAM_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_DRAM_SIZE) */
+#else
+ /* Map SDRAM to address zero */
+
+# define IMX_SDRAM_VSECTION 0x00000000 /* -(+CONFIG_DRAM_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_DRAM_NUTTXENTRY & 0xfff00000) | PGTABLE_SIZE)
+
+#if NUTTX_START_VADDR != CONFIG_DRAM_NUTTXENTRY
+# error "CONFIG_DRAM_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/nuttx/arch/arm/src/imx/imx_rtc.h b/nuttx/arch/arm/src/imx/imx_rtc.h
new file mode 100644
index 000000000..249e7a40d
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_rtc.h
@@ -0,0 +1,85 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_rtc.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/imx/imx_serial.c b/nuttx/arch/arm/src/imx/imx_serial.c
new file mode 100644
index 000000000..26e6592be
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_serial.c
@@ -0,0 +1,1244 @@
+/****************************************************************************
+ * arch/arm/src/imx/imx_serial.c
+ * arch/arm/src/chip/imx_serial.c
+ *
+ * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <arch/serial.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "imx_gpio.h"
+#include "os_internal.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_UART3_DISABLE)
+# define CONFIG_UART3_DISABLE 1
+#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 Variables
+ ****************************************************************************/
+
+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,
+ .send = up_send,
+ .txint = up_txint,
+ .txready = up_txready,
+ .txempty = up_txempty,
+};
+
+/* I/O buffers */
+
+#ifndef CONFIG_UART1_DISABLE
+static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE];
+static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE];
+#endif
+
+#ifndef CONFIG_UART2_DISABLE
+static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE];
+static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE];
+#endif
+
+#ifndef CONFIG_UART3_DISABLE
+static char g_uart3rxbuffer[CONFIG_UART2_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART2_TXBUFSIZE];
+#endif
+
+/* This describes the state of the IMX uart1 port. */
+
+#ifndef CONFIG_UART1_DISABLE
+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 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 IMX uart2 port. */
+
+#ifndef CONFIG_UART2_DISABLE
+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 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
+
+#ifndef CONFIG_UART3_DISABLE
+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 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
+
+/* Now, which one with be tty0/console and which tty1 and tty2? */
+
+#if defined(CONFIG_UART1_SERIAL_CONSOLE) && !defined(CONFIG_UART1_DISABLE)
+# 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_UART2_DISABLE)
+# define TTYS1_DEV g_uart2port /* UART2 is /dev/ttyS1 */
+# if !defined(CONFIG_UART3_DISABLE)
+# define TTYS2_DEV g_uart3port /* UART3 is /dev/ttyS2 */
+# else
+# undef TTYS2_DEV /* No /dev/ttyS2 */
+# endif
+# elif !defined(CONFIG_UART3_DISABLE)
+# 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_UART2_DISABLE)
+# 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_UART1_DISABLE)
+# define TTYS1_DEV g_uart1port /* UART1 is /dev/ttyS1 */
+# if !defined(CONFIG_UART3_DISABLE)
+# define TTYS2_DEV g_uart3port /* UART3 is /dev/ttyS2 */
+# else
+# undef TTYS2_DEV /* No /dev/ttyS2 */
+# endif
+# elif !defined(CONFIG_UART3_DISABLE)
+# 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_UART3_DISABLE)
+# 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_UART1_DISABLE)
+# define TTYS1_DEV g_uart1port /* UART1 is /dev/ttyS1 */
+# if !defined(CONFIG_UART2_DISABLE)
+# define TTYS2_DEV g_uart2port /* UART2 is /dev/ttyS2 */
+# else
+# undef TTYS2_DEV /* No /dev/ttyS2 */
+# endif
+# elif !defined(CONFIG_UART2_DISABLE)
+# 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_UART1_DISABLE)
+# define TTYS0_DEV g_uart1port /* UART1 is /dev/ttyS0 */
+# if !defined(CONFIG_UART2_DISABLE)
+# define TTYS1_DEV g_uart2port /* UART2 is /dev/ttyS1 */
+# if !defined(CONFIG_UART3_DISABLE)
+# define TTYS2_DEV g_uart3port /* UART3 is /dev/ttyS2 */
+# else
+# undef TTYS2_DEV /* No /dev/ttyS2 */
+# endif
+# elif !defined(CONFIG_UART3_DISABLE)
+# 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_DISABLE)
+# define TTYS0_DEV g_uart2port /* UART2 is /dev/ttyS0 */
+# undef TTYS2_DEV /* No /dev/ttyS2 */
+# if !defined(CONFIG_UART3_DISABLE)
+# define TTYS1_DEV g_uart2port /* UART2 is /dev/ttyS1 */
+# else
+# undef TTYS1_DEV /* No /dev/ttyS1 */
+# endif
+
+# elif !defined(CONFIG_UART3_DISABLE)
+# 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;
+ uint32_t regval;
+ uint32_t ucr2;
+ uint32_t div;
+ uint32_t num;
+ uint32_t den;
+
+ /* 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;
+ }
+ }
+
+ /* Select RTS */
+
+#if 0
+ ucr2 &= ~UCR2_IRTS;
+ ucr2 |= UCR2_CTSC;
+#endif
+
+ /* Setup hardware flow control */
+
+ regval = 0;
+#if 0
+ if (priv->hwfc)
+ {
+ 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);
+
+ /* Set the baud.
+ *
+ * baud * 16 / REFFREQ = NUM/DEN
+ * UBIR = NUM-1;
+ * UMBR = DEN-1
+ * REFFREQ = PERCLK1 / DIV
+ * DIV = RFDIV[2:0]
+ *
+ * First, select a closest value we can for the divider
+ */
+
+ div = (IMX_PERCLK1_FREQ >> 4) / priv->baud;
+ if (div > 7)
+ {
+ div = 7;
+ }
+ else if (div < 1)
+ {
+ div = 1;
+ }
+
+ /* Now find the numerator and denominator. These must have
+ * the ratio baud/(PERCLK / div / 16), but the values cannot
+ * exceed 16 bits
+ */
+
+ num = priv->baud;
+ den = (IMX_PERCLK1_FREQ << 4) / div;
+
+ if (num > den)
+ {
+ if (num > 0x00010000)
+ {
+ /* b16 is a scale such that b16*num = 0x10000 * 2**16 */
+
+ uint32_t b16 = 0x100000000LL / num;
+ num = 0x00010000;
+ den = (b16 * den) >> 16;
+ }
+ }
+ else
+ {
+ if (den > 0x0000ffff)
+ {
+ /* b16 is a scale such that b16*den = 0x10000 * 2**16 */
+
+ uint32_t b16 = 0x100000000LL / den;
+ num = (b16 * num) >> 16;
+ den = 0x00010000;
+ }
+ }
+
+ /* The actual values are we write to the registers need to be
+ * decremented by 1.
+ */
+
+ if (num > 0)
+ {
+ num--;
+ }
+
+ if (den > 0)
+ {
+ den--;
+ }
+
+ /* The UBIR must be set before the UBMR register */
+
+ up_serialout(priv, UART_UBIR, num);
+ up_serialout(priv, UART_UBMR, den);
+
+ /* 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)
+ {
+#ifndef CONFIG_UART1_DISABLE
+#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
+
+#ifndef CONFIG_UART2_DISABLE
+#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
+
+#ifndef CONFIG_UART3_DISABLE
+#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(OSERR_INTERNAL);
+ 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)
+{
+ struct inode *inode = filep->f_inode;
+ struct uart_dev_s *dev = inode->i_private;
+ int ret = OK;
+
+ switch (cmd)
+ {
+ 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;
+
+ 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 */
+
+#ifndef CONFIG_UART1_DISABLE
+ 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 */
+
+#ifndef CONFIG_UART2_DISABLE
+ 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 */
+
+#ifndef CONFIG_UART3_DISABLE
+ 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 */
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/imx/imx_spi.c b/nuttx/arch/arm/src/imx/imx_spi.c
new file mode 100644
index 000000000..5ee601263
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_spi.c
@@ -0,0 +1,1157 @@
+/****************************************************************************
+ * arch/arm/src/imx/imx_spi.c
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/spi.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#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? */
+
+#ifndef CONFIG_SPI1_DISABLE
+# define SPI1_NDX 0 /* Index to SPI1 in g_spidev[] */
+# ifndef CONFIG_SPI2_DISABLE
+# 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
+# ifndef CONFIG_SPI2_DISABLE
+# 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 sem; /* 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 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
+#endif
+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 =
+{
+#ifndef CONFIG_SPI_OWNBUS
+ .lock = spi_lock,
+#endif
+ .select = imx_spiselect, /* Provided externally by board logic */
+ .setfrequency = spi_setfrequency,
+ .setmode = spi_setmode,
+ .setbits = spi_setbits,
+ .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[] =
+{
+#ifndef CONFIG_SPI1_DISABLE
+ {
+ .ops = &g_spiops,
+ .base = IMX_CSPI1_VBASE,
+#ifndef CONFIG_SPI_POLLWAIT
+ .irq = IMX_IRQ_CSPI1,
+#endif
+ },
+#endif
+#ifndef CONFIG_SPI2_DISABLE
+ {
+ .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;
+#endif
+ uint32_t regval;
+ int ntxd;
+ int ret;
+
+ /* 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 = irqsave();
+ 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);
+ irqrestore(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->sem);
+ }
+ 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)
+ {
+#ifndef CONFIG_SPI1_DISABLE
+ case IMX_IRQ_CSPI1:
+ return &g_spidev[SPI1_NDX];
+#endif
+#ifndef CONFIG_SPI2_DISABLE
+ 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->sem);
+ }
+ 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
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_OWNBUS
+static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
+{
+ /* Not implemented */
+
+ return -ENOSYS;
+}
+#endif
+
+/****************************************************************************
+ * 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 = priv->actual;
+
+ if (priv && 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: up_spiinitialize
+ *
+ * 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 *up_spiinitialize(int port)
+{
+ struct imx_spidev_s *priv;
+ uint8_t regval;
+
+ /* Only the SPI1 interface is supported */
+
+ switch (port)
+ {
+#ifndef CONFIG_SPI1_DISABLE
+ 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_SPI1_DISABLE */
+
+#ifndef CONFIG_SPI2_DISABLE
+ 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_SPI2_DISABLE */
+
+ default:
+ return NULL;
+ }
+
+ /* Initialize the state structure */
+
+#ifndef CONFIG_SPI_POLLWAIT
+ sem_init(&priv->sem, 0, 0);
+#endif
+
+ /* 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/nuttx/arch/arm/src/imx/imx_system.h b/nuttx/arch/arm/src/imx/imx_system.h
new file mode 100644
index 000000000..ad363f14a
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_system.h
@@ -0,0 +1,187 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_system.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/imx/imx_timer.h b/nuttx/arch/arm/src/imx/imx_timer.h
new file mode 100644
index 000000000..9d91d3c0d
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_timer.h
@@ -0,0 +1,104 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_timer.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/imx/imx_timerisr.c b/nuttx/arch/arm/src/imx/imx_timerisr.c
new file mode 100644
index 000000000..896dc86e5
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_timerisr.c
@@ -0,0 +1,164 @@
+/****************************************************************************
+ * arch/arm/src/imx/imx_timerisr.c
+ * arch/arm/src/chip/imx_timerisr.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+#include <errno.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "clock_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize the timer
+ * interrupt.
+ *
+ ****************************************************************************/
+
+void up_timerinit(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 MSEC_PER_TICK. The value IMX_PERCLK1_FREQ/1000
+ * (defined in board.h) is the number of counts in millisecond, so:
+ */
+
+ putreg32((IMX_PERCLK1_FREQ / 1000) * MSEC_PER_TICK, 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/nuttx/arch/arm/src/imx/imx_uart.h b/nuttx/arch/arm/src/imx/imx_uart.h
new file mode 100644
index 000000000..5646e83f7
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_uart.h
@@ -0,0 +1,227 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_uart.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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_UART_H
+#define __ARCH_ARM_IMX_UART_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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_IMX_UART_H */
diff --git a/nuttx/arch/arm/src/imx/imx_usbd.h b/nuttx/arch/arm/src/imx/imx_usbd.h
new file mode 100644
index 000000000..8c810cacf
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_usbd.h
@@ -0,0 +1,320 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_usbd.h
+ *
+ * Copyright (c) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/imx/imx_wdog.h b/nuttx/arch/arm/src/imx/imx_wdog.h
new file mode 100644
index 000000000..4ee6438b3
--- /dev/null
+++ b/nuttx/arch/arm/src/imx/imx_wdog.h
@@ -0,0 +1,81 @@
+/************************************************************************************
+ * arch/arm/src/imx/imx_wdog.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/kinetis/Kconfig b/nuttx/arch/arm/src/kinetis/Kconfig
new file mode 100644
index 000000000..210683f59
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/Kconfig
@@ -0,0 +1,6 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+comment "Kinetis Configuration Options"
diff --git a/nuttx/arch/arm/src/kinetis/Make.defs b/nuttx/arch/arm/src/kinetis/Make.defs
new file mode 100644
index 000000000..22d066828
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/Make.defs
@@ -0,0 +1,94 @@
+############################################################################
+# arch/arm/src/kinetis/Make.defs
+#
+# Copyright (C) 2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (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_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
+ up_createstack.c up_mdelay.c up_udelay.c up_exit.c up_initialize.c \
+ up_memfault.c up_initialstate.c up_interruptcontext.c \
+ up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c \
+ up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c \
+ up_releasepending.c up_sigdeliver.c up_unblocktask.c up_usestack.c \
+ up_doirq.c up_hardfault.c up_svcall.c up_checkstack.c
+
+ifeq ($(CONFIG_NET),y)
+ifneq ($(CONFIG_KINETIS_ENET),y)
+CMN_CSRCS += up_etherstub.c
+endif
+endif
+
+# Required Kinetis files
+
+CHIP_ASRCS =
+CHIP_CSRCS = kinetis_clockconfig.c kinetis_clrpend.c kinetis_idle.c \
+ kinetis_irq.c kinetis_lowputc.c kinetis_pin.c kinetis_pingpio.c \
+ kinetis_serial.c kinetis_start.c kinetis_timerisr.c kinetis_wdog.c
+
+# Configuration-dependent Kinetis files
+
+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/nuttx/arch/arm/src/kinetis/chip.h b/nuttx/arch/arm/src/kinetis/chip.h
new file mode 100644
index 000000000..6ad781c20
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/chip.h
@@ -0,0 +1,853 @@
+/************************************************************************************
+ * arch/arm/src/kinetis/chip.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Get customizations for each supported chip */
+
+#if defined(CONFIG_ARCH_CHIP_MK40X64VFX50) || defined(CONFIG_ARCH_CHIP_MK40X64VLH50) || \
+ defined(CONFIG_ARCH_CHIP_MK40X64VLK50) || defined(CONFIG_ARCH_CHIP_MK40X64VMB50)
+# 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)
+# 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)
+# 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)
+# 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)
+# 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)
+# 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_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_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_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)*/
+# 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_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_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_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_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_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_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_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_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_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
+
+/* Include only the memory map. Other chip hardware files should then include this
+ * file for the proper setup
+ */
+
+#include "kinetis_memorymap.h"
+
+/* 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 */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_H */
diff --git a/nuttx/arch/arm/src/kinetis/kinetis_adc.h b/nuttx/arch/arm/src/kinetis/kinetis_adc.h
new file mode 100644
index 000000000..a17aa06c7
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_aips.h b/nuttx/arch/arm/src/kinetis/kinetis_aips.h
new file mode 100644
index 000000000..8f460567f
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_axbs.h b/nuttx/arch/arm/src/kinetis/kinetis_axbs.h
new file mode 100644
index 000000000..bf8543d4d
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_clockconfig.c b/nuttx/arch/arm/src/kinetis/kinetis_clockconfig.c
new file mode 100644
index 000000000..31ea235d2
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+
+#include "kinetis_internal.h"
+#include "kinetis_mcg.h"
+#include "kinetis_sim.h"
+#include "kinetis_fmc.h"
+#include "kinetis_llwu.h"
+#include "kinetis_pinmux.h"
+
+/****************************************************************************
+ * Private Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_BOOT_RAMFUNCS
+# error "CONFIG_BOOT_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/nuttx/arch/arm/src/kinetis/kinetis_clrpend.c b/nuttx/arch/arm/src/kinetis/kinetis_clrpend.c
new file mode 100644
index 000000000..2837d867f
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <arch/irq.h>
+
+#include "nvic.h"
+#include "up_arch.h"
+#include "kinetis_internal.h"
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/kinetis/kinetis_cmp.h b/nuttx/arch/arm/src/kinetis/kinetis_cmp.h
new file mode 100644
index 000000000..822b7a339
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_cmt.h b/nuttx/arch/arm/src/kinetis/kinetis_cmt.h
new file mode 100644
index 000000000..c3c47bb67
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_config.h b/nuttx/arch/arm/src/kinetis/kinetis_config.h
new file mode 100644
index 000000000..4faa90ce7
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Configuration *********************************************************************/
+/* Make that no unsupport 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/nuttx/arch/arm/src/kinetis/kinetis_crc.h b/nuttx/arch/arm/src/kinetis/kinetis_crc.h
new file mode 100644
index 000000000..7b590cf3a
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_dac.h b/nuttx/arch/arm/src/kinetis/kinetis_dac.h
new file mode 100644
index 000000000..5c3b5c0c0
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_dma.h b/nuttx/arch/arm/src/kinetis/kinetis_dma.h
new file mode 100644
index 000000000..9876a46a0
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_dmamux.h b/nuttx/arch/arm/src/kinetis/kinetis_dmamux.h
new file mode 100644
index 000000000..b83579180
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_dspi.h b/nuttx/arch/arm/src/kinetis/kinetis_dspi.h
new file mode 100644
index 000000000..e682ef23e
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_enet.c b/nuttx/arch/arm/src/kinetis/kinetis_enet.c
new file mode 100644
index 000000000..3e0a36779
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_enet.c
@@ -0,0 +1,1565 @@
+/****************************************************************************
+ * drivers/net/kinetis_enet.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_KINETIS_ENET)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <time.h>
+#include <string.h>
+#include <debug.h>
+#include <wdog.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/net/mii.h>
+
+#include <nuttx/net/uip/uip.h>
+#include <nuttx/net/uip/uip-arp.h>
+#include <nuttx/net/uip/uip-arch.h>
+
+#include "up_arch.h"
+#include "chip.h"
+#include "kinetis_internal.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
+
+/****************************************************************************
+ * 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
+# errror "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)
+#define KINETIS_POLLHSEC (1*2)
+
+/* 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 uip_eth_hdr *)priv->dev.d_buf)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+/* EMAC statistics (debug only) */
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
+struct kinetis_statistics_s
+{
+ uint32_t rx_packets; /* Number of packets received */
+ uint32_t tx_packets; /* Number of Tx packets queued */
+ unit32_t tx_done; /* Number of packets completed */
+ uint32_t tx_timeouts; /* Number of Tx timeout errors */
+ uint32_t errors; /* Number of error interrupts */
+};
+# define EMAC_STAT(priv,name) priv->stats.name++
+#else
+# define EMAC_STAT(priv,name)
+#endif
+
+/* 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 uip_driver_s dev; /* Interface understood by uIP */
+
+ /* Statistics */
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
+ struct kinetis_statistics_s stats;
+#endif
+
+ /* The DMA descriptors. A unaligned uint8_t is used to allocate the
+ * memory; 16 is added to assure that we can meet the desciptor 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 desciptor alignment
+ * requirements.
+ */
+
+ uint8_t buffers[NENET_NBUFFERS * CONFIG_NET_BUFSIZE + 16];
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct kinetis_driver_s g_enet[CONFIG_ENET_NETHIFS];
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+/* Utility functions */
+
+#ifdef CONFIG_ENDIAN_BIG
+# define kinesis_swap32(value) (value)
+# define kinesis_swap16(value) (value)
+#else
+static inline uint32_t kinesis_swap32(uint32_t value);
+static inline uint16_t kinesis_swap16(uint16_t value);
+#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_uiptxpoll(struct uip_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 uip_driver_s *dev);
+static int kinetis_ifdown(struct uip_driver_s *dev);
+static int kinetis_txavail(struct uip_driver_s *dev);
+#ifdef CONFIG_NET_IGMP
+static int kinetis_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
+static int kinetis_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
+#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
+ *
+ ****************************************************************************/
+
+#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
+
+/****************************************************************************
+ * 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;
+
+ /* 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 */
+
+ EMAC_STAT(priv, tx_packets);
+
+ /* 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 | TXDESC_W);
+
+ /* 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_uiptxpoll
+ *
+ * Description:
+ * The transmitter is available, check if uIP has any outgoing packets ready
+ * to send. This is a callback from uip_poll(). uip_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_uiptxpoll(struct uip_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)
+ {
+ uip_arp_out(&priv->dev);
+ kinetis_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 (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 */
+
+ EMAC_STAT(priv, rx_packets);
+
+ /* 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);
+
+ /* Doing this here could cause corruption! */
+
+ priv->rxdesc[priv->rxtail].status1 |= RXDESC_E;
+
+ /* Update the index to the next descriptor */
+
+ priv->rxtail++;
+ if (priv->rxtail >= CONFIG_ENET_NTXBUFFERS)
+ {
+ priv->rxtail = 0;
+ }
+
+ /* Indicate that there have been empty receive buffers produced */
+
+ putreg32(ENET_RDAR, KINETIS_ENET_RDAR);
+
+ /* We only accept IP packets of the configured type and ARP packets */
+
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(UIP_ETHTYPE_IP6))
+#else
+ if (BUF->type == HTONS(UIP_ETHTYPE_IP))
+#endif
+ {
+ uip_arp_ipin(&priv->dev);
+ uip_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)
+ {
+ uip_arp_out(&priv->dev);
+ kinetis_transmit(priv);
+ }
+ }
+ else if (BUF->type == htons(UIP_ETHTYPE_ARP))
+ {
+ uip_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);
+ }
+ }
+ }
+}
+
+/****************************************************************************
+ * 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)
+{
+ struct enet_desc_s *txdesc;
+ uint32_t regval;
+
+ /* Verify that the oldest descriptor descriptor completed */
+
+ txdesc = &priv->txdesc[priv->txtail];
+ if ((txdesc->status1 & TXDESC_R) == 0)
+ {
+ /* 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 */
+
+ EMAC_STAT(priv, tx_done);
+ }
+
+ /* 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)uip_poll(&priv->dev, kinetis_uiptxpoll);
+}
+
+/****************************************************************************
+ * 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 */
+
+ EMAC_STAT(priv, errors);
+
+ /* 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 */
+
+ EMAC_STAT(priv, tx_timeout);
+
+ /* Take the interface down and bring it back up. The is the most agressive
+ * hardware reset.
+ */
+
+ (void)kinetis_ifup(&priv->dev);
+ (void)kinetis_ifdown(&priv->dev);
+
+ /* Then poll uIP for new XMIT data */
+
+ (void)uip_poll(&priv->dev, kinetis_uiptxpoll);
+}
+
+/****************************************************************************
+ * 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)uip_timer(&priv->dev, kinetis_uiptxpoll, KINETIS_POLLHSEC);
+ }
+
+ /* 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 uip_driver_s *dev)
+{
+ FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)dev->d_private;
+ 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);
+
+ /* 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(CONFIG_NET_BUFSIZE, 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);
+
+ /* Indicate that there have been empty receive buffers produced */
+
+ putreg32(ENET_RDAR, KINETIS_ENET_RDAR);
+
+ /* And enable the MAC itself */
+
+ regval = getreg32(KINETIS_ENET_ECR);
+ regval |= ENET_ECR_ETHEREN;
+ putreg32(regval, KINETIS_ENET_ECR);
+
+ /* 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 uip_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 = irqsave();
+ 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;
+ irqrestore(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 uip_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 = irqsave();
+
+ /* 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)uip_poll(&priv->dev, kinetis_uiptxpoll);
+ }
+ }
+
+ irqrestore(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 uip_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 uip_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_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_PA_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_PA_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.
+ */
+
+#if CONFIG_ENET_USEMII
+ rcr = ENET_RCR_MII_MODE | ENET_RCR_CRCFWD |
+ CONFIG_NET_BUFSIZE << ENET_RCR_MAX_FL_SHIFT;
+#else
+ rcr = ENET_RCR_RMII_MODE | ENET_RCR_CRCFWD |
+ CONFIG_NET_BUFSIZE << ENET_RCR_MAX_FL_SHIFT;
+#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->txdesc = (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 += CONFIG_NET_BUFSIZE;
+ }
+
+ /* 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 += CONFIG_NET_BUFSIZE;
+ }
+
+ /* 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;
+}
+
+/****************************************************************************
+ * 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(inf < 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 */
+
+#if 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
+
+ /* 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);
+
+ /* 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
+ 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);
+ 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/nuttx/arch/arm/src/kinetis/kinetis_enet.h b/nuttx/arch/arm/src/kinetis/kinetis_enet.h
new file mode 100644
index 000000000..0a5e78ea9
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_enet.h
@@ -0,0 +1,609 @@
+/********************************************************************************************
+ * arch/arm/src/kinetis/kinetis_enet.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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 */
+ /* Bits 8-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 CONFIG_ENDIAN_BIG
+# 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 */
+
+#ifdef CONFIG_ENDIAN_BIG
+# 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 */
+
+#ifdef CONFIG_ENDIAN_BIG
+# 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 */
+
+#ifdef CONFIG_ENDIAN_BIG
+# 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
+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 */
+}
+#else
+struct enet_desc_s
+{
+ uint16_t status1; /* Control and status */
+ uint16_t length; /* Data length */
+ uint8_t *data; /* Buffer address */
+};
+#endif
+
+/********************************************************************************************
+ * Public Data
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Functions
+ ********************************************************************************************/
+
+#endif /* KINETIS_NENET && KINETIS_NENET > 0 */
+#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_ENET_H */
diff --git a/nuttx/arch/arm/src/kinetis/kinetis_ewm.h b/nuttx/arch/arm/src/kinetis/kinetis_ewm.h
new file mode 100644
index 000000000..e259a3cf2
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_flexbus.h b/nuttx/arch/arm/src/kinetis/kinetis_flexbus.h
new file mode 100644
index 000000000..37992320f
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_flexcan.h b/nuttx/arch/arm/src/kinetis/kinetis_flexcan.h
new file mode 100644
index 000000000..db151d540
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_fmc.h b/nuttx/arch/arm/src/kinetis/kinetis_fmc.h
new file mode 100644
index 000000000..66f3a3909
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_ftfl.h b/nuttx/arch/arm/src/kinetis/kinetis_ftfl.h
new file mode 100644
index 000000000..92e53b650
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_ftm.h b/nuttx/arch/arm/src/kinetis/kinetis_ftm.h
new file mode 100644
index 000000000..52f782855
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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_CH7OC(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_CH7SEL(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/nuttx/arch/arm/src/kinetis/kinetis_gpio.h b/nuttx/arch/arm/src/kinetis/kinetis_gpio.h
new file mode 100644
index 000000000..1d3d10553
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_i2c.h b/nuttx/arch/arm/src/kinetis/kinetis_i2c.h
new file mode 100644
index 000000000..bee9ef92d
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_i2s.h b/nuttx/arch/arm/src/kinetis/kinetis_i2s.h
new file mode 100644
index 000000000..11bcc0995
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_idle.c b/nuttx/arch/arm/src/kinetis/kinetis_idle.c
new file mode 100644
index 000000000..bcf8218cb
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_idle.c
@@ -0,0 +1,104 @@
+/****************************************************************************
+ * arch/arm/src/kinetis/kinetis_idle.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <arch/board/board.h>
+#include <nuttx/config.h>
+
+#include <nuttx/arch.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() up_ledon(LED_IDLE)
+# define END_IDLE() up_ledoff(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/nuttx/arch/arm/src/kinetis/kinetis_internal.h b/nuttx/arch/arm/src/kinetis/kinetis_internal.h
new file mode 100644
index 000000000..8d7baaaf1
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_internal.h
@@ -0,0 +1,847 @@
+/************************************************************************************
+ * arch/arm/src/kinetis/kinetis_internal.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_INTERNAL_H
+#define __ARCH_ARM_SRC_KINETIS_KINETIS_INTERNAL_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <nuttx/irq.h>
+
+#include "up_internal.h"
+#include "kinetis_config.h"
+#include "chip.h"
+#include "kinetis_port.h"
+
+/************************************************************************************
+ * 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- ---- ---- ---- ---- ---- ----
+ * oooommm:
+ * | `--- 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 << _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.
+ *
+ ************************************************************************************/
+
+EXTERN 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.
+ *
+ ************************************************************************************/
+
+EXTERN void kinetis_lowsetup(void);
+
+/******************************************************************************
+ * Name: kinetis_uartreset
+ *
+ * Description:
+ * Reset a UART.
+ *
+ ******************************************************************************/
+
+#ifdef HAVE_UART_DEVICE
+EXTERN void kinetis_uartreset(uintptr_t uart_base);
+#endif
+
+/******************************************************************************
+ * Name: kinetis_uartconfigure
+ *
+ * Description:
+ * Configure a UART as a RS-232 UART.
+ *
+ ******************************************************************************/
+
+#ifdef HAVE_UART_DEVICE
+EXTERN 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
+ *
+ ************************************************************************************/
+
+EXTERN void kinetis_wddisable(void);
+
+/************************************************************************************
+ * Name: kinetis_pinconfig
+ *
+ * Description:
+ * Configure a pin based on bit-encoded description of the pin.
+ *
+ ************************************************************************************/
+
+EXTERN 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
+ *
+ ************************************************************************************/
+
+EXTERN int kinetis_pinfilter(unsigned int port, bool lpo, unsigned int width);
+
+/************************************************************************************
+ * Name: kinetis_gpiowrite
+ *
+ * Description:
+ * Write one or zero to the selected GPIO pin
+ *
+ ************************************************************************************/
+
+EXTERN void kinetis_gpiowrite(uint32_t pinset, bool value);
+
+/************************************************************************************
+ * Name: kinetis_gpioread
+ *
+ * Description:
+ * Read one or zero from the selected GPIO pin
+ *
+ ************************************************************************************/
+
+EXTERN 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
+EXTERN 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.
+ *
+ ************************************************************************************/
+
+EXTERN 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
+EXTERN 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
+EXTERN 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
+EXTERN void kinetis_pindmaenable(uint32_t pinset);
+#endif
+
+/************************************************************************************
+ * Name: kinetis_pindmadisable
+ *
+ * Description:
+ * Disable DMA for specified pin
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_KINETIS_DMA
+EXTERN 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
+EXTERN 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.
+ *
+ ************************************************************************************/
+
+EXTERN void kinetis_clrpend(int irq);
+
+/************************************************************************************
+ * Name: kinetis_spi/ssp0/ssp1select, kinetis_spi/ssp0/ssp1status, and
+ * kinetis_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.h). All other methods
+ * including up_spiinitialize()) are provided by common Kinetis logic. To use
+ * this common SPI logic on your board:
+ *
+ * 1. Provide logic in kinetis_boardinitialize() to configure SPI/SSP chip select
+ * pins.
+ * 2. Provide kinetis_spi/ssp0/ssp1select() and kinetis_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
+ * kinetis_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 up_spiinitialize() in your low level application
+ * initialization logic
+ * 4. The handle returned by up_spiinitialize() 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_SPI
+EXTERN void kinetis_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t kinetis_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+#ifdef CONFIG_SPI_CMDDATA
+EXTERN int kinetis_spicmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+#endif
+#endif
+#ifdef CONFIG_KINETIS_SSP0
+EXTERN void kinetis_ssp0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t kinetis_ssp0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+#ifdef CONFIG_SPI_CMDDATA
+EXTERN int kinetis_ssp0cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+#endif
+#endif
+#ifdef CONFIG_KINETIS_SSP1
+EXTERN void kinetis_ssp1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t kinetis_ssp1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+#ifdef CONFIG_SPI_CMDDATA
+EXTERN int kinetis_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
+ *
+ ****************************************************************************/
+
+struct spi_dev_s;
+#ifdef CONFIG_KINETIS_SPI
+EXTERN void spi_flush(FAR struct spi_dev_s *dev);
+#endif
+#if defined(CONFIG_KINETIS_SSP0) || defined(CONFIG_KINETIS_SSP1)
+EXTERN void ssp_flush(FAR struct spi_dev_s *dev);
+#endif
+
+/****************************************************************************
+ * Name: kinetis_dmainitialize
+ *
+ * Description:
+ * Initialize the GPDMA subsystem.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_GPDMA
+EXTERN 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_GPDMA
+EXTERN 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_GPDMA
+EXTERN void kinetis_dmafree(DMA_HANDLE handle);
+#endif
+
+/****************************************************************************
+ * Name: kinetis_dmasetup
+ *
+ * Description:
+ * Configure DMA for one transfer.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_GPDMA
+EXTERN 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_GPDMA
+EXTERN 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_GPDMA
+EXTERN void kinetis_dmastop(DMA_HANDLE handle);
+#endif
+
+/****************************************************************************
+ * Name: kinetis_dmasample
+ *
+ * Description:
+ * Sample DMA register contents
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_GPDMA
+#ifdef CONFIG_DEBUG_DMA
+EXTERN 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_GPDMA
+#ifdef CONFIG_DEBUG_DMA
+EXTERN 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;
+EXTERN 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
+EXTERN 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
+EXTERN 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_INTERNAL_H */
diff --git a/nuttx/arch/arm/src/kinetis/kinetis_irq.c b/nuttx/arch/arm/src/kinetis/kinetis_irq.c
new file mode 100644
index 000000000..6fb58c6bf
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_irq.c
@@ -0,0 +1,511 @@
+/****************************************************************************
+ * arch/arm/src/lpc17/kinetis_irq.c
+ * arch/arm/src/chip/kinetis_irq.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "nvic.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+#include "kinetis_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* Enable NVIC debug features that are probably only desireable during
+ * bringup
+ */
+
+#undef KINETIS_IRQ_DEBUG
+
+/* 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
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: kinetis_dumpnvic
+ *
+ * Description:
+ * Dump some interesting NVIC registers
+ *
+ ****************************************************************************/
+
+#if defined(KINETIS_IRQ_DEBUG) && defined (CONFIG_DEBUG)
+static void kinetis_dumpnvic(const char *msg, int irq)
+{
+ irqstate_t flags;
+
+ flags = irqsave();
+ slldbg("NVIC (%s, irq=%d):\n", msg, irq);
+ slldbg(" INTCTRL: %08x VECTAB: %08x\n",
+ getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB));
+#if 0
+ slldbg(" 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
+ slldbg(" 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));
+ slldbg(" SYSH_PRIO: %08x %08x %08x\n",
+ getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY),
+ getreg32(NVIC_SYSH12_15_PRIORITY));
+ slldbg(" 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));
+ slldbg(" %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));
+ slldbg(" %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));
+
+ slldbg(" %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));
+ slldbg(" %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));
+
+ slldbg(" %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));
+ slldbg(" %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
+ slldbg(" %08x %08x\n",
+ getreg32(NVIC_IRQ112_115_PRIORITY), getreg32(NVIC_IRQ116_119_PRIORITY));
+#endif
+
+ irqrestore(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)irqsave();
+ dbg("PANIC!!! NMI received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int kinetis_busfault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Bus fault recived\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int kinetis_usagefault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Usage fault received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int kinetis_pendsv(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! PendSV received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int kinetis_dbgmonitor(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Debug Monitor receieved\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int kinetis_reserved(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Reserved interrupt\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+#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, uint32_t *regaddr, uint32_t *bit)
+{
+ 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;
+ *bit = 1 << (irq - KINETIS_IRQ_EXTINT);
+ }
+ else if (irq < (KINETIS_IRQ_EXTINT+64))
+ {
+ *regaddr = NVIC_IRQ32_63_ENABLE;
+ *bit = 1 << (irq - KINETIS_IRQ_EXTINT - 32);
+ }
+ else if (irq < (KINETIS_IRQ_EXTINT+96))
+ {
+ *regaddr = NVIC_IRQ64_95_ENABLE;
+ *bit = 1 << (irq - KINETIS_IRQ_EXTINT - 64);
+ }
+ else if (irq < NR_IRQS)
+ {
+ *regaddr = NVIC_IRQ96_127_ENABLE;
+ *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)
+{
+ /* Disable all interrupts */
+
+ putreg32(0, NVIC_IRQ0_31_ENABLE);
+ putreg32(0, NVIC_IRQ32_63_ENABLE);
+ putreg32(0, NVIC_IRQ64_95_ENABLE);
+ putreg32(0, NVIC_IRQ96_127_ENABLE);
+
+ /* Set all interrrupts (and exceptions) to the default priority */
+
+ putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);
+
+ putreg32(DEFPRIORITY32, NVIC_IRQ0_3_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ4_7_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ8_11_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ12_15_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ16_19_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ20_23_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ24_27_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ28_31_PRIORITY);
+
+ putreg32(DEFPRIORITY32, NVIC_IRQ32_35_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ36_39_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ40_43_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ44_47_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ48_51_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ52_55_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ56_59_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ60_63_PRIORITY);
+
+ putreg32(DEFPRIORITY32, NVIC_IRQ64_67_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ68_71_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ72_75_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ76_79_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ80_83_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ84_87_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ88_91_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ92_95_PRIORITY);
+
+ putreg32(DEFPRIORITY32, NVIC_IRQ96_99_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ100_103_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ104_107_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ108_111_PRIORITY); /* K40 has 111 defined vectors */
+#if NR_VECTORS > 111
+ putreg32(DEFPRIORITY32, NVIC_IRQ112_115_PRIORITY); /* K60 has 120 defined vectors */
+ putreg32(DEFPRIORITY32, NVIC_IRQ116_119_PRIORITY);
+#endif
+
+ /* 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
+
+ /* If the MPU is enabled, then attach and enable the Memory Management
+ * Fault handler.
+ */
+
+#ifdef CONFIG_ARMV7M_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_ARMV7M_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
+ setbasepri(NVIC_SYSH_PRIORITY_MAX);
+ irqrestore(0);
+#endif
+}
+
+/****************************************************************************
+ * Name: up_disable_irq
+ *
+ * Description:
+ * Disable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_disable_irq(int irq)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (kinetis_irqinfo(irq, &regaddr, &bit) == 0)
+ {
+ /* Clear the appropriate bit in the register to enable the interrupt */
+
+ 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)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (kinetis_irqinfo(irq, &regaddr, &bit) == 0)
+ {
+ /* Set the appropriate bit in the register to enable the interrupt */
+
+ regval = getreg32(regaddr);
+ regval |= bit;
+ putreg32(regval, regaddr);
+ }
+ kinetis_dumpnvic("enable", irq);
+}
+
+/****************************************************************************
+ * Name: up_maskack_irq
+ *
+ * Description:
+ * Mask the IRQ and acknowledge it
+ *
+ ****************************************************************************/
+
+void up_maskack_irq(int irq)
+{
+ up_disable_irq(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)
+ {
+ irq -= 4;
+ regaddr = NVIC_SYSH_PRIORITY(irq);
+ }
+ else
+ {
+ 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/nuttx/arch/arm/src/kinetis/kinetis_k40pinmux.h b/nuttx/arch/arm/src/kinetis/kinetis_k40pinmux.h
new file mode 100644
index 000000000..9798eda6b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_k60pinmux.h b/nuttx/arch/arm/src/kinetis/kinetis_k60pinmux.h
new file mode 100644
index 000000000..2c77dd4ba
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_k60pinmux.h
@@ -0,0 +1,481 @@
+/********************************************************************************************
+ * arch/arm/src/kinetis/kinetis_k60pinset.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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)
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_llwu.h b/nuttx/arch/arm/src/kinetis/kinetis_llwu.h
new file mode 100644
index 000000000..4324a7625
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_lowputc.c b/nuttx/arch/arm/src/kinetis/kinetis_lowputc.c
new file mode 100644
index 000000000..f52d3ba35
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_lowputc.c
@@ -0,0 +1,452 @@
+/**************************************************************************
+ * arch/arm/src/kinetis/kinetis_lowputc.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "kinetis_config.h"
+#include "kinetis_internal.h"
+#include "kinetis_uart.h"
+#include "kinetis_sim.h"
+#include "kinetis_pinmux.h"
+
+/**************************************************************************
+ * Private 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
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/* 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/nuttx/arch/arm/src/kinetis/kinetis_lptmr.h b/nuttx/arch/arm/src/kinetis/kinetis_lptmr.h
new file mode 100644
index 000000000..863b24108
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_mcg.h b/nuttx/arch/arm/src/kinetis/kinetis_mcg.h
new file mode 100644
index 000000000..60f13cd2a
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_mcm.h b/nuttx/arch/arm/src/kinetis/kinetis_mcm.h
new file mode 100644
index 000000000..d899b7702
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_memorymap.h b/nuttx/arch/arm/src/kinetis/kinetis_memorymap.h
new file mode 100644
index 000000000..7253717bd
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_memorymap.h
@@ -0,0 +1,343 @@
+/************************************************************************************
+ * arch/arm/src/kinetis/kinetis_memorymap.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Memory Map ***********************************************************************/
+/* K40 Family
+ *
+ * The memory map for the following parts is defined in Freescale document
+ * K40P144M100SF2RM
+ */
+
+#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 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 */
+
+/* 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)
+
+# 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/nuttx/arch/arm/src/kinetis/kinetis_mmcau.h b/nuttx/arch/arm/src/kinetis/kinetis_mmcau.h
new file mode 100644
index 000000000..7468a1d0b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_mpu.h b/nuttx/arch/arm/src/kinetis/kinetis_mpu.h
new file mode 100644
index 000000000..f2b1bf914
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_osc.h b/nuttx/arch/arm/src/kinetis/kinetis_osc.h
new file mode 100644
index 000000000..16efcf328
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_pdb.h b/nuttx/arch/arm/src/kinetis/kinetis_pdb.h
new file mode 100644
index 000000000..9cfab9b99
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_pin.c b/nuttx/arch/arm/src/kinetis/kinetis_pin.c
new file mode 100644
index 000000000..43bfae61e
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_pin.c
@@ -0,0 +1,261 @@
+/****************************************************************************
+ * arch/arm/src/kinetis/kinetis_pin.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <arch/board/board.h>
+
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/arch.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "kinetis_memorymap.h"
+#include "kinetis_internal.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/nuttx/arch/arm/src/kinetis/kinetis_pindma.c b/nuttx/arch/arm/src/kinetis/kinetis_pindma.c
new file mode 100644
index 000000000..91132a6a7
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_pindma.c
@@ -0,0 +1,146 @@
+/****************************************************************************
+ * arch/arm/src/kinetis/kinetis_pindma.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <arch/board/board.h>
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#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)
+ {
+ /* 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)
+ {
+ /* 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/nuttx/arch/arm/src/kinetis/kinetis_pingpio.c b/nuttx/arch/arm/src/kinetis/kinetis_pingpio.c
new file mode 100644
index 000000000..fe25f0df0
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <arch/board/board.h>
+
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/arch.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "kinetis_memorymap.h"
+#include "kinetis_internal.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/nuttx/arch/arm/src/kinetis/kinetis_pinirq.c b/nuttx/arch/arm/src/kinetis/kinetis_pinirq.c
new file mode 100644
index 000000000..537e7be9f
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_pinirq.c
@@ -0,0 +1,438 @@
+/****************************************************************************
+ * arch/arm/src/kinetis/kinetis_pinirq.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <arch/board/board.h>
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "kinetis_internal.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 = irqsave();
+ 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:
+ 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 */
+
+ 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/nuttx/arch/arm/src/kinetis/kinetis_pinmux.h b/nuttx/arch/arm/src/kinetis/kinetis_pinmux.h
new file mode 100644
index 000000000..9c791539f
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_pinmux.h
@@ -0,0 +1,75 @@
+/********************************************************************************************
+ * arch/arm/src/kinetis/kinetis_pinmux.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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_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/nuttx/arch/arm/src/kinetis/kinetis_pit.h b/nuttx/arch/arm/src/kinetis/kinetis_pit.h
new file mode 100644
index 000000000..808508f8f
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_pmc.h b/nuttx/arch/arm/src/kinetis/kinetis_pmc.h
new file mode 100644
index 000000000..065847da3
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_port.h b/nuttx/arch/arm/src/kinetis/kinetis_port.h
new file mode 100644
index 000000000..a256fc5c6
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_port.h
@@ -0,0 +1,431 @@
+/************************************************************************************
+ * arch/arm/src/kinetis/kinetis_port.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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_
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_rngb.h b/nuttx/arch/arm/src/kinetis/kinetis_rngb.h
new file mode 100644
index 000000000..a4f677555
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_rtc.h b/nuttx/arch/arm/src/kinetis/kinetis_rtc.h
new file mode 100644
index 000000000..69c097a7c
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_sdhc.c b/nuttx/arch/arm/src/kinetis/kinetis_sdhc.c
new file mode 100644
index 000000000..eec5fba0e
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_sdhc.c
@@ -0,0 +1,2934 @@
+/****************************************************************************
+ * arch/arm/src/kinetis/kinetis_sdhc.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+#include <wdog.h>
+#include <errno.h>
+
+#include <nuttx/clock.h>
+#include <nuttx/arch.h>
+#include <nuttx/sdio.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/mmcsd.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+
+#include "kinetis_internal.h"
+#include "kinetis_pinmux.h"
+#include "kinetis_sim.h"
+#include "kinetis_sdhc.h"
+
+#if 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.
+ */
+
+#if 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);
+#if 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 = irqsave();
+ 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);
+ irqrestore(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 = irqsave();
+ priv->xfrints = xfrints;
+ putreg32(priv->xfrints | priv->waitints | SDHC_INT_CINT,
+ KINETIS_SDHC_IRQSIGEN);
+ irqrestore(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(&regs);
+ kinetis_dumpsample(priv, &regs, 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 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);
+ }
+}
+
+/****************************************************************************
+ * Interrrupt 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 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 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
+ *
+ ****************************************************************************/
+
+#if 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
+ *
+ ****************************************************************************/
+
+#if 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);
+
+ /* Set the interrrupt priority */
+
+ up_prioritize_irq(KINETIS_IRQ_SDHC, CONFIG_KINETIS_SDHC_PRIO);
+
+ /* 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 interrrupts */
+
+ 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 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(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 cornercase */
+
+ if (!timeout)
+ {
+ return SDIOWAIT_TIMEOUT;
+ }
+
+ /* Start the watchdog timer */
+
+ delay = (timeout + (MSEC_PER_TICK-1)) / MSEC_PER_TICK;
+ 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 nonzero 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 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 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 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 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 interrrupts */
+
+ 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 -- 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 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 = irqsave();
+ 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);
+ }
+ irqrestore(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 = irqsave();
+ if (wrprotect)
+ {
+ priv->cdstatus |= SDIO_STATUS_WRPROTECTED;
+ }
+ else
+ {
+ priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED;
+ }
+
+ fvdbg("cdstatus: %02x\n", priv->cdstatus);
+ irqrestore(flags);
+}
+#endif /* CONFIG_KINETIS_SDHC */
diff --git a/nuttx/arch/arm/src/kinetis/kinetis_sdhc.h b/nuttx/arch/arm/src/kinetis/kinetis_sdhc.h
new file mode 100644
index 000000000..5d122315a
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_serial.c b/nuttx/arch/arm/src/kinetis/kinetis_serial.c
new file mode 100644
index 000000000..a35e0eef0
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_serial.c
@@ -0,0 +1,1350 @@
+/****************************************************************************
+ * arch/mips/src/kinetis/kinetis_serial.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "os_internal.h"
+
+#include "kinetis_config.h"
+#include "chip.h"
+#include "kinetis_uart.h"
+#include "kinetis_internal.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 */
+#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 Variables
+ ****************************************************************************/
+
+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,
+ .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 = irqsave();
+ regval = up_serialin(priv, KINETIS_UART_C2_OFFSET);
+ regval &= ~UART_C2_ALLINTS;
+ regval |= priv->ie;
+ up_serialout(priv, KINETIS_UART_C2_OFFSET, regval);
+ irqrestore(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 = irqsave();
+ priv->ie = ie & UART_C2_ALLINTS;
+ up_setuartint(priv);
+ irqrestore(flags);
+}
+
+/****************************************************************************
+ * Name: up_disableuartint
+ ****************************************************************************/
+
+static void up_disableuartint(struct up_dev_s *priv, uint8_t *ie)
+{
+ irqstate_t flags;
+
+ flags = irqsave();
+ if (ie)
+ {
+ *ie = priv->ie;
+ }
+
+ up_restoreuartint(priv, 0);
+ irqrestore(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);
+
+ /* Set up the interrupt priority */
+
+ up_prioritize_irq(priv->irqs, priv->irqprio);
+#ifdef CONFIG_DEBUG
+ up_prioritize_irq(priv->irqe, 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_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(OSERR_INTERNAL);
+ }
+ 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(OSERR_INTERNAL);
+ }
+ 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 the FIFO is full,
+ * rather, it means that the 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 the FIFO is empty, rather,
+ * it means that the 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 = irqsave();
+ 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);
+ }
+
+ irqrestore(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 the FIFO is full,
+ * rather, it means that the 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 = irqsave();
+ 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);
+ }
+
+ irqrestore(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 the FIFO is empty,
+ * rather, it means that the 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/nuttx/arch/arm/src/kinetis/kinetis_sim.h b/nuttx/arch/arm/src/kinetis/kinetis_sim.h
new file mode 100644
index 000000000..aad17e923
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_slcd.h b/nuttx/arch/arm/src/kinetis/kinetis_slcd.h
new file mode 100644
index 000000000..d56ee5c41
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_smc.h b/nuttx/arch/arm/src/kinetis/kinetis_smc.h
new file mode 100644
index 000000000..213ea8077
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_start.c b/nuttx/arch/arm/src/kinetis/kinetis_start.c
new file mode 100644
index 000000000..c8f20fbdd
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_start.c
@@ -0,0 +1,158 @@
+/****************************************************************************
+ * 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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/init.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "kinetis_internal.h"
+#include "kinetis_smc.h"
+
+/****************************************************************************
+ * Private 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 intialized 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
+ */
+
+#ifdef CONFIG_BOOT_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
+
+ /* 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/nuttx/arch/arm/src/kinetis/kinetis_timerisr.c b/nuttx/arch/arm/src/kinetis/kinetis_timerisr.c
new file mode 100644
index 000000000..9f9f14ba6
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <time.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "nvic.h"
+#include "clock_internal.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "kinetis_internal.h"
+
+/****************************************************************************
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize
+ * the timer interrupt.
+ *
+ ****************************************************************************/
+
+void up_timerinit(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/nuttx/arch/arm/src/kinetis/kinetis_tsi.h b/nuttx/arch/arm/src/kinetis/kinetis_tsi.h
new file mode 100644
index 000000000..5e1dd9976
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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 (3 << 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_MASK) /* 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/nuttx/arch/arm/src/kinetis/kinetis_uart.h b/nuttx/arch/arm/src/kinetis/kinetis_uart.h
new file mode 100644
index 000000000..fbdf7a319
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_usbdcd.h b/nuttx/arch/arm/src/kinetis/kinetis_usbdcd.h
new file mode 100644
index 000000000..fad76d150
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_usbotg.h b/nuttx/arch/arm/src/kinetis/kinetis_usbotg.h
new file mode 100644
index 000000000..127c71831
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_vectors.S b/nuttx/arch/arm/src/kinetis/kinetis_vectors.S
new file mode 100644
index 000000000..faa1ce7a7
--- /dev/null
+++ b/nuttx/arch/arm/src/kinetis/kinetis_vectors.S
@@ -0,0 +1,741 @@
+/************************************************************************************************
+ * arch/arm/src/kinetis/kinetis_vectors.S
+ * arch/arm/src/chip/kinetis_vectors.S
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <arch/irq.h>
+
+/************************************************************************************************
+ * Preprocessor Definitions
+ ************************************************************************************************/
+/* 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)
+#define HEAP_BASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE)
+
+/* The Cortex-M4 return from interrupt is unusual. We provide the following special
+ * address to the BX instruction. The particular value also forces a return to
+ * thread mode and covers state from the main stack point, the MSP (vs. the MSP).
+ */
+
+#define EXC_RETURN 0xfffffff9
+
+/************************************************************************************************
+ * Global Symbols
+ ************************************************************************************************/
+
+ .globl __start
+
+ .syntax unified
+ .thumb
+ .file "kinetis_vectors.S"
+
+/************************************************************************************************
+ * 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 kinetis_common
+ .endm
+
+/************************************************************************************************
+ * Vectors
+ ************************************************************************************************/
+
+ .section .vectors, "ax"
+ .code 16
+ .align 2
+ .globl kinetis_vectors
+ .type kinetis_vectors, function
+
+kinetis_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 **************************************************************************/
+/* K40 Family ***********************************************************************************
+ *
+ * The interrupt vectors for the following parts is defined in Freescale document
+ * K40P144M100SF2RM
+ */
+
+#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)
+
+ .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)
+
+ .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
+ * K40P144M100SF2RM
+ */
+
+#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)
+
+ 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)
+
+ 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
+ */
+
+kinetis_common:
+
+ /* Complete the context save */
+
+#ifdef CONFIG_NUTTX_KERNEL
+ /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
+ * (handler mode) if the state is on the MSP. It can only be on the PSP if
+ * EXC_RETURN is 0xfffffffd (unprivileged thread)
+ */
+
+ adds r2, r14, #3 /* If R14=0xfffffffd, then r2 == 0 */
+ ite ne /* Next two instructions are condition */
+ mrsne r1, msp /* R1=The main stack pointer */
+ mrseq r1, psp /* R1=The process stack pointer */
+#else
+ mrs r1, msp /* R1=The main stack pointer */
+#endif
+
+ mov r2, r1 /* R2=Copy of the main/process stack pointer */
+ add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
+ mrs r3, primask /* R3=Current PRIMASK setting */
+#ifdef CONFIG_NUTTX_KERNEL
+ stmdb r1!, {r2-r11,r14} /* Save the remaining registers plus the SP value */
+#else
+ stmdb r1!, {r2-r11} /* Save the remaining registers plus the SP value */
+#endif
+
+ /* 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 re-use the main stack for interrupt level processing.
+ */
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ ldr sp, =g_intstackbase
+ str r1, [sp, #-4]! /* Save the MSP on the interrupt stack */
+ bl up_doirq /* R0=IRQ, R1=register save (msp) */
+ ldr r1, [sp, #+4]! /* Recover R1=main stack pointer */
+#else
+ mov sp, r1 /* We are using the main stack pointer */
+ bl up_doirq /* R0=IRQ, R1=register save (msp) */
+ mov r1, sp /* 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 1f /* 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, are 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_NUTTX_KERNEL
+ 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 2f /* Re-join common logic */
+
+ /* We are returning with no context switch. We simply need to "unwind"
+ * the same stack frame that we created
+ */
+1:
+#ifdef CONFIG_NUTTX_KERNEL
+ ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
+#else
+ ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */
+#endif
+2:
+#ifdef CONFIG_NUTTX_KERNEL
+ /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
+ * (handler mode) if the state is on the MSP. It can only be on the PSP if
+ * EXC_RETURN is 0xfffffffd (unprivileged thread)
+ */
+
+ adds r0, r14, #3 /* If R14=0xfffffffd, then r0 == 0 */
+ ite ne /* Next two instructions are condition */
+ msrne msp, r1 /* R1=The main stack pointer */
+ msreq psp, r1 /* R1=The process stack pointer */
+#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 /* Load the special value */
+#endif
+
+ /* Restore the interrupt state */
+
+ msr primask, r3 /* Restore interrupts */
+
+ /* 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: up_interruptstack/g_intstackbase
+ *
+ * Description:
+ * Shouldn't happen
+ *
+ ************************************************************************************************/
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ .bss
+ .global g_intstackbase
+ .align 4
+up_interruptstack:
+ .skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
+g_intstackbase:
+ .size up_interruptstack, .-up_interruptstack
+#endif
+
+/************************************************************************************************
+ * .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_heapbase below.
+ */
+
+ .globl g_heapbase
+ .type g_heapbase, object
+g_heapbase:
+ .word HEAP_BASE
+ .size g_heapbase, .-g_heapbase
+
+ .end
diff --git a/nuttx/arch/arm/src/kinetis/kinetis_vrefv1.h b/nuttx/arch/arm/src/kinetis/kinetis_vrefv1.h
new file mode 100644
index 000000000..ed9a1ff95
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/kinetis/kinetis_wdog.c b/nuttx/arch/arm/src/kinetis/kinetis_wdog.c
new file mode 100644
index 000000000..19b6b1d59
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <arch/irq.h>
+
+#include "up_arch.h"
+#include "kinetis_internal.h"
+#include "kinetis_wdog.h"
+
+/****************************************************************************
+ * Private 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 = irqsave();
+
+ /* Write 0xC520 followed by 0xD928 to the unlock register */
+
+ putreg16(0xc520, KINETIS_WDOG_UNLOCK);
+ putreg16(0xd928, KINETIS_WDOG_UNLOCK);
+ irqrestore(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/nuttx/arch/arm/src/kinetis/kinetis_wdog.h b/nuttx/arch/arm/src/kinetis/kinetis_wdog.h
new file mode 100644
index 000000000..326c2cf62
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/lm3s/Kconfig b/nuttx/arch/arm/src/lm3s/Kconfig
new file mode 100644
index 000000000..03da5c458
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/Kconfig
@@ -0,0 +1,77 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+comment "LM3S Configuration Options"
+
+choice
+ prompt "LM3S Chip Selection"
+ default ARCH_CHIP_LM3S6965
+ depends on ARCH_CHIP_LM3S
+
+config ARCH_CHIP_LM3S6918
+ bool "LM3S6918"
+
+config ARCH_CHIP_LM3S9B96
+ bool "LM3S9B96"
+
+config ARCH_CHIP_LM3S6432
+ bool "LM3S6432"
+
+config ARCH_CHIP_LM3S6965
+ bool "LM3S6965"
+
+config ARCH_CHIP_LM3S8962
+ bool "LM3S8962"
+
+endchoice
+
+choice
+ prompt "Toolchain"
+ default LM3S_BUILDROOT
+
+config LM3S_CODESOURCERYW
+ bool "CodeSourcery GNU toolchain under Windows"
+
+config LM3S_CODESOURCERYL
+ bool "CodeSourcery GNU toolchain under Linux"
+
+config LM3S_DEVKITARM
+ bool "devkitARM GNU toolchain"
+
+config LM3S_BUILDROOT
+ bool "Buildroot"
+
+endchoice
+
+config LM3S_DFU
+ bool "DFU"
+ default y
+
+config LM3S_DISABLE_GPIOA_IRQS
+ bool "Disable GPIOA IRQs"
+
+config LM3S_DISABLE_GPIOB_IRQS
+ bool "Disable GPIOB IRQs"
+
+config LM3S_DISABLE_GPIOC_IRQS
+ bool "Disable GPIOC IRQs"
+
+config LM3S_DISABLE_GPIOD_IRQS
+ bool "Disable GPIOD IRQs"
+
+config LM3S_DISABLE_GPIOE_IRQS
+ bool "Disable GPIOE IRQs"
+
+config LM3S_DISABLE_GPIOF_IRQS
+ bool "Disable GPIOF IRQs"
+
+config LM3S_DISABLE_GPIOG_IRQS
+ bool "Disable GPIOG IRQs"
+
+config LM3S_DISABLE_GPIOH_IRQS
+ bool "Disable GPIOH IRQs"
+
+config LM3S_DISABLE_GPIOJ_IRQS
+ bool "Disable GPIOJ IRQs"
diff --git a/nuttx/arch/arm/src/lm3s/Make.defs b/nuttx/arch/arm/src/lm3s/Make.defs
new file mode 100644
index 000000000..574526f18
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/Make.defs
@@ -0,0 +1,54 @@
+############################################################################
+# arch/arm/src/lm3s/Make.defs
+#
+# Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (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 = lm3s_vectors.S
+
+CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
+CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
+ up_createstack.c up_mdelay.c up_udelay.c up_exit.c \
+ up_idle.c up_initialize.c up_initialstate.c up_interruptcontext.c \
+ up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c \
+ up_releasepending.c up_releasestack.c up_reprioritizertr.c \
+ up_schedulesigaction.c up_sigdeliver.c up_unblocktask.c \
+ up_usestack.c up_doirq.c up_hardfault.c up_svcall.c
+
+CHIP_ASRCS =
+CHIP_CSRCS = lm3s_start.c lm3s_syscontrol.c lm3s_irq.c \
+ lm3s_gpio.c lm3s_gpioirq.c lm3s_timerisr.c lm3s_lowputc.c \
+ lm3s_serial.c lm3s_ssi.c lm3s_dumpgpio.c
+
+ifdef CONFIG_NET
+CHIP_CSRCS += lm3s_ethernet.c
+endif
diff --git a/nuttx/arch/arm/src/lm3s/chip.h b/nuttx/arch/arm/src/lm3s/chip.h
new file mode 100644
index 000000000..1e22f6221
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/chip.h
@@ -0,0 +1,134 @@
+/************************************************************************************
+ * arch/arm/src/lm3s/chip.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_LM3S_CHIP_H
+#define __ARCH_ARM_SRC_LM3S_CHIP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Get customizations for each supported chip (only the LM3S6918 and 65 right now) */
+
+#if defined(CONFIG_ARCH_CHIP_LM3S6918)
+# define LM3S_NTIMERS 4 /* Four general purpose timers */
+# define LM3S_NETHCONTROLLERS 1 /* One Ethernet controller */
+# undef LM3S_ETHTS /* No timestamp register */
+# define LM3S_NSSI 2 /* Two SSI modules */
+# define LM3S_NUARTS 2 /* Two UART modules */
+# define LM3S_NI2C 2 /* Two I2C modules */
+# define LM3S_NADC 1 /* One ADC module */
+# define LM2S_NPWM 0 /* No PWM generator modules */
+# define LM3S_NQEI 0 /* No quadrature encoders */
+# define LM3S_NPORTS 8 /* 8 Ports (GPIOA-H) 5-38 GPIOs */
+#elif defined(CONFIG_ARCH_CHIP_LM3S6432)
+# define LM3S_NTIMERS 3 /* Three general purpose timers */
+# define LM3S_NETHCONTROLLERS 1 /* One Ethernet controller */
+# undef LM3S_ETHTS /* No timestamp register */
+# define LM3S_NSSI 1 /* One SSI module */
+# define LM3S_NUARTS 2 /* Two UART modules */
+# define LM3S_NI2C 1 /* Two I2C modules */
+# define LM3S_NADC 1 /* One ADC module */
+# define LM2S_NPWM 1 /* One PWM generator module */
+# define LM3S_NQEI 0 /* No quadrature encoders */
+# define LM3S_NPORTS 7 /* 7 Ports (GPIOA-G), 0-42 GPIOs */
+#elif defined(CONFIG_ARCH_CHIP_LM3S6965)
+# define LM3S_NTIMERS 4 /* Four general purpose timers */
+# define LM3S_NETHCONTROLLERS 1 /* One Ethernet controller */
+# undef LM3S_ETHTS /* No timestamp register */
+# define LM3S_NSSI 1 /* One SSI module */
+# define LM3S_NUARTS 3 /* Three UART modules */
+# define LM3S_NI2C 2 /* Two I2C modules */
+# define LM3S_NADC 1 /* One ADC module */
+# define LM2S_NPWM 3 /* Three PWM generator modules */
+# define LM3S_NQEI 2 /* Two quadrature encoders */
+# define LM3S_NPORTS 7 /* 7 Ports (GPIOA-G), 0-42 GPIOs */
+#elif defined(CONFIG_ARCH_CHIP_LM3S9B96)
+# define LM3S_NTIMERS 4 /* Four general purpose timers */
+# define LM3S_NETHCONTROLLERS 1 /* One Ethernet controller */
+# undef LM3S_ETHTS /* No timestamp register */
+# define LM3S_NSSI 2 /* Two SSI modules */
+# define LM3S_NUARTS 3 /* Three UART modules */
+# define LM3S_NI2C 2 /* Two I2C modules */
+# define LM3S_NADC 2 /* Two ADC module */
+# define LM3S_CAN 2 /* Two CAN module */
+# define LM3S_NPWM 4 /* Four PWM generator modules */
+# define LM3S_NQEI 2 /* Two quadrature encoders */
+# define LM3S_NPORTS 9 /* 9 Ports (GPIOA-H,J) 0-65 GPIOs */
+#elif defined(CONFIG_ARCH_CHIP_LM3S8962)
+# define LM3S_NTIMERS 4 /* Four general purpose timers */
+# define LM3S_NETHCONTROLLERS 1 /* One Ethernet controller */
+# define LM3S_NSSI 1 /* One SSI module */
+# define LM3S_NUARTS 3 /* Two UART modules */
+# define LM3S_NI2C 2 /* One I2C module */
+# define LM3S_NADC 1 /* One ADC module */
+# define LM2S_NPWM 3 /* Three PWM generator modules */
+# define LM3S_NQEI 2 /* Two quadrature encoders */
+# define LM3S_NPORTS 7 /* 7 Ports (GPIOA-G), 5-42 GPIOs */
+# define LC3S_CANCONTROLLER 1 /* One CAN controller */
+#else
+# error "Capabilities not specified for this LM3S chip"
+#endif
+
+/* Then get all of the register definitions */
+
+#include "lm3s_memorymap.h" /* Memory map */
+#include "lm3s_syscontrol.h" /* System control module */
+#include "lm3s_gpio.h" /* GPIO modules */
+#include "lm3s_uart.h" /* UART modules */
+#include "lm3s_i2c.h" /* I2C modules */
+#include "lm3s_ssi.h" /* SSI modules */
+#include "lm3s_ethernet.h" /* Ethernet MAC and PHY */
+#include "lm3s_flash.h" /* FLASH */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LM3S_CHIP_H */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_dumpgpio.c b/nuttx/arch/arm/src/lm3s/lm3s_dumpgpio.c
new file mode 100644
index 000000000..334a3930f
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_dumpgpio.c
@@ -0,0 +1,167 @@
+/****************************************************************************
+ * arch/arm/src/lm3s/lm3s_dumpgpio.c
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lm3s_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* NOTE: this is duplicated in lm3s_gpio.c */
+
+#ifdef LM3S_GPIOH_BASE
+static const uint32_t g_gpiobase[8] =
+{
+ LM3S_GPIOA_BASE, LM3S_GPIOB_BASE, LM3S_GPIOC_BASE, LM3S_GPIOD_BASE,
+ LM3S_GPIOE_BASE, LM3S_GPIOF_BASE, LM3S_GPIOG_BASE, LM3S_GPIOH_BASE,
+};
+
+static const char g_portchar[8] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
+#else
+static const uint32_t g_gpiobase[8] =
+{
+ LM3S_GPIOA_BASE, LM3S_GPIOB_BASE, LM3S_GPIOC_BASE, LM3S_GPIOD_BASE,
+ LM3S_GPIOE_BASE, LM3S_GPIOF_BASE, LM3S_GPIOG_BASE, 0,
+};
+
+static const char g_portchar[8] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', '?' };
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lm3s_gpiobaseaddress
+ *
+ * Description:
+ * Given a GPIO enumeration value, return the base address of the
+ * associated GPIO registers.
+ *
+ ****************************************************************************/
+
+static inline uint32_t lm3s_gpiobaseaddress(int port)
+{
+ return g_gpiobase[port & 7];
+}
+
+/****************************************************************************
+ * Name: lm3s_gpioport
+ *
+ * Description:
+ * Given a GPIO enumeration value, return the base address of the
+ * associated GPIO registers.
+ *
+ ****************************************************************************/
+
+static inline uint8_t lm3s_gpioport(int port)
+{
+ return g_portchar[port & 7];
+}
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: lm3s_dumpgpio
+ *
+ * Description:
+ * Dump all GPIO registers associated with the provided base address
+ *
+ ****************************************************************************/
+
+int lm3s_dumpgpio(uint32_t pinset, const char *msg)
+{
+ irqstate_t flags;
+ unsigned int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ uint32_t base;
+ uint32_t rcgc2;
+ bool enabled;
+
+ /* Get the base address associated with the GPIO port */
+
+ base = lm3s_gpiobaseaddress(port);
+ DEBUGASSERT(base != 0);
+
+ /* The following requires exclusive access to the GPIO registers */
+
+ flags = irqsave();
+ rcgc2 = getreg32(LM3S_SYSCON_RCGC2);
+ enabled = ((rcgc2 & SYSCON_RCGC2_GPIO(port)) != 0);
+
+ lldbg("GPIO%c pinset: %08x base: %08x -- %s\n",
+ lm3s_gpioport(port), pinset, base, msg);
+ lldbg(" RCGC2: %08x (%s)\n",
+ rcgc2, enabled ? "enabled" : "disabled" );
+
+ /* 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 + LM3S_GPIO_AFSEL_OFFSET), getreg32(base + LM3S_GPIO_DEN_OFFSET),
+ getreg32(base + LM3S_GPIO_DIR_OFFSET), getreg32(base + LM3S_GPIO_DATA_OFFSET + 0x3fc));
+ lldbg(" IS: %02x IBE: %02x IEV: %02x IM: %02x RIS: %08x MIS: %08x\n",
+ getreg32(base + LM3S_GPIO_IEV_OFFSET), getreg32(base + LM3S_GPIO_IM_OFFSET),
+ getreg32(base + LM3S_GPIO_RIS_OFFSET), getreg32(base + LM3S_GPIO_MIS_OFFSET));
+ lldbg(" 2MA: %02x 4MA: %02x 8MA: %02x ODR: %02x PUR %02x PDR: %02x SLR: %02x\n",
+ getreg32(base + LM3S_GPIO_DR2R_OFFSET), getreg32(base + LM3S_GPIO_DR4R_OFFSET),
+ getreg32(base + LM3S_GPIO_DR8R_OFFSET), getreg32(base + LM3S_GPIO_ODR_OFFSET),
+ getreg32(base + LM3S_GPIO_PUR_OFFSET), getreg32(base + LM3S_GPIO_PDR_OFFSET),
+ getreg32(base + LM3S_GPIO_SLR_OFFSET));
+ }
+ irqrestore(flags);
+ return OK;
+}
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_epi.h b/nuttx/arch/arm/src/lm3s/lm3s_epi.h
new file mode 100644
index 000000000..90c9bfb7f
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_epi.h
@@ -0,0 +1,113 @@
+/************************************************************************************
+ * arch/arm/src/lm3s/lm3s_epi.h
+ *
+ * Copyright (C) 2009-2012 Max Neklyudov. All rights reserved.
+ * Author: Max Neklyudov <macscomp@gmail.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_LM3S_LM3S_EPI_H
+#define __ARCH_ARM_SRC_LM3S_LM3S_EPI_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* External Peripheral Interface Register Offsets ***********************************/
+
+#define LM3S_EPI_CFG_OFFSET 0x000
+#define LM3S_EPI_SDRAMCFG_OFFSET 0x010
+#define LM3S_EPI_ADDRMAP_OFFSET 0x01C
+#define LM3S_EPI_STAT_OFFSET 0x060
+#define LM3S_EPI_BAUD_OFFSET 0x004
+
+/* External Peripheral Interface Register Addresses *********************************/
+
+#define LM3S_EPI0_CFG (LM3S_EPI0_BASE + LM3S_EPI_CFG_OFFSET)
+#define LM3S_EPI0_SDRAMCFG (LM3S_EPI0_BASE + LM3S_EPI_SDRAMCFG_OFFSET)
+#define LM3S_EPI0_ADDRMAP (LM3S_EPI0_BASE + LM3S_EPI_ADDRMAP_OFFSET)
+#define LM3S_EPI0_STAT (LM3S_EPI0_BASE + LM3S_EPI_STAT_OFFSET)
+#define LM3S_EPI0_BAUD (LM3S_EPI0_BASE + LM3S_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_LM3S_LM3S_EPI_H */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_ethernet.c b/nuttx/arch/arm/src/lm3s/lm3s_ethernet.c
new file mode 100644
index 000000000..f7bbedb20
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_ethernet.c
@@ -0,0 +1,1470 @@
+/****************************************************************************
+ * arch/arm/src/lm3s/lm3s_ethernet.c
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_LM3S_ETHERNET)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <time.h>
+#include <string.h>
+#include <debug.h>
+#include <wdog.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+#include <nuttx/net/uip/uip.h>
+#include <nuttx/net/uip/uip-arp.h>
+#include <nuttx/net/uip/uip-arch.h>
+
+#include "chip.h"
+#include "up_arch.h"
+
+#include "lm3s_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Half duplex can be forced if CONFIG_LM3S_ETHHDUPLEX is defined. */
+
+#ifdef CONFIG_LM3S_ETHHDUPLEX
+# define LM3S_DUPLEX_SETBITS 0
+# define LM3S_DUPLEX_CLRBITS MAC_TCTL_DUPLEX
+#else
+# define LM3S_DUPLEX_SETBITS MAC_TCTL_DUPLEX
+# define LM3S_DUPLEX_CLRBITS 0
+#endif
+
+/* Auto CRC generation can be suppressed if CONFIG_LM3S_ETHNOAUTOCRC is definde */
+
+#ifdef CONFIG_LM3S_ETHNOAUTOCRC
+# define LM3S_CRC_SETBITS 0
+# define LM3S_CRC_CLRBITS MAC_TCTL_CRC
+#else
+# define LM3S_CRC_SETBITS MAC_TCTL_CRC
+# define LM3S_CRC_CLRBITS 0
+#endif
+
+/* Tx padding can be suppressed if CONFIG_LM3S_ETHNOPAD is defined */
+
+#ifdef CONFIG_LM3S_ETHNOPAD
+# define LM3S_PADEN_SETBITS 0
+# define LM3S_PADEN_CLRBITS MAC_TCTL_PADEN
+#else
+# define LM3S_PADEN_SETBITS MAC_TCTL_PADEN
+# define LM3S_PADEN_CLRBITS 0
+#endif
+
+#define LM3S_TCTCL_SETBITS (LM3S_DUPLEX_SETBITS|LM3S_CRC_SETBITS|LM3S_PADEN_SETBITS)
+#define LM3S_TCTCL_CLRBITS (LM3S_DUPLEX_CLRBITS|LM3S_CRC_CLRBITS|LM3S_PADEN_CLRBITS)
+
+/* Multicast frames can be enabled by defining CONFIG_LM3S_MULTICAST */
+
+#ifdef CONFIG_LM3S_MULTICAST
+# define LM3S_AMUL_SETBITS MAC_RCTL_AMUL
+# define LM3S_AMUL_CLRBITS 0
+#else
+# define LM3S_AMUL_SETBITS 0
+# define LM3S_AMUL_CLRBITS MAC_RCTL_AMUL
+#endif
+
+/* Promiscuous mode can be enabled by defining CONFIG_LM3S_PROMISCUOUS */
+
+#ifdef CONFIG_LM3S_PROMISCUOUS
+# define LM3S_PRMS_SETBITS MAC_RCTL_PRMS
+# define LM3S_PRMS_CLRBITS 0
+#else
+# define LM3S_PRMS_SETBITS 0
+# define LM3S_PRMS_CLRBITS MAC_RCTL_PRMS
+#endif
+
+/* Bad CRC rejection can be enabled by define CONFIG_LM3S_BADCRC */
+
+#ifdef CONFIG_LM3S_BADCRC
+# define LM3S_BADCRC_SETBITS MAC_RCTL_BADCRC
+# define LM3S_BADCRC_CLRBITS 0
+#else
+# define LM3S_BADCRC_SETBITS 0
+# define LM3S_BADCRC_CLRBITS MAC_RCTL_BADCRC
+#endif
+
+#define LM3S_RCTCL_SETBITS (LM3S_AMUL_SETBITS|LM3S_PRMS_SETBITS|LM3S_BADCRC_SETBITS)
+#define LM3S_RCTCL_CLRBITS (LM3S_AMUL_CLRBITS|LM3S_PRMS_CLRBITS|LM3S_BADCRC_CLRBITS)
+
+/* CONFIG_LM3S_DUMPPACKET will dump the contents of each packet to the console. */
+
+#ifdef CONFIG_LM3S_DUMPPACKET
+# define lm3s_dumppacket(m,a,n) lib_dumpbuffer(m,a,n)
+#else
+# define lm3s_dumppacket(m,a,n)
+#endif
+
+/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */
+
+#define LM3S_WDDELAY (1*CLK_TCK)
+#define LM3S_POLLHSEC (1*2)
+
+/* TX timeout = 1 minute */
+
+#define LM3S_TXTIMEOUT (60*CLK_TCK)
+
+/* This is a helper pointer for accessing the contents of the Ethernet header */
+
+#define ETHBUF ((struct uip_eth_hdr *)priv->ld_dev.d_buf)
+
+#define LM32S_MAX_MDCCLK 2500000
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* EMAC statistics (debug only) */
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
+struct lm3s_statistics_s
+{
+ uint32_t rx_int; /* Number of Rx interrupts received */
+ uint32_t rx_packets; /* Number of packets received (sum of the following): */
+ uint32_t rx_ip; /* Number of Rx IP packets received */
+ uint32_t rx_arp; /* Number of Rx ARP packets received */
+ uint32_t rx_dropped; /* Number of dropped, unsupported Rx packets */
+ uint32_t rx_pktsize; /* Number of dropped, too small or too big */
+ uint32_t rx_errors; /* Number of Rx errors (reception error) */
+ uint32_t rx_ovrerrors; /* Number of Rx FIFO overrun errors */
+ uint32_t tx_int; /* Number of Tx interrupts received */
+ uint32_t tx_packets; /* Number of Tx packets queued */
+ uint32_t tx_errors; /* Number of Tx errors (transmission error)*/
+ uint32_t tx_timeouts; /* Number of Tx timeout errors */
+};
+# define EMAC_STAT(priv,name) priv->ld_stat.name++
+#else
+# define EMAC_STAT(priv,name)
+#endif
+
+/* The lm3s_driver_s encapsulates all state information for a single hardware
+ * interface
+ */
+
+struct lm3s_driver_s
+{
+ /* The following fields would only be necessary on chips that support
+ * multiple Ethernet controllers.
+ */
+
+#if LM3S_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 */
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
+ struct lm3s_statistics_s ld_stat;
+#endif
+
+ /* This holds the information visible to uIP/NuttX */
+
+ struct uip_driver_s ld_dev; /* Interface understood by uIP */
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct lm3s_driver_s g_lm3sdev[LM3S_NETHCONTROLLERS];
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Miscellaneous low level helpers */
+
+#if LM3S_NETHCONTROLLERS > 1
+static uint32_t lm3s_ethin(struct lm3s_driver_s *priv, int offset);
+static void lm3s_ethout(struct lm3s_driver_s *priv, int offset, uint32_t value);
+#else
+static inline uint32_t lm3s_ethin(struct lm3s_driver_s *priv, int offset);
+static inline void lm3s_ethout(struct lm3s_driver_s *priv, int offset, uint32_t value);
+#endif
+static void lm3s_ethreset(struct lm3s_driver_s *priv);
+#if 0 /* Not used */
+static void lm3s_phywrite(struct lm3s_driver_s *priv, int regaddr, uint16_t value);
+#endif
+static uint16_t lm3s_phyread(struct lm3s_driver_s *priv, int regaddr);
+
+/* Common TX logic */
+
+static int lm3s_transmit(struct lm3s_driver_s *priv);
+static int lm3s_uiptxpoll(struct uip_driver_s *dev);
+
+/* Interrupt handling */
+
+static void lm3s_receive(struct lm3s_driver_s *priv);
+static void lm3s_txdone(struct lm3s_driver_s *priv);
+static int lm3s_interrupt(int irq, FAR void *context);
+
+/* Watchdog timer expirations */
+
+static void lm3s_polltimer(int argc, uint32_t arg, ...);
+static void lm3s_txtimeout(int argc, uint32_t arg, ...);
+
+/* NuttX callback functions */
+
+static int lm3s_ifup(struct uip_driver_s *dev);
+static int lm3s_ifdown(struct uip_driver_s *dev);
+static int lm3s_txavail(struct uip_driver_s *dev);
+#ifdef CONFIG_NET_IGMP
+static int lm3s_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
+static int lm3s_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: lm3s_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 LM3S_NETHCONTROLLERS > 1
+static uint32_t lm3s_ethin(struct lm3s_driver_s *priv, int offset)
+{
+ return getreg32(priv->ld_base + offset);
+}
+#else
+static inline uint32_t lm3s_ethin(struct lm3s_driver_s *priv, int offset)
+{
+ return getreg32(LM3S_ETHCON_BASE + offset);
+}
+#endif
+
+/****************************************************************************
+ * Function: lm3s_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 LM3S_NETHCONTROLLERS > 1
+static void lm3s_ethout(struct lm3s_driver_s *priv, int offset, uint32_t value)
+{
+ putreg32(value, priv->ld_base + offset);
+}
+#else
+static inline void lm3s_ethout(struct lm3s_driver_s *priv, int offset, uint32_t value)
+{
+ putreg32(value, LM3S_ETHCON_BASE + offset);
+}
+#endif
+
+/****************************************************************************
+ * Function: lm3s_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 lm3s_ethreset(struct lm3s_driver_s *priv)
+{
+ irqstate_t flags;
+ uint32_t regval;
+
+#if LM3S_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 = irqsave();
+ regval = getreg32(LM3S_SYSCON_RCGC2);
+ regval |= (SYSCON_RCGC2_EMAC0|SYSCON_RCGC2_EPHY0);
+ putreg32(regval, LM3S_SYSCON_RCGC2);
+ nllvdbg("RCGC2: %08x\n", regval);
+
+ /* Put the Ethernet controller into the reset state */
+
+ regval = getreg32(LM3S_SYSCON_SRCR2);
+ regval |= (SYSCON_SRCR2_EMAC0|SYSCON_SRCR2_EPHY0);
+ putreg32(regval, LM3S_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, LM3S_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_LM3S_ETHLEDS
+ /* Configure the pins for the peripheral function */
+
+ lm3s_configgpio(GPIO_ETHPHY_LED0 | GPIO_STRENGTH_2MA | GPIO_PADTYPE_STD);
+ lm3s_configgpio(GPIO_ETHPHY_LED1 | GPIO_STRENGTH_2MA | GPIO_PADTYPE_STD);
+#endif
+
+ /* Disable all Ethernet controller interrupts */
+
+ regval = lm3s_ethin(priv, LM3S_MAC_IM_OFFSET);
+ regval &= ~MAC_IM_ALLINTS;
+ lm3s_ethout(priv, LM3S_MAC_IM_OFFSET, regval);
+
+ /* Clear any pending interrupts (shouldn't be any) */
+
+ regval = lm3s_ethin(priv, LM3S_MAC_RIS_OFFSET);
+ lm3s_ethout(priv, LM3S_MAC_IACK_OFFSET, regval);
+ irqrestore(flags);
+}
+
+/****************************************************************************
+ * Function: lm3s_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 lm3s_phywrite(struct lm3s_driver_s *priv, int regaddr, uint16_t value)
+{
+ /* Wait for any MII transactions in progress to complete */
+
+ while ((lm3s_ethin(priv, LM3S_MAC_MCTL_OFFSET) & MAC_MCTL_START) != 0);
+
+ /* Set up the data to be written */
+
+ DEBUGASSERT(value < MAC_MTXD_MASK);
+ lm3s_ethout(priv, LM3S_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);
+ lm3s_ethout(priv, LM3S_MAC_MCTL_OFFSET, regaddr | MAC_MCTL_WRITE | MAC_MCTL_START);
+
+ /* Wait for the write transaction to complete */
+
+ while ((lm3s_ethin(priv, LM3S_MAC_MCTL_OFFSET) & MAC_MCTL_START) != 0);
+}
+#endif
+
+/****************************************************************************
+ * Function: lm3s_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 lm3s_phyread(struct lm3s_driver_s *priv, int regaddr)
+{
+ /* Wait for any MII transactions in progress to complete */
+
+ while ((lm3s_ethin(priv, LM3S_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);
+ lm3s_ethout(priv, LM3S_MAC_MCTL_OFFSET, regaddr | MAC_MCTL_START);
+
+ /* Wait for the write transaction to complete */
+
+ while ((lm3s_ethin(priv, LM3S_MAC_MCTL_OFFSET) & MAC_MCTL_START) != 0);
+
+ /* Read and return the PHY data */
+
+ return (uint16_t)(lm3s_ethin(priv, LM3S_MAC_MRXD_OFFSET) & MAC_MTRD_MASK);
+}
+
+/****************************************************************************
+ * Function: lm3s_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 lm3s_transmit(struct lm3s_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 = irqsave();
+ if ((lm3s_ethin(priv, LM3S_MAC_TR_OFFSET) & MAC_TR_NEWTX) == 0)
+ {
+ /* Increment statistics */
+
+ EMAC_STAT(priv, tx_packets);
+ lm3s_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 > UIP_LLH_LEN);
+
+ dbuf = priv->ld_dev.d_buf;
+ regval = (uint32_t)(pktlen - 14);
+ regval |= ((uint32_t)(*dbuf++) << 16);
+ regval |= ((uint32_t)(*dbuf++) << 24);
+ lm3s_ethout(priv, LM3S_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.
+ */
+
+ lm3s_ethout(priv, LM3S_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;
+ }
+ lm3s_ethout(priv, LM3S_MAC_DATA_OFFSET, regval);
+ }
+
+ /* Activate the transmitter */
+
+ lm3s_ethout(priv, LM3S_MAC_TR_OFFSET, MAC_TR_NEWTX);
+
+ /* Setup the TX timeout watchdog (perhaps restarting the timer) */
+
+ (void)wd_start(priv->ld_txtimeout, LM3S_TXTIMEOUT, lm3s_txtimeout, 1, (uint32_t)priv);
+ ret = OK;
+ }
+
+ irqrestore(flags);
+ return ret;
+}
+
+/****************************************************************************
+ * Function: lm3s_uiptxpoll
+ *
+ * Description:
+ * The transmitter is available, check if uIP has any outgoing packets ready
+ * to send. This is a callback from uip_poll(). uip_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 lm3s_uiptxpoll(struct uip_driver_s *dev)
+{
+ struct lm3s_driver_s *priv = (struct lm3s_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)
+ {
+ /* Send the packet. lm3s_transmit() will return zero if the
+ * packet was successfully handled.
+ */
+
+ DEBUGASSERT((lm3s_ethin(priv, LM3S_MAC_TR_OFFSET) & MAC_TR_NEWTX) == 0)
+ uip_arp_out(&priv->ld_dev);
+ ret = lm3s_transmit(priv);
+ }
+
+ /* If zero is returned, the polling will continue until all connections have
+ * been examined.
+ */
+
+ return ret;
+}
+
+/****************************************************************************
+ * Function: lm3s_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 lm3s_receive(struct lm3s_driver_s *priv)
+{
+ uint32_t regval;
+ uint8_t *dbuf;
+ int pktlen;
+ int bytesleft;
+
+ /* Loop while there are incoming packets to be processed */
+
+ while ((lm3s_ethin(priv, LM3S_MAC_NP_OFFSET) & MAC_NP_MASK) != 0)
+ {
+ /* Update statistics */
+
+ EMAC_STAT(priv, rx_packets);
+
+ /* 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 = lm3s_ethin(priv, LM3S_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_BUFSIZE + 6) || pktlen <= (UIP_LLH_LEN + 6))
+ {
+ int wordlen;
+
+ /* We will have to drop this packet */
+
+ nlldbg("Bad packet size dropped (%d)\n", pktlen);
+ EMAC_STAT(priv, rx_pktsize);
+
+ /* 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)lm3s_ethin(priv, LM3S_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 = lm3s_ethin(priv, LM3S_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 = lm3s_ethin(priv, LM3S_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;
+ lm3s_dumppacket("Received packet", priv->ld_dev.d_buf, priv->ld_dev.d_len);
+
+ /* We only accept IP packets of the configured type and ARP packets */
+
+#ifdef CONFIG_NET_IPv6
+ if (ETHBUF->type == HTONS(UIP_ETHTYPE_IP6))
+#else
+ if (ETHBUF->type == HTONS(UIP_ETHTYPE_IP))
+#endif
+ {
+ nllvdbg("IP packet received (%02x)\n", ETHBUF->type);
+ EMAC_STAT(priv, rx_ip);
+
+ uip_arp_ipin(&priv->ld_dev);
+ uip_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)
+ {
+ uip_arp_out(&priv->ld_dev);
+ lm3s_transmit(priv);
+ }
+ }
+ else if (ETHBUF->type == htons(UIP_ETHTYPE_ARP))
+ {
+ nllvdbg("ARP packet received (%02x)\n", ETHBUF->type);
+ EMAC_STAT(priv, rx_arp);
+
+ uip_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)
+ {
+ lm3s_transmit(priv);
+ }
+ }
+#ifdef CONFIG_DEBUG
+ else
+ {
+ nlldbg("Unsupported packet type dropped (%02x)\n", htons(ETHBUF->type));
+ EMAC_STAT(priv, rx_dropped);
+ }
+#endif
+ }
+}
+
+/****************************************************************************
+ * Function: lm3s_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 lm3s_txdone(struct lm3s_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((lm3s_ethin(priv, LM3S_MAC_TR_OFFSET) & MAC_TR_NEWTX) == 0)
+
+ /* Then poll uIP for new XMIT data */
+
+ (void)uip_poll(&priv->ld_dev, lm3s_uiptxpoll);
+}
+
+/****************************************************************************
+ * Function: lm3s_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 lm3s_interrupt(int irq, FAR void *context)
+{
+ register struct lm3s_driver_s *priv;
+ uint32_t ris;
+
+#if LM3S_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 = lm3s_ethin(priv, LM3S_MAC_RIS_OFFSET);
+
+ /* Clear all pending interrupts */
+
+ lm3s_ethout(priv, LM3S_MAC_IACK_OFFSET, ris);
+
+ /* Check for errors */
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
+ if ((ris & MAC_RIS_TXER) != 0)
+ {
+ EMAC_STAT(priv, tx_errors); /* Number of Tx errors */
+ }
+
+ if ((ris & MAC_RIS_FOV) != 0)
+ {
+ EMAC_STAT(priv, rx_ovrerrors); /* Number of Rx FIFO overrun errors */
+ }
+
+ if ((ris & MAC_RIS_RXER) != 0)
+ {
+ EMAC_STAT(priv, rx_errors); /* Number of Rx errors */
+ }
+#endif
+
+ /* Handle (unmasked) interrupts according to status bit settings */
+
+ ris &= lm3s_ethin(priv, LM3S_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 */
+
+ EMAC_STAT(priv, rx_int);
+ lm3s_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 */
+
+ EMAC_STAT(priv, tx_int);
+ lm3s_txdone(priv);
+ }
+
+ /* Enable Ethernet interrupts (perhaps excluding the TX done interrupt if
+ * there are no pending transmissions).
+ */
+
+ return OK;
+}
+
+/****************************************************************************
+ * Function: lm3s_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 lm3s_txtimeout(int argc, uint32_t arg, ...)
+{
+ struct lm3s_driver_s *priv = (struct lm3s_driver_s *)arg;
+
+ /* Increment statistics */
+
+ nlldbg("Tx timeout\n");
+ EMAC_STAT(priv, tx_timeouts);
+
+ /* Then reset the hardware */
+
+ DEBUGASSERT(priv->ld_bifup);
+ lm3s_ifdown(&priv->ld_dev);
+ lm3s_ifup(&priv->ld_dev);
+
+ /* Then poll uIP for new XMIT data */
+
+ (void)uip_poll(&priv->ld_dev, lm3s_uiptxpoll);
+}
+
+/****************************************************************************
+ * Function: lm3s_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 lm3s_polltimer(int argc, uint32_t arg, ...)
+{
+ struct lm3s_driver_s *priv = (struct lm3s_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 ((lm3s_ethin(priv, LM3S_MAC_TR_OFFSET) & MAC_TR_NEWTX) == 0)
+ {
+ /* If so, update TCP timing states and poll uIP for new XMIT data */
+
+ (void)uip_timer(&priv->ld_dev, lm3s_uiptxpoll, LM3S_POLLHSEC);
+
+ /* Setup the watchdog poll timer again */
+
+ (void)wd_start(priv->ld_txpoll, LM3S_WDDELAY, lm3s_polltimer, 1, arg);
+ }
+}
+
+/****************************************************************************
+ * Function: lm3s_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 lm3s_ifup(struct uip_driver_s *dev)
+{
+ struct lm3s_driver_s *priv = (struct lm3s_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 = irqsave();
+ lm3s_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 LM32S_MAX_MDCCLK is not exceeded.
+ */
+
+ div = SYSCLK_FREQUENCY / 2 / LM32S_MAX_MDCCLK;
+ lm3s_ethout(priv, LM3S_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 = lm3s_ethin(priv, LM3S_MAC_TCTL_OFFSET);
+ regval &= ~LM3S_TCTCL_CLRBITS;
+ regval |= LM3S_TCTCL_SETBITS;
+ lm3s_ethout(priv, LM3S_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 = lm3s_ethin(priv, LM3S_MAC_RCTL_OFFSET);
+ regval &= ~LM3S_RCTCL_CLRBITS;
+ regval |= LM3S_RCTCL_SETBITS;
+ lm3s_ethout(priv, LM3S_MAC_RCTL_OFFSET, regval);
+ nllvdbg("RCTL: %08x\n", regval);
+
+ /* Setup the time stamp configuration register */
+
+#ifdef LM3S_ETHTS
+ regval = lm3s_ethin(priv, LM3S_MAC_TS_OFFSET);
+#ifdef CONFIG_LM3S_TIMESTAMP
+ regval |= MAC_TS_EN;
+#else
+ regval &= ~(MAC_TS_EN);
+#endif
+ lm3s_ethout(priv, LM3S_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 = lm3s_phyread(priv, MII_MSR);
+ }
+ while ((phyreg & MII_MSR_LINKSTATUS) == 0);
+ nlldbg("Link established\n");
+
+ /* Reset the receive FIFO */
+
+ regval = lm3s_ethin(priv, LM3S_MAC_RCTL_OFFSET);
+ regval |= MAC_RCTL_RSTFIFO;
+ lm3s_ethout(priv, LM3S_MAC_RCTL_OFFSET, regval);
+
+ /* Enable the Ethernet receiver */
+
+ regval = lm3s_ethin(priv, LM3S_MAC_RCTL_OFFSET);
+ regval |= MAC_RCTL_RXEN;
+ lm3s_ethout(priv, LM3S_MAC_RCTL_OFFSET, regval);
+
+ /* Enable the Ethernet transmitter */
+
+ regval = lm3s_ethin(priv, LM3S_MAC_TCTL_OFFSET);
+ regval |= MAC_TCTL_TXEN;
+ lm3s_ethout(priv, LM3S_MAC_TCTL_OFFSET, regval);
+
+ /* Reset the receive FIFO (again) */
+
+ regval = lm3s_ethin(priv, LM3S_MAC_RCTL_OFFSET);
+ regval |= MAC_RCTL_RSTFIFO;
+ lm3s_ethout(priv, LM3S_MAC_RCTL_OFFSET, regval);
+
+ /* Enable the Ethernet interrupt */
+
+#if LM3S_NETHCONTROLLERS > 1
+ up_enable_irq(priv->irq);
+#else
+ up_enable_irq(LM3S_IRQ_ETHCON);
+#endif
+
+ /* Enable the Ethernet RX packet receipt interrupt */
+
+ regval = lm3s_ethin(priv, LM3S_MAC_IM_OFFSET);
+ regval |= MAC_IM_RXINTM;
+ lm3s_ethout(priv, LM3S_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];
+ lm3s_ethout(priv, LM3S_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];
+ lm3s_ethout(priv, LM3S_MAC_IA1_OFFSET, regval);
+
+ /* Set and activate a timer process */
+
+ (void)wd_start(priv->ld_txpoll, LM3S_WDDELAY, lm3s_polltimer, 1, (uint32_t)priv);
+
+ priv->ld_bifup = true;
+ irqrestore(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * Function: lm3s_ifdown
+ *
+ * Description:
+ * NuttX Callback: Stop the interface. The only way to restore normal
+ * behavior is to call lm3s_ifup().
+ *
+ * Parameters:
+ * dev - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int lm3s_ifdown(struct uip_driver_s *dev)
+{
+ struct lm3s_driver_s *priv = (struct lm3s_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 = irqsave();
+ wd_cancel(priv->ld_txpoll);
+ wd_cancel(priv->ld_txtimeout);
+
+ /* Disable the Ethernet interrupt */
+
+#if LM3S_NETHCONTROLLERS > 1
+ up_disable_irq(priv->irq);
+#else
+ up_disable_irq(LM3S_IRQ_ETHCON);
+#endif
+
+ /* Disable all Ethernet controller interrupt sources */
+
+ regval = lm3s_ethin(priv, LM3S_MAC_IM_OFFSET);
+ regval &= ~MAC_IM_ALLINTS;
+ lm3s_ethout(priv, LM3S_MAC_IM_OFFSET, regval);
+
+ /* Reset the receive FIFO */
+
+ regval = lm3s_ethin(priv, LM3S_MAC_RCTL_OFFSET);
+ regval |= MAC_RCTL_RSTFIFO;
+ lm3s_ethout(priv, LM3S_MAC_RCTL_OFFSET, regval);
+
+ /* Disable the Ethernet receiver */
+
+ regval = lm3s_ethin(priv, LM3S_MAC_RCTL_OFFSET);
+ regval &= ~MAC_RCTL_RXEN;
+ lm3s_ethout(priv, LM3S_MAC_RCTL_OFFSET, regval);
+
+ /* Disable the Ethernet transmitter */
+
+ regval = lm3s_ethin(priv, LM3S_MAC_RCTL_OFFSET);
+ regval &= ~MAC_TCTL_TXEN;
+ lm3s_ethout(priv, LM3S_MAC_TCTL_OFFSET, regval);
+
+ /* Reset the receive FIFO (again) */
+
+ regval = lm3s_ethin(priv, LM3S_MAC_RCTL_OFFSET);
+ regval |= MAC_RCTL_RSTFIFO;
+ lm3s_ethout(priv, LM3S_MAC_RCTL_OFFSET, regval);
+
+ /* Clear any pending interrupts */
+
+ regval = lm3s_ethin(priv, LM3S_MAC_RIS_OFFSET);
+ lm3s_ethout(priv, LM3S_MAC_IACK_OFFSET, regval);
+
+ /* The interface is now DOWN */
+
+ priv->ld_bifup = false;
+ irqrestore(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * Function: lm3s_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 lm3s_txavail(struct uip_driver_s *dev)
+{
+ struct lm3s_driver_s *priv = (struct lm3s_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, lm3s_txdone() will be called and the Tx polling
+ * will occur at that time.
+ */
+
+ flags = irqsave();
+ if (priv->ld_bifup && (lm3s_ethin(priv, LM3S_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)uip_poll(&priv->ld_dev, lm3s_uiptxpoll);
+ }
+
+ irqrestore(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * Function: lm3s_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 lm3s_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
+{
+ FAR struct lm3s_driver_s *priv = (FAR struct lm3s_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: lm3s_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 lm3s_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
+{
+ FAR struct lm3s_driver_s *priv = (FAR struct lm3s_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: lm3s_ethinitialize
+ *
+ * Description:
+ * Initialize the Ethernet driver for one interface
+ *
+ * Parameters:
+ * None
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#if LM3S_NETHCONTROLLERS > 1
+int lm3s_ethinitialize(int intf)
+#else
+static inline int lm3s_ethinitialize(int intf)
+#endif
+{
+ struct lm3s_driver_s *priv = &g_lm3sdev[intf];
+ int ret;
+
+ /* Check if the Ethernet module is present */
+
+ ndbg("Setting up eth%d\n", intf);
+
+#if LM3S_NETHCONTROLLERS > 1
+# error "This debug check only works with one interface"
+#else
+ DEBUGASSERT((getreg32(LM3S_SYSCON_DC4) & (SYSCON_DC4_EMAC0|SYSCON_DC4_EPHY0)) == (SYSCON_DC4_EMAC0|SYSCON_DC4_EPHY0));
+#endif
+ DEBUGASSERT((unsigned)intf < LM3S_NETHCONTROLLERS);
+
+ /* Initialize the driver structure */
+
+ memset(priv, 0, sizeof(struct lm3s_driver_s));
+ priv->ld_dev.d_ifup = lm3s_ifup; /* I/F down callback */
+ priv->ld_dev.d_ifdown = lm3s_ifdown; /* I/F up (new IP address) callback */
+ priv->ld_dev.d_txavail = lm3s_txavail; /* New TX data callback */
+#ifdef CONFIG_NET_IGMP
+ priv->ld_dev.d_addmac = lm3s_addmac; /* Add multicast MAC address */
+ priv->ld_dev.d_rmmac = lm3s_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 transmisstions */
+
+#if LM3S_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 lm3s_ifup()
+ * is caleld (and the MAC can be overwritten with a netdev ioctl call).
+ */
+
+#ifdef CONFIG_LM3S_BOARDMAC
+ lm3s_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 lm3s_ifup() is called.
+ */
+
+ lm3s_ethreset(priv);
+ lm3s_ifdown(&priv->ld_dev);
+
+ /* Attach the IRQ to the driver */
+
+#if LM3S_NETHCONTROLLERS > 1
+ ret = irq_attach(priv->irq, lm3s_interrupt);
+#else
+ ret = irq_attach(LM3S_IRQ_ETHCON, lm3s_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);
+ 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 LM3S_NETHCONTROLLERS == 1
+void up_netinitialize(void)
+{
+ (void)lm3s_ethinitialize(0);
+}
+#endif
+
+#endif /* CONFIG_NET && CONFIG_LM3S_ETHERNET */
+
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_ethernet.h b/nuttx/arch/arm/src/lm3s/lm3s_ethernet.h
new file mode 100644
index 000000000..71833b271
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_ethernet.h
@@ -0,0 +1,203 @@
+/************************************************************************************
+ * arch/arm/src/lm3s/lm3s_ethernet.h
+ *
+ * Copyright (C) 2009-2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_LM3S_LM3S_ETHERNET_H
+#define __ARCH_ARM_SRC_LM3S_LM3S_ETHERNET_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/net/mii.h>
+
+#include "chip.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Ethernet Controller Register Offsets *********************************************/
+
+/* Ethernet MAC Register Offsets */
+
+#define LM3S_MAC_RIS_OFFSET 0x000 /* Ethernet MAC Raw Interrupt Status */
+#define LM3S_MAC_IACK_OFFSET 0x000 /* Ethernet MAC Acknowledge */
+#define LM3S_MAC_IM_OFFSET 0x004 /* Ethernet MAC Interrupt Mask */
+#define LM3S_MAC_RCTL_OFFSET 0x008 /* Ethernet MAC Receive Control */
+#define LM3S_MAC_TCTL_OFFSET 0x00c /* Ethernet MAC Transmit Control */
+#define LM3S_MAC_DATA_OFFSET 0x010 /* Ethernet MAC Data */
+#define LM3S_MAC_IA0_OFFSET 0x014 /* Ethernet MAC Individual Address 0 */
+#define LM3S_MAC_IA1_OFFSET 0x018 /* Ethernet MAC Individual Address 1 */
+#define LM3S_MAC_THR_OFFSET 0x01c /* Ethernet MAC Threshold */
+#define LM3S_MAC_MCTL_OFFSET 0x020 /* Ethernet MAC Management Control */
+#define LM3S_MAC_MDV_OFFSET 0x024 /* Ethernet MAC Management Divider */
+#define LM3S_MAC_MTXD_OFFSET 0x02c /* Ethernet MAC Management Transmit Data */
+#define LM3S_MAC_MRXD_OFFSET 0x030 /* Ethernet MAC Management Receive Data */
+#define LM3S_MAC_NP_OFFSET 0x034 /* Ethernet MAC Number of Packets */
+#define LM3S_MAC_TR_OFFSET 0x038 /* Ethernet MAC Transmission Request */
+#ifdef LM3S_ETHTS
+# define LM3S_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 LM3S_MAC_RIS (LM3S_ETHCON_BASE + LM3S_MAC_RIS_OFFSET)
+#define LM3S_MAC_IACK (LM3S_ETHCON_BASE + LM3S_MAC_IACK_OFFSET)
+#define LM3S_MAC_IM (LM3S_ETHCON_BASE + LM3S_MAC_IM_OFFSET)
+#define LM3S_MAC_RCTL (LM3S_ETHCON_BASE + LM3S_MAC_RCTL_OFFSET)
+#define LM3S_MAC_TCTL (LM3S_ETHCON_BASE + LM3S_MAC_TCTL_OFFSET)
+#define LM3S_MAC_DATA (LM3S_ETHCON_BASE + LM3S_MAC_DATA_OFFSET)
+#define LM3S_MAC_IA0 (LM3S_ETHCON_BASE + LM3S_MAC_IA0_OFFSET)
+#define LM3S_MAC_IA1 (LM3S_ETHCON_BASE + LM3S_MAC_IA1_OFFSET)
+#define LM3S_MAC_THR (LM3S_ETHCON_BASE + LM3S_MAC_THR_OFFSET)
+#define LM3S_MAC_MCTL (LM3S_ETHCON_BASE + LM3S_MAC_MCTL_OFFSET)
+#define LM3S_MAC_MDV (LM3S_ETHCON_BASE + LM3S_MAC_MDV_OFFSET)
+#define LM3S_MAC_MTXD (LM3S_ETHCON_BASE + LM3S_MAC_MTXD_OFFSET)
+#define LM3S_MAC_MRXD (LM3S_ETHCON_BASE + LM3S_MAC_MRXD_OFFSET)
+#define LM3S_MAC_NP (LM3S_ETHCON_BASE + LM3S_MAC_NP_OFFSET)
+#define LM3S_MAC_TR (LM3S_ETHCON_BASE + LM3S_MAC_TR_OFFSET)
+#ifdef LM3S_ETHTS
+# define LM3S_MAC_TS (LM3S_ETHCON_BASE + LM3S_MAC_TS_OFFSET)
+#endif
+
+/* Memory Mapped MII Management Registers */
+
+#define MAC_MII_MCR (LM3S_ETHCON_BASE + MII_MCR)
+#define MAC_MII_MSR (LM3S_ETHCON_BASE + MII_MSR)
+#define MAC_MII_PHYID1 (LM3S_ETHCON_BASE + MII_PHYID1)
+#define MAC_MII_PHYID2 (LM3S_ETHCON_BASE + MII_PHYID2)
+#define MAC_MII_ADVERTISE (LM3S_ETHCON_BASE + MII_ADVERTISE)
+#define MAC_MII_LPA (LM3S_ETHCON_BASE + MII_LPA)
+#define MAC_MII_EXPANSION (LM3S_ETHCON_BASE + MII_EXPANSION)
+#define MAC_MII_VSPECIFIC (LM3S_ETHCON_BASE + MII_LM3S_VSPECIFIC)
+#define MAC_MII_INTCS (LM3S_ETHCON_BASE + MII_LM3S_INTCS)
+#define MAC_MII_DIAGNOSTIC (LM3S_ETHCON_BASE + MII_LM3S_DIAGNOSTIC)
+#define MAC_MII_XCVRCONTROL (LM3S_ETHCON_BASE + MII_LM3S_XCVRCONTROL)
+#define MAC_MII_LEDCONFIG (LM3S_ETHCON_BASE + MII_LM3S_LEDCONFIG)
+#define MAC_MII_MDICONTROL (LM3S_ETHCON_BASE + MII_LM3S_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_LM3S_LM3S_ETHERNET_H */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_flash.h b/nuttx/arch/arm/src/lm3s/lm3s_flash.h
new file mode 100644
index 000000000..83e388921
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_flash.h
@@ -0,0 +1,128 @@
+/************************************************************************************
+ * arch/arm/src/lm3s/lm3s_flash.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_LM3S_LM3S_FLASH_H
+#define __ARCH_ARM_SRC_LM3S_LM3S_FLASH_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* FLASH register offsets ***********************************************************/
+
+/* The FMA, FMD, FMC, FCRIS, FCIM, and FCMISC registers are relative to the Flash
+ * control base address of LM3S_FLASHCON_BASE.
+ */
+
+#define LM3S_FLASH_FMA_OFFSET 0x000 /* Flash memory address */
+#define LM3S_FLASH_FMD_OFFSET 0x004 /* Flash memory data */
+#define LM3S_FLASH_FMC_OFFSET 0x008 /* Flash memory control */
+#define LM3S_FLASH_FCRIS_OFFSET 0x00c /* Flash controller raw interrupt status */
+#define LM3S_FLASH_FCIM_OFFSET 0x010 /* Flash controller interrupt mask */
+#define LM3S_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 LM3S_SYSCON_BASE
+ */
+
+#define LM3S_FLASH_FMPRE_OFFSET 0x130 /* Flash memory protection read enable */
+#define LM3S_FLASH_FMPPE_OFFSET 0x134 /* Flash memory protection program enable */
+#define LM3S_FLASH_USECRL_OFFSET 0x140 /* USec Reload */
+#define LM3S_FLASH_USERDBG_OFFSET 0x1d0 /* User Debug */
+#define LM3S_FLASH_USERREG0_OFFSET 0x1e0 /* User Register 0 */
+#define LM3S_FLASH_USERREG1_OFFSET 0x1e4 /* User Register 1 */
+#define LM3S_FLASH_FMPRE0_OFFSET 0x200 /* Flash Memory Protection Read Enable 0 */
+#define LM3S_FLASH_FMPRE1_OFFSET 0x204 /* Flash Memory Protection Read Enable 1 */
+#define LM3S_FLASH_FMPRE2_OFFSET 0x208 /* Flash Memory Protection Read Enable 2 */
+#define LM3S_FLASH_FMPRE3_OFFSET 0x20c /* Flash Memory Protection Read Enable 3 */
+#define LM3S_FLASH_FMPPE0_OFFSET 0x400 /* Flash Memory Protection Program Enable 0 */
+#define LM3S_FLASH_FMPPE1_OFFSET 0x404 /* Flash Memory Protection Program Enable 1 */
+#define LM3S_FLASH_FMPPE2_OFFSET 0x408 /* Flash Memory Protection Program Enable 2 */
+#define LM3S_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 LM3S_FLASHCON_BASE.
+ */
+
+#define LM3S_FLASH_FMA (LM3S_FLASHCON_BASE + LM3S_FLASH_FMA_OFFSET)
+#define LM3S_FLASH_FMD (LM3S_FLASHCON_BASE + LM3S_FLASH_FMD_OFFSET)
+#define LM3S_FLASH_FMC (LM3S_FLASHCON_BASE + LM3S_FLASH_FMC_OFFSET)
+#define LM3S_FLASH_FCRIS (LM3S_FLASHCON_BASE + LM3S_FLASH_FCRIS_OFFSET)
+#define LM3S_FLASH_FCIM (LM3S_FLASHCON_BASE + LM3S_FLASH_FCIM_OFFSET)
+#define LM3S_FLASH_FCMISC (LM3S_FLASHCON_BASE + LM3S_FLASH_FCMISC_OFFSET)
+
+/* The FMPREn, FMPPEn, USECRL, USER_DBG, and USER_REGn registers are relative to the
+ * System Control base address of LM3S_SYSCON_BASE
+ */
+
+#define LM3S_FLASH_FMPRE (LM3S_SYSCON_BASE + LM3S_FLASH_FMPRE_OFFSET)
+#define LM3S_FLASH_FMPPE (LM3S_SYSCON_BASE + LM3S_FLASH_FMPPE_OFFSET)
+#define LM3S_FLASH_USECRL (LM3S_SYSCON_BASE + LM3S_FLASH_USECRL_OFFSET)
+#define LM3S_FLASH_USERDBG (LM3S_SYSCON_BASE + LM3S_FLASH_USERDBG_OFFSET)
+#define LM3S_FLASH_USERREG0 (LM3S_SYSCON_BASE + LM3S_FLASH_USERREG0_OFFSET)
+#define LM3S_FLASH_USERREG1 (LM3S_SYSCON_BASE + LM3S_FLASH_USERREG1_OFFSET)
+#define LM3S_FLASH_FMPRE0 (LM3S_SYSCON_BASE + LM3S_FLASH_FMPRE0_OFFSET)
+#define LM3S_FLASH_FMPRE1 (LM3S_SYSCON_BASE + LM3S_FLASH_FMPRE1_OFFSET)
+#define LM3S_FLASH_FMPRE2 (LM3S_SYSCON_BASE + LM3S_FLASH_FMPRE2_OFFSET)
+#define LM3S_FLASH_FMPRE3 (LM3S_SYSCON_BASE + LM3S_FLASH_FMPRE3_OFFSET)
+#define LM3S_FLASH_FMPPE0 (LM3S_SYSCON_BASE + LM3S_FLASH_FMPPE0_OFFSET)
+#define LM3S_FLASH_FMPPE1 (LM3S_SYSCON_BASE + LM3S_FLASH_FMPPE1_OFFSET)
+#define LM3S_FLASH_FMPPE2 (LM3S_SYSCON_BASE + LM3S_FLASH_FMPPE2_OFFSET)
+#define LM3S_FLASH_FMPPE3 (LM3S_SYSCON_BASE + LM3S_FLASH_FMPPE3_OFFSET)
+
+/* FLASH register bit defitiions ****************************************************/
+/* To be provided */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Function Prototypes
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LM3S_LM3S_FLASH_H */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_gpio.c b/nuttx/arch/arm/src/lm3s/lm3s_gpio.c
new file mode 100644
index 000000000..c345d113c
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_gpio.c
@@ -0,0 +1,854 @@
+/****************************************************************************
+ * arch/arm/src/lm3s/lm3s_gpio.c
+ * arch/arm/src/chip/lm3s_gpio.c
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#include "up_arch.h"
+#include "os_internal.h"
+#include "lm3s_internal.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 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 (AFSEL_0 | DIR_0 | ODR_0 | DEN_1 | PUR_X | PDR_X)
+#define GPIO_INPUT_CLRBITS (AFSEL_1 | DIR_1 | ODR_1 | DEN_0 | PUR_X | PDR_X)
+
+#define GPIO_OUTPUT_SETBITS (AFSEL_0 | DIR_1 | ODR_0 | DEN_1 | PUR_X | PDR_X)
+#define GPIO_OUTPUT_CLRBITS (AFSEL_1 | DIR_0 | ODR_1 | DEN_0 | PUR_X | PDR_X)
+
+#define GPIO_ODINPUT_SETBITS (AFSEL_0 | DIR_0 | ODR_1 | DEN_1 | PUR_X | PDR_X)
+#define GPIO_ODINPUT_CLRBITS (AFSEL_1 | DIR_1 | ODR_0 | DEN_0 | PUR_X | PDR_X)
+
+#define GPIO_ODOUTPUT_SETBITS (AFSEL_0 | DIR_1 | ODR_1 | DEN_1 | PUR_X | PDR_X)
+#define GPIO_ODOUTPUT_CLRBITS (AFSEL_1 | DIR_0 | ODR_0 | DEN_0 | PUR_X | PDR_X)
+
+#define GPIO_PFODIO_SETBITS (AFSEL_1 | DIR_X | ODR_1 | DEN_1 | PUR_X | PDR_X)
+#define GPIO_PFODIO_CLRBITS (AFSEL_0 | DIR_X | ODR_0 | DEN_0 | PUR_X | PDR_X)
+
+#define GPIO_PFIO_SETBITS (AFSEL_1 | DIR_X | ODR_0 | DEN_1 | PUR_X | PDR_X)
+#define GPIO_PFIO_CLRBITS (AFSEL_0 | DIR_X | ODR_1 | DEN_0 | PUR_X | PDR_X)
+
+#define GPIO_ANINPUT_SETBITS (AFSEL_0 | DIR_0 | ODR_0 | DEN_0 | PUR_0 | PDR_0)
+#define GPIO_ANINPUT_CLRBITS (AFSEL_1 | DIR_1 | ODR_1 | DEN_1 | PUR_1 | PDR_1)
+
+#define GPIO_INTERRUPT_SETBITS (AFSEL_0 | DIR_0 | ODR_0 | DEN_1 | PUR_X | PDR_X)
+#define GPIO_INTERRUPT_CLRBITS (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 */
+};
+
+static const uint32_t g_gpiobase[LM3S_NPORTS] =
+{
+ /* All support LM3S parts have at least 7 ports, GPIOA-G */
+
+ LM3S_GPIOA_BASE, LM3S_GPIOB_BASE, LM3S_GPIOC_BASE, LM3S_GPIOD_BASE,
+ LM3S_GPIOE_BASE, LM3S_GPIOF_BASE, LM3S_GPIOG_BASE,
+
+ /* GPIOH exists on the LM3S6918 and th LM3S6B96, but not on the LM3S6965 or LM3S8962*/
+
+#if LM3S_NPORTS > 7
+ LM3S_GPIOH_BASE,
+#endif
+
+ /* GPIOJ exists on the LM3S6B96, but not on the LM3S6918 or LM3S6965 or LM3S8962*/
+
+#if LM3S_NPORTS > 8
+ LM3S_GPIOJ_BASE,
+#endif
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lm3s_gpiobaseaddress
+ *
+ * Description:
+ * Given a GPIO enumeration value, return the base address of the
+ * associated GPIO registers.
+ *
+ ****************************************************************************/
+
+static uint32_t lm3s_gpiobaseaddress(unsigned int port)
+{
+ uint32_t gpiobase = 0;
+ if (port < LM3S_NPORTS)
+ {
+ gpiobase = g_gpiobase[port];
+ }
+ return gpiobase;
+}
+
+/****************************************************************************
+ * Name: lm3s_gpiofunc
+ *
+ * Description:
+ * Configure GPIO registers for a specific function
+ *
+ ****************************************************************************/
+
+static void lm3s_gpiofunc(uint32_t base, uint32_t pinno, const struct gpio_func_s *func)
+{
+ uint32_t setbit;
+ uint32_t clrbit;
+ uint32_t regval;
+
+ /* 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;
+
+ regval = getreg32(base + LM3S_GPIO_ODR_OFFSET);
+ regval &= ~clrbit;
+ regval |= setbit;
+ putreg32(regval, base + LM3S_GPIO_ODR_OFFSET);
+
+ /* 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)
+ {
+ regval = getreg32(base + LM3S_GPIO_PUR_OFFSET);
+ regval &= ~clrbit;
+ regval |= setbit;
+ putreg32(regval, base + LM3S_GPIO_PUR_OFFSET);
+ }
+
+ /* 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)
+ {
+ regval = getreg32(base + LM3S_GPIO_PDR_OFFSET);
+ regval &= ~clrbit;
+ regval |= setbit;
+ putreg32(regval, base + LM3S_GPIO_PDR_OFFSET);
+ }
+
+ /* 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;
+
+ regval = getreg32(base + LM3S_GPIO_DEN_OFFSET);
+ regval &= ~clrbit;
+ regval |= setbit;
+ putreg32(regval, base + LM3S_GPIO_DEN_OFFSET);
+
+ /* 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;
+
+ regval = getreg32(base + LM3S_GPIO_DIR_OFFSET);
+ regval &= ~clrbit;
+ regval |= setbit;
+ putreg32(regval, base + LM3S_GPIO_DIR_OFFSET);
+
+ /* 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 so 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;
+
+ regval = getreg32(base + LM3S_GPIO_AFSEL_OFFSET);
+ regval &= ~clrbit;
+ regval |= setbit;
+ putreg32(regval, base + LM3S_GPIO_AFSEL_OFFSET);
+}
+
+/****************************************************************************
+ * Name: lm3s_gpiopadstrength
+ *
+ * Description:
+ * Set up pad strength and pull-ups
+ *
+ ****************************************************************************/
+
+static inline void lm3s_gpiopadstrength(uint32_t base, uint32_t pin, uint32_t cfgset)
+{
+ int strength = (cfgset & GPIO_STRENGTH_MASK) >> GPIO_STRENGTH_SHIFT;
+ uint32_t regoffset;
+ uint32_t regval;
+ uint32_t slrset;
+ uint32_t slrclr;
+
+ /* Prepare bits to disable slew */
+
+ slrset = 0;
+ slrclr = pin;
+
+ switch (strength)
+ {
+ case 0: /* 2mA pad drive strength */
+ {
+ /* "The GPIODR2R register is the 2-mA drive control register. It
+ * allows for each GPIO signal in the port to be individually configured
+ * without affecting the other pads. When writing a DRV2 bit for a GPIO
+ * signal, the corresponding DRV4 bit in the GPIO DR4R register and the
+ * DRV8 bit in the GPIODR8R register are automatically cleared by hardware."
+ */
+
+ regoffset = LM3S_GPIO_DR2R_OFFSET;
+ }
+ break;
+
+ case 1: /* 4mA pad drive strength */
+ {
+ /* "The GPIODR4R register is the 4-mA drive control register. It allows
+ * for each GPIO signal in the port to be individually configured without
+ * affecting the other pads. When writing the DRV4 bit for a GPIO signal,
+ * the corresponding DRV2 bit in the GPIO DR2R register and the DRV8 bit
+ * in the GPIO DR8R register are automatically cleared by hardware."
+ */
+
+ regoffset = LM3S_GPIO_DR4R_OFFSET;
+ }
+ break;
+
+ case 3: /* 8mA Pad drive with slew rate control */
+ {
+ /* "The GPIOSLR register is the slew rate control register. Slew rate
+ * control is only available when using the 8-mA drive strength option
+ * via the GPIO 8-mA Drive Select (GPIODR8R) register..."
+ */
+
+ slrset = pin;
+ slrclr = 0;
+ }
+ /* Fall through */
+
+ case 2: /* 8mA pad drive strength (without slew rate control) */
+ {
+ /* "The GPIODR8R register is the 8-mA drive control register. It
+ * allows for each GPIO signal in the port to be individually configured
+ * without affecting the other pads. When writing the DRV8 bit for a GPIO
+ * signal, the corresponding DRV2 bit in the GPIO DR2R register and the
+ * DRV4 bit in the GPIO DR4R register are automatically cleared by hardware."
+ */
+
+ regoffset = LM3S_GPIO_DR8R_OFFSET;
+ }
+ break;
+ }
+
+ /* Set the selected pad strength and set/clear optional slew rate control */
+
+ regval = getreg32(base + regoffset);
+ regval |= pin;
+ putreg32(regval, base + regoffset);
+
+ regval = getreg32(base + LM3S_GPIO_SLR_OFFSET);
+ regval &= slrclr;
+ regval |= slrset;
+ putreg32(regval, base + LM3S_GPIO_SLR_OFFSET);
+}
+
+/****************************************************************************
+ * Name: lm3s_gpiopadtype
+ *
+ * Description:
+ * Set up pad strength and pull-ups. Some of these values may be over-
+ * written by lm3s_gpiofunc, depending on the function selection. Others
+ * are optional for different function selections.
+ *
+ ****************************************************************************/
+
+static inline void lm3s_gpiopadtype(uint32_t base, uint32_t pin, uint32_t cfgset)
+{
+ int padtype = (cfgset & GPIO_PADTYPE_MASK) >> GPIO_PADTYPE_SHIFT;
+#if 0 /* always overwritten by lm3s_gpiofunc */
+ uint32_t odrset;
+ uint32_t odrclr;
+#endif
+ uint32_t purset;
+ uint32_t purclr;
+ uint32_t pdrset;
+ uint32_t pdrclr;
+#if 0 /* always overwritten by lm3s_gpiofunc */
+ uint32_t denset;
+ uint32_t denclr;
+#endif
+ uint32_t regval;
+
+ /* Assume digital GPIO function, push-pull with no pull-up or pull-down */
+
+#if 0 /* always overwritten by lm3s_gpiofunc */
+ odrset = 0;
+ odrclr = pin;
+#endif
+ purset = 0;
+ purclr = pin;
+ pdrset = 0;
+ pdrclr = pin;
+#if 0 /* always overwritten by lm3s_gpiofunc */
+ denset = pin;
+ denclr = 0;
+#endif
+
+ switch (padtype)
+ {
+ case 0: /* Push-pull */
+ default:
+ {
+ }
+ break;
+
+ case 1: /* Push-pull with weak pull-up */
+ {
+ purset = pin;
+ purclr = 0;
+ }
+ break;
+ case 2: /* Push-pull with weak pull-down */
+ {
+ pdrset = pin;
+ pdrclr = 0;
+ }
+ break;
+ case 3: /* Open-drain */
+ {
+#if 0 /* always overwritten by lm3s_gpiofunc */
+ odrset = pin;
+ odrclr = 0;
+#endif
+ }
+ break;
+ case 4: /* Open-drain with weak pull-up */
+ {
+#if 0 /* always overwritten by lm3s_gpiofunc */
+ odrset = pin;
+ odrclr = 0;
+#endif
+ purset = pin;
+ purclr = 0;
+ }
+ break;
+ case 5: /* Open-drain with weak pull-down */
+ {
+#if 0 /* always overwritten by lm3s_gpiofunc */
+ odrset = pin;
+ odrclr = 0;
+#endif
+ pdrset = pin;
+ pdrclr = 0;
+ }
+ break;
+ case 6: /* Analog comparator */
+ {
+#if 0 /* always overwritten by lm3s_gpiofunc */
+ denset = 0;
+ denclr = pin;
+#endif
+ }
+ break;
+ }
+
+ /* Set/clear 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."
+ */
+
+#if 0 /* always overwritten by lm3s_gpiofunc */
+ regval = getreg32(base + LM3S_GPIO_ODR_OFFSET);
+ regval &= ~odrclr;
+ regval |= odrset;
+ putreg32(regval, base + LM3S_GPIO_ODR_OFFSET);
+#endif
+
+ /* 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 ..."
+ */
+
+ regval = getreg32(base + LM3S_GPIO_PUR_OFFSET);
+ regval &= ~purclr;
+ regval |= purset;
+ putreg32(regval, base + LM3S_GPIO_PUR_OFFSET);
+
+ /* 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 ..."
+ */
+
+ regval = getreg32(base + LM3S_GPIO_PDR_OFFSET);
+ regval &= ~pdrclr;
+ regval |= pdrset;
+ putreg32(regval, base + LM3S_GPIO_PDR_OFFSET);
+
+ /* 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."
+ */
+
+#if 0 /* always overwritten by lm3s_gpiofunc */
+ regval = getreg32(base + LM3S_GPIO_DEN_OFFSET);
+ regval &= ~denclr;
+ regval |= denset;
+ putreg32(regval, base + LM3S_GPIO_DEN_OFFSET);
+#endif
+}
+
+/****************************************************************************
+ * Name: lm3s_initoutput
+ *
+ * Description:
+ * Set the GPIO output value
+ *
+ ****************************************************************************/
+
+static inline void lm3s_initoutput(uint32_t cfgset)
+{
+ bool value = ((cfgset & GPIO_VALUE_MASK) != GPIO_VALUE_ZERO);
+ lm3s_gpiowrite(cfgset, value);
+}
+
+/****************************************************************************
+ * Name: lm3s_interrupt
+ *
+ * Description:
+ * Configure the interrupt pin.
+ *
+ ****************************************************************************/
+
+static inline void lm3s_interrupt(uint32_t base, uint32_t pin, uint32_t cfgset)
+{
+ int inttype = (cfgset & GPIO_INT_MASK) >> GPIO_INT_SHIFT;
+ uint32_t regval;
+ uint32_t isset;
+ uint32_t isclr;
+ uint32_t ibeset;
+ uint32_t ibeclr;
+ uint32_t iveset;
+ uint32_t iveclr;
+
+ /* Mask and clear the GPIO interrupt
+ *
+ * "The GPIOIM 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."
+ */
+
+ regval = getreg32(base + LM3S_GPIO_IM_OFFSET);
+ regval &= ~pin;
+ putreg32(regval, base + LM3S_GPIO_IM_OFFSET);
+
+ /* "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."
+ */
+
+ regval = getreg32(base + LM3S_GPIO_ICR_OFFSET);
+ regval |= pin;
+ putreg32(regval, base + LM3S_GPIO_ICR_OFFSET);
+
+ /* Assume rising edge */
+
+ isset = 0; /* Not level sensed */
+ isclr = pin;
+ ibeset = 0; /* Single edge */
+ ibeclr = pin;
+ iveset = pin; /* Rising edge or high levels*/
+ iveclr = 0;
+
+ /* Then handle according to the selected interrupt type */
+
+ switch (inttype)
+ {
+ case 0: /* Interrupt on falling edge */
+ {
+ iveset = 0; /* Falling edge or low levels*/
+ iveclr = pin;
+ }
+ break;
+
+ case 1: /* Interrupt on rising edge */
+ default:
+ break;
+
+ case 2: /* Interrupt on both edges */
+ {
+ ibeset = pin; /* Both edges */
+ ibeclr = 0;
+ }
+ break;
+
+ case 3: /* Interrupt on low level */
+ {
+ isset = pin; /* Level sensed */
+ isclr = 0;
+ iveset = 0; /* Falling edge or low levels*/
+ iveclr = pin;
+ }
+ break;
+
+ case 4: /* Interrupt on high level */
+ {
+ isset = pin; /* Level sensed */
+ isclr = 0;
+ }
+ break;
+ }
+
+ /* "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.
+ */
+
+ regval = getreg32(base + LM3S_GPIO_IS_OFFSET);
+ regval &= isclr;
+ regval |= isset;
+ putreg32(regval, base + LM3S_GPIO_IS_OFFSET);
+
+ /* "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.
+ */
+
+ regval = getreg32(base + LM3S_GPIO_IBE_OFFSET);
+ regval &= ibeclr;
+ regval |= ibeset;
+ putreg32(regval, base + LM3S_GPIO_IBE_OFFSET);
+
+ /* "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.
+ */
+
+ regval = getreg32(base + LM3S_GPIO_IEV_OFFSET);
+ regval &= iveclr;
+ regval |= iveset;
+ putreg32(regval, base + LM3S_GPIO_IEV_OFFSET);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lm3s_configgpio
+ *
+ * Description:
+ * Configure a GPIO pin based on bit-encoded description of the pin.
+ *
+ ****************************************************************************/
+
+int lm3s_configgpio(uint32_t cfgset)
+{
+ irqstate_t flags;
+ unsigned int func;
+ unsigned int port;
+ unsigned int pinno;
+ uint32_t pin;
+ uint32_t base;
+ uint32_t regval;
+
+ /* Decode the basics */
+
+ func = (cfgset & GPIO_FUNC_MASK) >> GPIO_FUNC_SHIFT;
+ port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ pinno = (cfgset & GPIO_NUMBER_MASK);
+ pin = (1 <<pinno);
+
+ DEBUGASSERT(func <= GPIO_FUNC_MAX);
+
+ /* Get the base address associated with the GPIO port */
+
+ base = lm3s_gpiobaseaddress(port);
+ DEBUGASSERT(base != 0);
+
+ /* The following requires exclusive access to the GPIO registers */
+
+ flags = irqsave();
+
+ /* Enable clocking for this GPIO peripheral. "To use the GPIO, the peripheral
+ * clock must be enabled by setting the appropriate GPIO Port bit field (GPIOn)
+ * in the RCGC2 register."
+ */
+
+ regval = getreg32(LM3S_SYSCON_RCGC2);
+ regval |= SYSCON_RCGC2_GPIO(port);
+ putreg32(regval, LM3S_SYSCON_RCGC2);
+
+ /* First, set the port to digital input. This is the safest state in which
+ * to perform reconfiguration.
+ */
+
+ lm3s_gpiofunc(base, pinno, &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.
+ */
+
+ lm3s_gpiopadstrength(base, pin, cfgset);
+ lm3s_gpiopadtype(base, pin, cfgset);
+
+ /* Then set up the real pin function */
+
+ lm3s_gpiofunc(base, pinno, &g_funcbits[func]);
+
+ /* Special GPIO digital output pins */
+
+ if (func == 1 || func == 3)
+ {
+ lm3s_initoutput(cfgset);
+ }
+
+
+ /* Special setup for interrupt GPIO pins */
+
+ else if (func == 7)
+ {
+ lm3s_interrupt(base, pin, cfgset);
+ }
+
+ irqrestore(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: lm3s_gpiowrite
+ *
+ * Description:
+ * Write one or zero to the selected GPIO pin
+ *
+ ****************************************************************************/
+
+void lm3s_gpiowrite(uint32_t pinset, bool value)
+{
+ unsigned int port;
+ unsigned int pinno;
+ uint32_t base;
+
+ /* Decode the basics */
+
+ port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ pinno = (pinset & GPIO_NUMBER_MASK);
+
+ /* Get the base address associated with the GPIO port */
+
+ base = lm3s_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 + LM3S_GPIO_DATA_OFFSET + (1 << (pinno + 2)));
+}
+
+/****************************************************************************
+ * Name: lm3s_gpioread
+ *
+ * Description:
+ * Read one or zero from the selected GPIO pin
+ *
+ ****************************************************************************/
+
+bool lm3s_gpioread(uint32_t pinset, bool value)
+{
+ unsigned int port;
+ unsigned int pinno;
+ uint32_t base;
+
+ /* Decode the basics */
+
+ port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ pinno = (pinset & GPIO_NUMBER_MASK);
+
+ /* Get the base address associated with the GPIO port */
+
+ base = lm3s_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 + LM3S_GPIO_DATA_OFFSET + (1 << (pinno + 2))) != 0);
+}
+
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_gpio.h b/nuttx/arch/arm/src/lm3s/lm3s_gpio.h
new file mode 100644
index 000000000..066666432
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_gpio.h
@@ -0,0 +1,395 @@
+/************************************************************************************
+ * arch/arm/src/lm3s/lm3s_gpio.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_LM3S_LM3S_GPIO_H
+#define __ARCH_ARM_SRC_LM3S_LM3S_GPIO_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* GPIO Register Offsets ************************************************************/
+
+#define LM3S_GPIO_DATA_OFFSET 0x000 /* GPIO Data */
+#define LM3S_GPIO_DIR_OFFSET 0x400 /* GPIO Direction */
+#define LM3S_GPIO_IS_OFFSET 0x404 /* GPIO Interrupt Sense */
+#define LM3S_GPIO_IBE_OFFSET 0x408 /* GPIO Interrupt Both Edges */
+#define LM3S_GPIO_IEV_OFFSET 0x40c /* GPIO Interrupt Event */
+#define LM3S_GPIO_IM_OFFSET 0x410 /* GPIO Interrupt Mask */
+#define LM3S_GPIO_RIS_OFFSET 0x414 /* GPIO Raw Interrupt Status */
+#define LM3S_GPIO_MIS_OFFSET 0x418 /* GPIO Masked Interrupt Status */
+#define LM3S_GPIO_ICR_OFFSET 0x41c /* GPIO Interrupt Clear */
+#define LM3S_GPIO_AFSEL_OFFSET 0x420 /* GPIO Alternate Function */
+#define LM3S_GPIO_DR2R_OFFSET 0x500 /* Select GPIO 2-mA Drive Select */
+#define LM3S_GPIO_DR4R_OFFSET 0x504 /* GPIO 4-mA Drive Select */
+#define LM3S_GPIO_DR8R_OFFSET 0x508 /* GPIO 8-mA Drive Select */
+#define LM3S_GPIO_ODR_OFFSET 0x50c /* GPIO Open Drain Select */
+#define LM3S_GPIO_PUR_OFFSET 0x510 /* GPIO Pull-Up Select */
+#define LM3S_GPIO_PDR_OFFSET 0x514 /* GPIO Pull-Down Select */
+#define LM3S_GPIO_SLR_OFFSET 0x518 /* GPIO Slew Rate Control Select */
+#define LM3S_GPIO_DEN_OFFSET 0x51C /* GPIO Digital Enable */
+#define LM3S_GPIO_LOCK_OFFSET 0x520 /* GPIO Lock */
+#define LM3S_GPIO_CR_OFFSET 0x524 /* GPIO Commit */
+#define LM3S_GPIO_PERIPHID4_OFFSET 0xfd0 /* GPIO Peripheral Identification 4 */
+#define LM3S_GPIO_PERIPHID5_OFFSET 0xfd4 /* GPIO Peripheral Identification 5 */
+#define LM3S_GPIO_PERIPHID6_OFFSET 0xfd8 /* GPIO Peripheral Identification 6 */
+#define LM3S_GPIO_PERIPHID7_OFFSET 0xfdc /* GPIO Peripheral Identification 7 */
+#define LM3S_GPIO_PERIPHID0_OFFSET 0xfe0 /* GPIO Peripheral Identification 0 */
+#define LM3S_GPIO_PERIPHID1_OFFSET 0xfe4 /* GPIO Peripheral Identification 1 */
+#define LM3S_GPIO_PERIPHID2_OFFSET 0xfe8 /* GPIO Peripheral Identification 2 */
+#define LM3S_GPIO_PERIPHID3_OFFSET 0xfec /* GPIO Peripheral Identification 3 */
+#define LM3S_GPIO_PCELLID0_OFFSET 0xff0 /* GPIO PrimeCell Identification 0 */
+#define LM3S_GPIO_PCELLID1_OFFSET 0xff4 /* GPIO PrimeCell Identification 1 */
+#define LM3S_GPIO_PCELLID2_OFFSET 0xff8 /* GPIO PrimeCell Identification 2 */
+#define LM3S_GPIO_PCELLID3_OFFSET 0xffc /* GPIO PrimeCell Identification 3*/
+
+/* GPIO Register Addresses **********************************************************/
+
+#define LM3S_GPIOA_DATA (LM3S_GPIOA_BASE + LM3S_GPIO_DATA_OFFSET)
+#define LM3S_GPIOA_DIR (LM3S_GPIOA_BASE + LM3S_GPIO_DIR_OFFSET)
+#define LM3S_GPIOA_IS (LM3S_GPIOA_BASE + LM3S_GPIO_IS_OFFSET)
+#define LM3S_GPIOA_IBE (LM3S_GPIOA_BASE + LM3S_GPIO_IBE_OFFSET)
+#define LM3S_GPIOA_IEV (LM3S_GPIOA_BASE + LM3S_GPIO_IEV_OFFSET)
+#define LM3S_GPIOA_IM (LM3S_GPIOA_BASE + LM3S_GPIO_IM_OFFSET)
+#define LM3S_GPIOA_RIS (LM3S_GPIOA_BASE + LM3S_GPIO_RIS_OFFSET)
+#define LM3S_GPIOA_MIS (LM3S_GPIOA_BASE + LM3S_GPIO_MIS_OFFSET)
+#define LM3S_GPIOA_ICR (LM3S_GPIOA_BASE + LM3S_GPIO_ICR_OFFSET)
+#define LM3S_GPIOA_AFSEL (LM3S_GPIOA_BASE + LM3S_GPIO_AFSEL_OFFSET)
+#define LM3S_GPIOA_DR2R (LM3S_GPIOA_BASE + LM3S_GPIO_DR2R_OFFSET)
+#define LM3S_GPIOA_DR4R (LM3S_GPIOA_BASE + LM3S_GPIO_DR4R_OFFSET)
+#define LM3S_GPIOA_DR8R (LM3S_GPIOA_BASE + LM3S_GPIO_DR8R_OFFSET)
+#define LM3S_GPIOA_ODR (LM3S_GPIOA_BASE + LM3S_GPIO_ODR_OFFSET)
+#define LM3S_GPIOA_PUR (LM3S_GPIOA_BASE + LM3S_GPIO_PUR_OFFSET)
+#define LM3S_GPIOA_PDR (LM3S_GPIOA_BASE + LM3S_GPIO_PDR_OFFSET)
+#define LM3S_GPIOA_SLR (LM3S_GPIOA_BASE + LM3S_GPIO_SLR_OFFSET)
+#define LM3S_GPIOA_DEN (LM3S_GPIOA_BASE + LM3S_GPIO_DEN_OFFSET)
+#define LM3S_GPIOA_LOCK (LM3S_GPIOA_BASE + LM3S_GPIO_LOCK_OFFSET)
+#define LM3S_GPIOA_CR (LM3S_GPIOA_BASE + LM3S_GPIO_CR_OFFSET)
+#define LM3S_GPIOA_PERIPHID4 (LM3S_GPIOA_BASE + LM3S_GPIO_PERIPHID4_OFFSET)
+#define LM3S_GPIOA_PERIPHID5 (LM3S_GPIOA_BASE + LM3S_GPIO_PERIPHID5_OFFSET)
+#define LM3S_GPIOA_PERIPHID6 (LM3S_GPIOA_BASE + LM3S_GPIO_PERIPHID6_OFFSET)
+#define LM3S_GPIOA_PERIPHID7 (LM3S_GPIOA_BASE + LM3S_GPIO_PERIPHID7_OFFSET)
+#define LM3S_GPIOA_PERIPHID0 (LM3S_GPIOA_BASE + LM3S_GPIO_PERIPHID0_OFFSET)
+#define LM3S_GPIOA_PERIPHID1 (LM3S_GPIOA_BASE + LM3S_GPIO_PERIPHID1_OFFSET)
+#define LM3S_GPIOA_PERIPHID2 (LM3S_GPIOA_BASE + LM3S_GPIO_PERIPHID2_OFFSET)
+#define LM3S_GPIOA_PERIPHID3 (LM3S_GPIOA_BASE + LM3S_GPIO_PERIPHID3_OFFSET)
+#define LM3S_GPIOA_PCELLID0 (LM3S_GPIOA_BASE + LM3S_GPIO_PCELLID0_OFFSET)
+#define LM3S_GPIOA_PCELLID1 (LM3S_GPIOA_BASE + LM3S_GPIO_PCELLID1_OFFSET)
+#define LM3S_GPIOA_PCELLID2 (LM3S_GPIOA_BASE + LM3S_GPIO_PCELLID2_OFFSET)
+#define LM3S_GPIOA_PCELLID3 (LM3S_GPIOA_BASE + LM3S_GPIO_PCELLID3_OFFSET)
+
+#define LM3S_GPIOB_DATA (LM3S_GPIOB_BASE + LM3S_GPIO_DATA_OFFSET)
+#define LM3S_GPIOB_DIR (LM3S_GPIOB_BASE + LM3S_GPIO_DIR_OFFSET)
+#define LM3S_GPIOB_IS (LM3S_GPIOB_BASE + LM3S_GPIO_IS_OFFSET)
+#define LM3S_GPIOB_IBE (LM3S_GPIOB_BASE + LM3S_GPIO_IBE_OFFSET)
+#define LM3S_GPIOB_IEV (LM3S_GPIOB_BASE + LM3S_GPIO_IEV_OFFSET)
+#define LM3S_GPIOB_IM (LM3S_GPIOB_BASE + LM3S_GPIO_IM_OFFSET)
+#define LM3S_GPIOB_RIS (LM3S_GPIOB_BASE + LM3S_GPIO_RIS_OFFSET)
+#define LM3S_GPIOB_MIS (LM3S_GPIOB_BASE + LM3S_GPIO_MIS_OFFSET)
+#define LM3S_GPIOB_ICR (LM3S_GPIOB_BASE + LM3S_GPIO_ICR_OFFSET)
+#define LM3S_GPIOB_AFSEL (LM3S_GPIOB_BASE + LM3S_GPIO_AFSEL_OFFSET)
+#define LM3S_GPIOB_DR2R (LM3S_GPIOB_BASE + LM3S_GPIO_DR2R_OFFSET)
+#define LM3S_GPIOB_DR4R (LM3S_GPIOB_BASE + LM3S_GPIO_DR4R_OFFSET)
+#define LM3S_GPIOB_DR8R (LM3S_GPIOB_BASE + LM3S_GPIO_DR8R_OFFSET)
+#define LM3S_GPIOB_ODR (LM3S_GPIOB_BASE + LM3S_GPIO_ODR_OFFSET)
+#define LM3S_GPIOB_PUR (LM3S_GPIOB_BASE + LM3S_GPIO_PUR_OFFSET)
+#define LM3S_GPIOB_PDR (LM3S_GPIOB_BASE + LM3S_GPIO_PDR_OFFSET)
+#define LM3S_GPIOB_SLR (LM3S_GPIOB_BASE + LM3S_GPIO_SLR_OFFSET)
+#define LM3S_GPIOB_DEN (LM3S_GPIOB_BASE + LM3S_GPIO_DEN_OFFSET)
+#define LM3S_GPIOB_LOCK (LM3S_GPIOB_BASE + LM3S_GPIO_LOCK_OFFSET)
+#define LM3S_GPIOB_CR (LM3S_GPIOB_BASE + LM3S_GPIO_CR_OFFSET)
+#define LM3S_GPIOB_PERIPHID4 (LM3S_GPIOB_BASE + LM3S_GPIO_PERIPHID4_OFFSET)
+#define LM3S_GPIOB_PERIPHID5 (LM3S_GPIOB_BASE + LM3S_GPIO_PERIPHID5_OFFSET)
+#define LM3S_GPIOB_PERIPHID6 (LM3S_GPIOB_BASE + LM3S_GPIO_PERIPHID6_OFFSET)
+#define LM3S_GPIOB_PERIPHID7 (LM3S_GPIOB_BASE + LM3S_GPIO_PERIPHID7_OFFSET)
+#define LM3S_GPIOB_PERIPHID0 (LM3S_GPIOB_BASE + LM3S_GPIO_PERIPHID0_OFFSET)
+#define LM3S_GPIOB_PERIPHID1 (LM3S_GPIOB_BASE + LM3S_GPIO_PERIPHID1_OFFSET)
+#define LM3S_GPIOB_PERIPHID2 (LM3S_GPIOB_BASE + LM3S_GPIO_PERIPHID2_OFFSET)
+#define LM3S_GPIOB_PERIPHID3 (LM3S_GPIOB_BASE + LM3S_GPIO_PERIPHID3_OFFSET)
+#define LM3S_GPIOB_PCELLID0 (LM3S_GPIOB_BASE + LM3S_GPIO_PCELLID0_OFFSET)
+#define LM3S_GPIOB_PCELLID1 (LM3S_GPIOB_BASE + LM3S_GPIO_PCELLID1_OFFSET)
+#define LM3S_GPIOB_PCELLID2 (LM3S_GPIOB_BASE + LM3S_GPIO_PCELLID2_OFFSET)
+#define LM3S_GPIOB_PCELLID3 (LM3S_GPIOB_BASE + LM3S_GPIO_PCELLID3_OFFSET)
+
+#define LM3S_GPIOC_DATA (LM3S_GPIOC_BASE + LM3S_GPIO_DATA_OFFSET)
+#define LM3S_GPIOC_DIR (LM3S_GPIOC_BASE + LM3S_GPIO_DIR_OFFSET)
+#define LM3S_GPIOC_IS (LM3S_GPIOC_BASE + LM3S_GPIO_IS_OFFSET)
+#define LM3S_GPIOC_IBE (LM3S_GPIOC_BASE + LM3S_GPIO_IBE_OFFSET)
+#define LM3S_GPIOC_IEV (LM3S_GPIOC_BASE + LM3S_GPIO_IEV_OFFSET)
+#define LM3S_GPIOC_IM (LM3S_GPIOC_BASE + LM3S_GPIO_IM_OFFSET)
+#define LM3S_GPIOC_RIS (LM3S_GPIOC_BASE + LM3S_GPIO_RIS_OFFSET)
+#define LM3S_GPIOC_MIS (LM3S_GPIOC_BASE + LM3S_GPIO_MIS_OFFSET)
+#define LM3S_GPIOC_ICR (LM3S_GPIOC_BASE + LM3S_GPIO_ICR_OFFSET)
+#define LM3S_GPIOC_AFSEL (LM3S_GPIOC_BASE + LM3S_GPIO_AFSEL_OFFSET)
+#define LM3S_GPIOC_DR2R (LM3S_GPIOC_BASE + LM3S_GPIO_DR2R_OFFSET)
+#define LM3S_GPIOC_DR4R (LM3S_GPIOC_BASE + LM3S_GPIO_DR4R_OFFSET)
+#define LM3S_GPIOC_DR8R (LM3S_GPIOC_BASE + LM3S_GPIO_DR8R_OFFSET)
+#define LM3S_GPIOC_ODR (LM3S_GPIOC_BASE + LM3S_GPIO_ODR_OFFSET)
+#define LM3S_GPIOC_PUR (LM3S_GPIOC_BASE + LM3S_GPIO_PUR_OFFSET)
+#define LM3S_GPIOC_PDR (LM3S_GPIOC_BASE + LM3S_GPIO_PDR_OFFSET)
+#define LM3S_GPIOC_SLR (LM3S_GPIOC_BASE + LM3S_GPIO_SLR_OFFSET)
+#define LM3S_GPIOC_DEN (LM3S_GPIOC_BASE + LM3S_GPIO_DEN_OFFSET)
+#define LM3S_GPIOC_LOCK (LM3S_GPIOC_BASE + LM3S_GPIO_LOCK_OFFSET)
+#define LM3S_GPIOC_CR (LM3S_GPIOC_BASE + LM3S_GPIO_CR_OFFSET)
+#define LM3S_GPIOC_PERIPHID4 (LM3S_GPIOC_BASE + LM3S_GPIO_PERIPHID4_OFFSET)
+#define LM3S_GPIOC_PERIPHID5 (LM3S_GPIOC_BASE + LM3S_GPIO_PERIPHID5_OFFSET)
+#define LM3S_GPIOC_PERIPHID6 (LM3S_GPIOC_BASE + LM3S_GPIO_PERIPHID6_OFFSET)
+#define LM3S_GPIOC_PERIPHID7 (LM3S_GPIOC_BASE + LM3S_GPIO_PERIPHID7_OFFSET)
+#define LM3S_GPIOC_PERIPHID0 (LM3S_GPIOC_BASE + LM3S_GPIO_PERIPHID0_OFFSET)
+#define LM3S_GPIOC_PERIPHID1 (LM3S_GPIOC_BASE + LM3S_GPIO_PERIPHID1_OFFSET)
+#define LM3S_GPIOC_PERIPHID2 (LM3S_GPIOC_BASE + LM3S_GPIO_PERIPHID2_OFFSET)
+#define LM3S_GPIOC_PERIPHID3 (LM3S_GPIOC_BASE + LM3S_GPIO_PERIPHID3_OFFSET)
+#define LM3S_GPIOC_PCELLID0 (LM3S_GPIOC_BASE + LM3S_GPIO_PCELLID0_OFFSET)
+#define LM3S_GPIOC_PCELLID1 (LM3S_GPIOC_BASE + LM3S_GPIO_PCELLID1_OFFSET)
+#define LM3S_GPIOC_PCELLID2 (LM3S_GPIOC_BASE + LM3S_GPIO_PCELLID2_OFFSET)
+#define LM3S_GPIOC_PCELLID3 (LM3S_GPIOC_BASE + LM3S_GPIO_PCELLID3_OFFSET)
+
+#define LM3S_GPIOD_DATA (LM3S_GPIOD_BASE + LM3S_GPIO_DATA_OFFSET)
+#define LM3S_GPIOD_DIR (LM3S_GPIOD_BASE + LM3S_GPIO_DIR_OFFSET)
+#define LM3S_GPIOD_IS (LM3S_GPIOD_BASE + LM3S_GPIO_IS_OFFSET)
+#define LM3S_GPIOD_IBE (LM3S_GPIOD_BASE + LM3S_GPIO_IBE_OFFSET)
+#define LM3S_GPIOD_IEV (LM3S_GPIOD_BASE + LM3S_GPIO_IEV_OFFSET)
+#define LM3S_GPIOD_IM (LM3S_GPIOD_BASE + LM3S_GPIO_IM_OFFSET)
+#define LM3S_GPIOD_RIS (LM3S_GPIOD_BASE + LM3S_GPIO_RIS_OFFSET)
+#define LM3S_GPIOD_MIS (LM3S_GPIOD_BASE + LM3S_GPIO_MIS_OFFSET)
+#define LM3S_GPIOD_ICR (LM3S_GPIOD_BASE + LM3S_GPIO_ICR_OFFSET)
+#define LM3S_GPIOD_AFSEL (LM3S_GPIOD_BASE + LM3S_GPIO_AFSEL_OFFSET)
+#define LM3S_GPIOD_DR2R (LM3S_GPIOD_BASE + LM3S_GPIO_DR2R_OFFSET)
+#define LM3S_GPIOD_DR4R (LM3S_GPIOD_BASE + LM3S_GPIO_DR4R_OFFSET)
+#define LM3S_GPIOD_DR8R (LM3S_GPIOD_BASE + LM3S_GPIO_DR8R_OFFSET)
+#define LM3S_GPIOD_ODR (LM3S_GPIOD_BASE + LM3S_GPIO_ODR_OFFSET)
+#define LM3S_GPIOD_PUR (LM3S_GPIOD_BASE + LM3S_GPIO_PUR_OFFSET)
+#define LM3S_GPIOD_PDR (LM3S_GPIOD_BASE + LM3S_GPIO_PDR_OFFSET)
+#define LM3S_GPIOD_SLR (LM3S_GPIOD_BASE + LM3S_GPIO_SLR_OFFSET)
+#define LM3S_GPIOD_DEN (LM3S_GPIOD_BASE + LM3S_GPIO_DEN_OFFSET)
+#define LM3S_GPIOD_LOCK (LM3S_GPIOD_BASE + LM3S_GPIO_LOCK_OFFSET)
+#define LM3S_GPIOD_CR (LM3S_GPIOD_BASE + LM3S_GPIO_CR_OFFSET)
+#define LM3S_GPIOD_PERIPHID4 (LM3S_GPIOD_BASE + LM3S_GPIO_PERIPHID4_OFFSET)
+#define LM3S_GPIOD_PERIPHID5 (LM3S_GPIOD_BASE + LM3S_GPIO_PERIPHID5_OFFSET)
+#define LM3S_GPIOD_PERIPHID6 (LM3S_GPIOD_BASE + LM3S_GPIO_PERIPHID6_OFFSET)
+#define LM3S_GPIOD_PERIPHID7 (LM3S_GPIOD_BASE + LM3S_GPIO_PERIPHID7_OFFSET)
+#define LM3S_GPIOD_PERIPHID0 (LM3S_GPIOD_BASE + LM3S_GPIO_PERIPHID0_OFFSET)
+#define LM3S_GPIOD_PERIPHID1 (LM3S_GPIOD_BASE + LM3S_GPIO_PERIPHID1_OFFSET)
+#define LM3S_GPIOD_PERIPHID2 (LM3S_GPIOD_BASE + LM3S_GPIO_PERIPHID2_OFFSET)
+#define LM3S_GPIOD_PERIPHID3 (LM3S_GPIOD_BASE + LM3S_GPIO_PERIPHID3_OFFSET)
+#define LM3S_GPIOD_PCELLID0 (LM3S_GPIOD_BASE + LM3S_GPIO_PCELLID0_OFFSET)
+#define LM3S_GPIOD_PCELLID1 (LM3S_GPIOD_BASE + LM3S_GPIO_PCELLID1_OFFSET)
+#define LM3S_GPIOD_PCELLID2 (LM3S_GPIOD_BASE + LM3S_GPIO_PCELLID2_OFFSET)
+#define LM3S_GPIOD_PCELLID3 (LM3S_GPIOD_BASE + LM3S_GPIO_PCELLID3_OFFSET)
+
+#define LM3S_GPIOE_DATA (LM3S_GPIOE_BASE + LM3S_GPIO_DATA_OFFSET)
+#define LM3S_GPIOE_DIR (LM3S_GPIOE_BASE + LM3S_GPIO_DIR_OFFSET)
+#define LM3S_GPIOE_IS (LM3S_GPIOE_BASE + LM3S_GPIO_IS_OFFSET)
+#define LM3S_GPIOE_IBE (LM3S_GPIOE_BASE + LM3S_GPIO_IBE_OFFSET)
+#define LM3S_GPIOE_IEV (LM3S_GPIOE_BASE + LM3S_GPIO_IEV_OFFSET)
+#define LM3S_GPIOE_IM (LM3S_GPIOE_BASE + LM3S_GPIO_IM_OFFSET)
+#define LM3S_GPIOE_RIS (LM3S_GPIOE_BASE + LM3S_GPIO_RIS_OFFSET)
+#define LM3S_GPIOE_MIS (LM3S_GPIOE_BASE + LM3S_GPIO_MIS_OFFSET)
+#define LM3S_GPIOE_ICR (LM3S_GPIOE_BASE + LM3S_GPIO_ICR_OFFSET)
+#define LM3S_GPIOE_AFSEL (LM3S_GPIOE_BASE + LM3S_GPIO_AFSEL_OFFSET)
+#define LM3S_GPIOE_DR2R (LM3S_GPIOE_BASE + LM3S_GPIO_DR2R_OFFSET)
+#define LM3S_GPIOE_DR4R (LM3S_GPIOE_BASE + LM3S_GPIO_DR4R_OFFSET)
+#define LM3S_GPIOE_DR8R (LM3S_GPIOE_BASE + LM3S_GPIO_DR8R_OFFSET)
+#define LM3S_GPIOE_ODR (LM3S_GPIOE_BASE + LM3S_GPIO_ODR_OFFSET)
+#define LM3S_GPIOE_PUR (LM3S_GPIOE_BASE + LM3S_GPIO_PUR_OFFSET)
+#define LM3S_GPIOE_PDR (LM3S_GPIOE_BASE + LM3S_GPIO_PDR_OFFSET)
+#define LM3S_GPIOE_SLR (LM3S_GPIOE_BASE + LM3S_GPIO_SLR_OFFSET)
+#define LM3S_GPIOE_DEN (LM3S_GPIOE_BASE + LM3S_GPIO_DEN_OFFSET)
+#define LM3S_GPIOE_LOCK (LM3S_GPIOE_BASE + LM3S_GPIO_LOCK_OFFSET)
+#define LM3S_GPIOE_CR (LM3S_GPIOE_BASE + LM3S_GPIO_CR_OFFSET)
+#define LM3S_GPIOE_PERIPHID4 (LM3S_GPIOE_BASE + LM3S_GPIO_PERIPHID4_OFFSET)
+#define LM3S_GPIOE_PERIPHID5 (LM3S_GPIOE_BASE + LM3S_GPIO_PERIPHID5_OFFSET)
+#define LM3S_GPIOE_PERIPHID6 (LM3S_GPIOE_BASE + LM3S_GPIO_PERIPHID6_OFFSET)
+#define LM3S_GPIOE_PERIPHID7 (LM3S_GPIOE_BASE + LM3S_GPIO_PERIPHID7_OFFSET)
+#define LM3S_GPIOE_PERIPHID0 (LM3S_GPIOE_BASE + LM3S_GPIO_PERIPHID0_OFFSET)
+#define LM3S_GPIOE_PERIPHID1 (LM3S_GPIOE_BASE + LM3S_GPIO_PERIPHID1_OFFSET)
+#define LM3S_GPIOE_PERIPHID2 (LM3S_GPIOE_BASE + LM3S_GPIO_PERIPHID2_OFFSET)
+#define LM3S_GPIOE_PERIPHID3 (LM3S_GPIOE_BASE + LM3S_GPIO_PERIPHID3_OFFSET)
+#define LM3S_GPIOE_PCELLID0 (LM3S_GPIOE_BASE + LM3S_GPIO_PCELLID0_OFFSET)
+#define LM3S_GPIOE_PCELLID1 (LM3S_GPIOE_BASE + LM3S_GPIO_PCELLID1_OFFSET)
+#define LM3S_GPIOE_PCELLID2 (LM3S_GPIOE_BASE + LM3S_GPIO_PCELLID2_OFFSET)
+#define LM3S_GPIOE_PCELLID3 (LM3S_GPIOE_BASE + LM3S_GPIO_PCELLID3_OFFSET)
+
+#define LM3S_GPIOF_DATA (LM3S_GPIOF_BASE + LM3S_GPIO_DATA_OFFSET)
+#define LM3S_GPIOF_DIR (LM3S_GPIOF_BASE + LM3S_GPIO_DIR_OFFSET)
+#define LM3S_GPIOF_IS (LM3S_GPIOF_BASE + LM3S_GPIO_IS_OFFSET)
+#define LM3S_GPIOF_IBE (LM3S_GPIOF_BASE + LM3S_GPIO_IBE_OFFSET)
+#define LM3S_GPIOF_IEV (LM3S_GPIOF_BASE + LM3S_GPIO_IEV_OFFSET)
+#define LM3S_GPIOF_IM (LM3S_GPIOF_BASE + LM3S_GPIO_IM_OFFSET)
+#define LM3S_GPIOF_RIS (LM3S_GPIOF_BASE + LM3S_GPIO_RIS_OFFSET)
+#define LM3S_GPIOF_MIS (LM3S_GPIOF_BASE + LM3S_GPIO_MIS_OFFSET)
+#define LM3S_GPIOF_ICR (LM3S_GPIOF_BASE + LM3S_GPIO_ICR_OFFSET)
+#define LM3S_GPIOF_AFSEL (LM3S_GPIOF_BASE + LM3S_GPIO_AFSEL_OFFSET)
+#define LM3S_GPIOF_DR2R (LM3S_GPIOF_BASE + LM3S_GPIO_DR2R_OFFSET)
+#define LM3S_GPIOF_DR4R (LM3S_GPIOF_BASE + LM3S_GPIO_DR4R_OFFSET)
+#define LM3S_GPIOF_DR8R (LM3S_GPIOF_BASE + LM3S_GPIO_DR8R_OFFSET)
+#define LM3S_GPIOF_ODR (LM3S_GPIOF_BASE + LM3S_GPIO_ODR_OFFSET)
+#define LM3S_GPIOF_PUR (LM3S_GPIOF_BASE + LM3S_GPIO_PUR_OFFSET)
+#define LM3S_GPIOF_PDR (LM3S_GPIOF_BASE + LM3S_GPIO_PDR_OFFSET)
+#define LM3S_GPIOF_SLR (LM3S_GPIOF_BASE + LM3S_GPIO_SLR_OFFSET)
+#define LM3S_GPIOF_DEN (LM3S_GPIOF_BASE + LM3S_GPIO_DEN_OFFSET)
+#define LM3S_GPIOF_LOCK (LM3S_GPIOF_BASE + LM3S_GPIO_LOCK_OFFSET)
+#define LM3S_GPIOF_CR (LM3S_GPIOF_BASE + LM3S_GPIO_CR_OFFSET)
+#define LM3S_GPIOF_PERIPHID4 (LM3S_GPIOF_BASE + LM3S_GPIO_PERIPHID4_OFFSET)
+#define LM3S_GPIOF_PERIPHID5 (LM3S_GPIOF_BASE + LM3S_GPIO_PERIPHID5_OFFSET)
+#define LM3S_GPIOF_PERIPHID6 (LM3S_GPIOF_BASE + LM3S_GPIO_PERIPHID6_OFFSET)
+#define LM3S_GPIOF_PERIPHID7 (LM3S_GPIOF_BASE + LM3S_GPIO_PERIPHID7_OFFSET)
+#define LM3S_GPIOF_PERIPHID0 (LM3S_GPIOF_BASE + LM3S_GPIO_PERIPHID0_OFFSET)
+#define LM3S_GPIOF_PERIPHID1 (LM3S_GPIOF_BASE + LM3S_GPIO_PERIPHID1_OFFSET)
+#define LM3S_GPIOF_PERIPHID2 (LM3S_GPIOF_BASE + LM3S_GPIO_PERIPHID2_OFFSET)
+#define LM3S_GPIOF_PERIPHID3 (LM3S_GPIOF_BASE + LM3S_GPIO_PERIPHID3_OFFSET)
+#define LM3S_GPIOF_PCELLID0 (LM3S_GPIOF_BASE + LM3S_GPIO_PCELLID0_OFFSET)
+#define LM3S_GPIOF_PCELLID1 (LM3S_GPIOF_BASE + LM3S_GPIO_PCELLID1_OFFSET)
+#define LM3S_GPIOF_PCELLID2 (LM3S_GPIOF_BASE + LM3S_GPIO_PCELLID2_OFFSET)
+#define LM3S_GPIOF_PCELLID3 (LM3S_GPIOF_BASE + LM3S_GPIO_PCELLID3_OFFSET)
+
+#define LM3S_GPIOG_DATA (LM3S_GPIOG_BASE + LM3S_GPIO_DATA_OFFSET)
+#define LM3S_GPIOG_DIR (LM3S_GPIOG_BASE + LM3S_GPIO_DIR_OFFSET)
+#define LM3S_GPIOG_IS (LM3S_GPIOG_BASE + LM3S_GPIO_IS_OFFSET)
+#define LM3S_GPIOG_IBE (LM3S_GPIOG_BASE + LM3S_GPIO_IBE_OFFSET)
+#define LM3S_GPIOG_IEV (LM3S_GPIOG_BASE + LM3S_GPIO_IEV_OFFSET)
+#define LM3S_GPIOG_IM (LM3S_GPIOG_BASE + LM3S_GPIO_IM_OFFSET)
+#define LM3S_GPIOG_RIS (LM3S_GPIOG_BASE + LM3S_GPIO_RIS_OFFSET)
+#define LM3S_GPIOG_MIS (LM3S_GPIOG_BASE + LM3S_GPIO_MIS_OFFSET)
+#define LM3S_GPIOG_ICR (LM3S_GPIOG_BASE + LM3S_GPIO_ICR_OFFSET)
+#define LM3S_GPIOG_AFSEL (LM3S_GPIOG_BASE + LM3S_GPIO_AFSEL_OFFSET)
+#define LM3S_GPIOG_DR2R (LM3S_GPIOG_BASE + LM3S_GPIO_DR2R_OFFSET)
+#define LM3S_GPIOG_DR4R (LM3S_GPIOG_BASE + LM3S_GPIO_DR4R_OFFSET)
+#define LM3S_GPIOG_DR8R (LM3S_GPIOG_BASE + LM3S_GPIO_DR8R_OFFSET)
+#define LM3S_GPIOG_ODR (LM3S_GPIOG_BASE + LM3S_GPIO_ODR_OFFSET)
+#define LM3S_GPIOG_PUR (LM3S_GPIOG_BASE + LM3S_GPIO_PUR_OFFSET)
+#define LM3S_GPIOG_PDR (LM3S_GPIOG_BASE + LM3S_GPIO_PDR_OFFSET)
+#define LM3S_GPIOG_SLR (LM3S_GPIOG_BASE + LM3S_GPIO_SLR_OFFSET)
+#define LM3S_GPIOG_DEN (LM3S_GPIOG_BASE + LM3S_GPIO_DEN_OFFSET)
+#define LM3S_GPIOG_LOCK (LM3S_GPIOG_BASE + LM3S_GPIO_LOCK_OFFSET)
+#define LM3S_GPIOG_CR (LM3S_GPIOG_BASE + LM3S_GPIO_CR_OFFSET)
+#define LM3S_GPIOG_PERIPHID4 (LM3S_GPIOG_BASE + LM3S_GPIO_PERIPHID4_OFFSET)
+#define LM3S_GPIOG_PERIPHID5 (LM3S_GPIOG_BASE + LM3S_GPIO_PERIPHID5_OFFSET)
+#define LM3S_GPIOG_PERIPHID6 (LM3S_GPIOG_BASE + LM3S_GPIO_PERIPHID6_OFFSET)
+#define LM3S_GPIOG_PERIPHID7 (LM3S_GPIOG_BASE + LM3S_GPIO_PERIPHID7_OFFSET)
+#define LM3S_GPIOG_PERIPHID0 (LM3S_GPIOG_BASE + LM3S_GPIO_PERIPHID0_OFFSET)
+#define LM3S_GPIOG_PERIPHID1 (LM3S_GPIOG_BASE + LM3S_GPIO_PERIPHID1_OFFSET)
+#define LM3S_GPIOG_PERIPHID2 (LM3S_GPIOG_BASE + LM3S_GPIO_PERIPHID2_OFFSET)
+#define LM3S_GPIOG_PERIPHID3 (LM3S_GPIOG_BASE + LM3S_GPIO_PERIPHID3_OFFSET)
+#define LM3S_GPIOG_PCELLID0 (LM3S_GPIOG_BASE + LM3S_GPIO_PCELLID0_OFFSET)
+#define LM3S_GPIOG_PCELLID1 (LM3S_GPIOG_BASE + LM3S_GPIO_PCELLID1_OFFSET)
+#define LM3S_GPIOG_PCELLID2 (LM3S_GPIOG_BASE + LM3S_GPIO_PCELLID2_OFFSET)
+#define LM3S_GPIOG_PCELLID3 (LM3S_GPIOG_BASE + LM3S_GPIO_PCELLID3_OFFSET)
+
+#define LM3S_GPIOH_DATA (LM3S_GPIOH_BASE + LM3S_GPIO_DATA_OFFSET)
+#define LM3S_GPIOH_DIR (LM3S_GPIOH_BASE + LM3S_GPIO_DIR_OFFSET)
+#define LM3S_GPIOH_IS (LM3S_GPIOH_BASE + LM3S_GPIO_IS_OFFSET)
+#define LM3S_GPIOH_IBE (LM3S_GPIOH_BASE + LM3S_GPIO_IBE_OFFSET)
+#define LM3S_GPIOH_IEV (LM3S_GPIOH_BASE + LM3S_GPIO_IEV_OFFSET)
+#define LM3S_GPIOH_IM (LM3S_GPIOH_BASE + LM3S_GPIO_IM_OFFSET)
+#define LM3S_GPIOH_RIS (LM3S_GPIOH_BASE + LM3S_GPIO_RIS_OFFSET)
+#define LM3S_GPIOH_MIS (LM3S_GPIOH_BASE + LM3S_GPIO_MIS_OFFSET)
+#define LM3S_GPIOH_ICR (LM3S_GPIOH_BASE + LM3S_GPIO_ICR_OFFSET)
+#define LM3S_GPIOH_AFSEL (LM3S_GPIOH_BASE + LM3S_GPIO_AFSEL_OFFSET)
+#define LM3S_GPIOH_DR2R (LM3S_GPIOH_BASE + LM3S_GPIO_DR2R_OFFSET)
+#define LM3S_GPIOH_DR4R (LM3S_GPIOH_BASE + LM3S_GPIO_DR4R_OFFSET)
+#define LM3S_GPIOH_DR8R (LM3S_GPIOH_BASE + LM3S_GPIO_DR8R_OFFSET)
+#define LM3S_GPIOH_ODR (LM3S_GPIOH_BASE + LM3S_GPIO_ODR_OFFSET)
+#define LM3S_GPIOH_PUR (LM3S_GPIOH_BASE + LM3S_GPIO_PUR_OFFSET)
+#define LM3S_GPIOH_PDR (LM3S_GPIOH_BASE + LM3S_GPIO_PDR_OFFSET)
+#define LM3S_GPIOH_SLR (LM3S_GPIOH_BASE + LM3S_GPIO_SLR_OFFSET)
+#define LM3S_GPIOH_DEN (LM3S_GPIOH_BASE + LM3S_GPIO_DEN_OFFSET)
+#define LM3S_GPIOH_LOCK (LM3S_GPIOH_BASE + LM3S_GPIO_LOCK_OFFSET)
+#define LM3S_GPIOH_CR (LM3S_GPIOH_BASE + LM3S_GPIO_CR_OFFSET)
+#define LM3S_GPIOH_PERIPHID4 (LM3S_GPIOH_BASE + LM3S_GPIO_PERIPHID4_OFFSET)
+#define LM3S_GPIOH_PERIPHID5 (LM3S_GPIOH_BASE + LM3S_GPIO_PERIPHID5_OFFSET)
+#define LM3S_GPIOH_PERIPHID6 (LM3S_GPIOH_BASE + LM3S_GPIO_PERIPHID6_OFFSET)
+#define LM3S_GPIOH_PERIPHID7 (LM3S_GPIOH_BASE + LM3S_GPIO_PERIPHID7_OFFSET)
+#define LM3S_GPIOH_PERIPHID0 (LM3S_GPIOH_BASE + LM3S_GPIO_PERIPHID0_OFFSET)
+#define LM3S_GPIOH_PERIPHID1 (LM3S_GPIOH_BASE + LM3S_GPIO_PERIPHID1_OFFSET)
+#define LM3S_GPIOH_PERIPHID2 (LM3S_GPIOH_BASE + LM3S_GPIO_PERIPHID2_OFFSET)
+#define LM3S_GPIOH_PERIPHID3 (LM3S_GPIOH_BASE + LM3S_GPIO_PERIPHID3_OFFSET)
+#define LM3S_GPIOH_PCELLID0 (LM3S_GPIOH_BASE + LM3S_GPIO_PCELLID0_OFFSET)
+#define LM3S_GPIOH_PCELLID1 (LM3S_GPIOH_BASE + LM3S_GPIO_PCELLID1_OFFSET)
+#define LM3S_GPIOH_PCELLID2 (LM3S_GPIOH_BASE + LM3S_GPIO_PCELLID2_OFFSET)
+#define LM3S_GPIOH_PCELLID3 (LM3S_GPIOH_BASE + LM3S_GPIO_PCELLID3_OFFSET)
+
+#define LM3S_GPIOJ_DATA (LM3S_GPIOJ_BASE + LM3S_GPIO_DATA_OFFSET)
+#define LM3S_GPIOJ_DIR (LM3S_GPIOJ_BASE + LM3S_GPIO_DIR_OFFSET)
+#define LM3S_GPIOJ_IS (LM3S_GPIOJ_BASE + LM3S_GPIO_IS_OFFSET)
+#define LM3S_GPIOJ_IBE (LM3S_GPIOJ_BASE + LM3S_GPIO_IBE_OFFSET)
+#define LM3S_GPIOJ_IEV (LM3S_GPIOJ_BASE + LM3S_GPIO_IEV_OFFSET)
+#define LM3S_GPIOJ_IM (LM3S_GPIOJ_BASE + LM3S_GPIO_IM_OFFSET)
+#define LM3S_GPIOJ_RIS (LM3S_GPIOJ_BASE + LM3S_GPIO_RIS_OFFSET)
+#define LM3S_GPIOJ_MIS (LM3S_GPIOJ_BASE + LM3S_GPIO_MIS_OFFSET)
+#define LM3S_GPIOJ_ICR (LM3S_GPIOJ_BASE + LM3S_GPIO_ICR_OFFSET)
+#define LM3S_GPIOJ_AFSEL (LM3S_GPIOJ_BASE + LM3S_GPIO_AFSEL_OFFSET)
+#define LM3S_GPIOJ_DR2R (LM3S_GPIOJ_BASE + LM3S_GPIO_DR2R_OFFSET)
+#define LM3S_GPIOJ_DR4R (LM3S_GPIOJ_BASE + LM3S_GPIO_DR4R_OFFSET)
+#define LM3S_GPIOJ_DR8R (LM3S_GPIOJ_BASE + LM3S_GPIO_DR8R_OFFSET)
+#define LM3S_GPIOJ_ODR (LM3S_GPIOJ_BASE + LM3S_GPIO_ODR_OFFSET)
+#define LM3S_GPIOJ_PUR (LM3S_GPIOJ_BASE + LM3S_GPIO_PUR_OFFSET)
+#define LM3S_GPIOJ_PDR (LM3S_GPIOJ_BASE + LM3S_GPIO_PDR_OFFSET)
+#define LM3S_GPIOJ_SLR (LM3S_GPIOJ_BASE + LM3S_GPIO_SLR_OFFSET)
+#define LM3S_GPIOJ_DEN (LM3S_GPIOJ_BASE + LM3S_GPIO_DEN_OFFSET)
+#define LM3S_GPIOJ_LOCK (LM3S_GPIOJ_BASE + LM3S_GPIO_LOCK_OFFSET)
+#define LM3S_GPIOJ_CR (LM3S_GPIOJ_BASE + LM3S_GPIO_CR_OFFSET)
+#define LM3S_GPIOJ_PERIPHID4 (LM3S_GPIOJ_BASE + LM3S_GPIO_PERIPHID4_OFFSET)
+#define LM3S_GPIOJ_PERIPHID5 (LM3S_GPIOJ_BASE + LM3S_GPIO_PERIPHID5_OFFSET)
+#define LM3S_GPIOJ_PERIPHID6 (LM3S_GPIOJ_BASE + LM3S_GPIO_PERIPHID6_OFFSET)
+#define LM3S_GPIOJ_PERIPHID7 (LM3S_GPIOJ_BASE + LM3S_GPIO_PERIPHID7_OFFSET)
+#define LM3S_GPIOJ_PERIPHID0 (LM3S_GPIOJ_BASE + LM3S_GPIO_PERIPHID0_OFFSET)
+#define LM3S_GPIOJ_PERIPHID1 (LM3S_GPIOJ_BASE + LM3S_GPIO_PERIPHID1_OFFSET)
+#define LM3S_GPIOJ_PERIPHID2 (LM3S_GPIOJ_BASE + LM3S_GPIO_PERIPHID2_OFFSET)
+#define LM3S_GPIOJ_PERIPHID3 (LM3S_GPIOJ_BASE + LM3S_GPIO_PERIPHID3_OFFSET)
+#define LM3S_GPIOJ_PCELLID0 (LM3S_GPIOJ_BASE + LM3S_GPIO_PCELLID0_OFFSET)
+#define LM3S_GPIOJ_PCELLID1 (LM3S_GPIOJ_BASE + LM3S_GPIO_PCELLID1_OFFSET)
+#define LM3S_GPIOJ_PCELLID2 (LM3S_GPIOJ_BASE + LM3S_GPIO_PCELLID2_OFFSET)
+#define LM3S_GPIOJ_PCELLID3 (LM3S_GPIOJ_BASE + LM3S_GPIO_PCELLID3_OFFSET)
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Function Prototypes
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LM3S_LM3S_GPIO_H */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_gpioirq.c b/nuttx/arch/arm/src/lm3s/lm3s_gpioirq.c
new file mode 100644
index 000000000..7cc5fea40
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_gpioirq.c
@@ -0,0 +1,433 @@
+/****************************************************************************
+ * arch/arm/src/lm3s/lm3s_gpioirq.c
+ * arch/arm/src/chip/lm3s_gpioirq.c
+ *
+ * Copyright (C) 2009-2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#include "up_arch.h"
+#include "os_internal.h"
+#include "irq_internal.h"
+#include "lm3s_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* A table of handlers for each GPIO interrupt */
+
+static FAR xcpt_t g_gpioirqvector[NR_GPIO_IRQS];
+
+/* A table that maps a GPIO group to a GPIO base address. Overly complicated
+ * because we support disabling interrupt support for arbitrary ports. This
+ * must carefully match the IRQ numbers assigned in arch/arm/include/lm3s/irq.h
+ */
+
+static const uint32_t g_gpiobase[] =
+{
+#ifndef CONFIG_LM3S_DISABLE_GPIOA_IRQS
+ LM3S_GPIOA_BASE,
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOB_IRQS
+ LM3S_GPIOB_BASE,
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOC_IRQS
+ LM3S_GPIOC_BASE,
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOD_IRQS
+ LM3S_GPIOD_BASE,
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOE_IRQS
+ LM3S_GPIOE_BASE,
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOF_IRQS
+ LM3S_GPIOF_BASE,
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOG_IRQS
+ LM3S_GPIOG_BASE,
+#endif
+
+ /* NOTE: Not all LM3S architectures support GPIOs above GPIOG. If the chip
+ * does not support these higher ports, then they must be disabled in the
+ * configuration. Otherwise, the following will likely cause compilation
+ * errors!
+ */
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOH_IRQS
+ LM3S_GPIOH_BASE,
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOJ_IRQS
+ LM3S_GPIOJ_BASE,
+#endif
+};
+
+#define GPIO_NADDRS (sizeof(g_gpiobase)/sizeof(uint32_t))
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lm3s_gpiobaseaddress
+ *
+ * Input:
+ * gpioirq - A pin number in the range of 0 to NR_GPIO_IRQS.
+ *
+ * Description:
+ * Given a GPIO enumeration value, return the base address of the
+ * associated GPIO registers. NOTE that range checking was provided by
+ * callee
+ *
+ ****************************************************************************/
+
+static uint32_t lm3s_gpiobaseaddress(unsigned int gpioirq)
+{
+ unsigned int ndx = gpioirq >> 3;
+ if (ndx < GPIO_NADDRS)
+ {
+ return g_gpiobase[ndx];
+ }
+ return 0;
+}
+
+/****************************************************************************
+ * Name: lm3s_gpio*handler
+ *
+ * Description:
+ * Handle interrupts on each enabled GPIO port
+ *
+ ****************************************************************************/
+
+static int lm3s_gpiohandler(uint32_t regbase, int irqbase, void *context)
+{
+ uint32_t mis;
+ int irq;
+ int pin;
+
+ /* Handle each pending GPIO interrupt. "The GPIO MIS register is the masked
+ * interrupt status register. Bits read High in GPIO MIS reflect the status
+ * of input lines triggering an interrupt. Bits read as Low indicate that
+ * either no interrupt has been generated, or the interrupt is masked."
+ */
+
+ mis = getreg32(regbase + LM3S_GPIO_MIS_OFFSET) & 0xff;
+
+ /* Clear all GPIO interrupts that we are going to process. "The GPIO ICR
+ * 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."
+ */
+
+ putreg32(mis, regbase + LM3S_GPIO_ICR_OFFSET);
+
+ /* Now process each IRQ pending in the MIS */
+
+ for (pin = 0; pin < 8 && mis != 0; pin++, mis >>= 1)
+ {
+ if ((mis & 1) != 0)
+ {
+ irq = irqbase + pin;
+ g_gpioirqvector[irq - NR_IRQS](irq, context);
+ }
+ }
+ return OK;
+}
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOA_IRQS
+static int lm3s_gpioahandler(int irq, FAR void *context)
+{
+ return lm3s_gpiohandler(LM3S_GPIOA_BASE, LM3S_IRQ_GPIOA_0, context);
+}
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOB_IRQS
+static int lm3s_gpiobhandler(int irq, FAR void *context)
+{
+ return lm3s_gpiohandler(LM3S_GPIOB_BASE, LM3S_IRQ_GPIOB_0, context);
+}
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOC_IRQS
+static int lm3s_gpiochandler(int irq, FAR void *context)
+{
+ return lm3s_gpiohandler(LM3S_GPIOC_BASE, LM3S_IRQ_GPIOC_0, context);
+}
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOD_IRQS
+static int lm3s_gpiodhandler(int irq, FAR void *context)
+{
+ return lm3s_gpiohandler(LM3S_GPIOD_BASE, LM3S_IRQ_GPIOD_0, context);
+}
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOE_IRQS
+static int lm3s_gpioehandler(int irq, FAR void *context)
+{
+ return lm3s_gpiohandler(LM3S_GPIOE_BASE, LM3S_IRQ_GPIOE_0, context);
+}
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOF_IRQS
+static int lm3s_gpiofhandler(int irq, FAR void *context)
+{
+ return lm3s_gpiohandler(LM3S_GPIOF_BASE, LM3S_IRQ_GPIOF_0, context);
+}
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOG_IRQS
+static int lm3s_gpioghandler(int irq, FAR void *context)
+{
+ return lm3s_gpiohandler(LM3S_GPIOG_BASE, LM3S_IRQ_GPIOG_0, context);
+}
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOH_IRQS
+static int lm3s_gpiohhandler(int irq, FAR void *context)
+{
+ return lm3s_gpiohandler(LM3S_GPIOH_BASE, LM3S_IRQ_GPIOH_0, context);
+}
+#endif
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOJ_IRQS
+static int lm3s_gpiojhandler(int irq, FAR void *context)
+{
+ return lm3s_gpiohandler(LM3S_GPIOJ_BASE, LM3S_IRQ_GPIOJ_0, context);
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gpio_irqinitialize
+ *
+ * Description:
+ * Initialize all vectors to the unexpected interrupt handler
+ *
+ ****************************************************************************/
+
+int gpio_irqinitialize(void)
+{
+ int i;
+
+ /* Point all interrupt vectors to the unexpected interrupt */
+
+ for (i = 0; i < NR_GPIO_IRQS; i++)
+ {
+ g_gpioirqvector[i] = irq_unexpected_isr;
+ }
+
+ /* Then attach each GPIO interrupt handlers and enable corresponding GPIO
+ * interrupts
+ */
+
+#ifndef CONFIG_LM3S_DISABLE_GPIOA_IRQS
+ irq_attach(LM3S_IRQ_GPIOA, lm3s_gpioahandler);
+ up_enable_irq(LM3S_IRQ_GPIOA);
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOB_IRQS
+ irq_attach(LM3S_IRQ_GPIOB, lm3s_gpiobhandler);
+ up_enable_irq(LM3S_IRQ_GPIOB);
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOC_IRQS
+ irq_attach(LM3S_IRQ_GPIOC, lm3s_gpiochandler);
+ up_enable_irq(LM3S_IRQ_GPIOC);
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOD_IRQS
+ irq_attach(LM3S_IRQ_GPIOD, lm3s_gpiodhandler);
+ up_enable_irq(LM3S_IRQ_GPIOD);
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOE_IRQS
+ irq_attach(LM3S_IRQ_GPIOE, lm3s_gpioehandler);
+ up_enable_irq(LM3S_IRQ_GPIOE);
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOF_IRQS
+ irq_attach(LM3S_IRQ_GPIOF, lm3s_gpiofhandler);
+ up_enable_irq(LM3S_IRQ_GPIOF);
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOG_IRQS
+ irq_attach(LM3S_IRQ_GPIOG, lm3s_gpioghandler);
+ up_enable_irq(LM3S_IRQ_GPIOG);
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOH_IRQS
+ irq_attach(LM3S_IRQ_GPIOH, lm3s_gpiohhandler);
+ up_enable_irq(LM3S_IRQ_GPIOH);
+#endif
+#ifndef CONFIG_LM3S_DISABLE_GPIOJ_IRQS
+ irq_attach(LM3S_IRQ_GPIOJ, lm3s_gpiojhandler);
+ up_enable_irq(LM3S_IRQ_GPIOJ);
+#endif
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: gpio_irqattach
+ *
+ * Description:
+ * Attach in GPIO interrupt to the provide 'isr'
+ *
+ ****************************************************************************/
+
+int gpio_irqattach(int irq, xcpt_t isr)
+{
+ irqstate_t flags;
+ int gpioirq = irq - NR_IRQS;
+ int ret = ERROR;
+
+ if ((unsigned)gpioirq < NR_GPIO_IRQS)
+ {
+ flags = irqsave();
+
+ /* 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.
+ */
+
+ if (isr == NULL)
+ {
+#ifndef CONFIG_ARCH_NOINTC
+ gpio_irqdisable(gpioirq);
+#endif
+ isr = irq_unexpected_isr;
+ }
+
+ /* Save the new ISR in the table. */
+
+ g_irqvector[gpioirq] = isr;
+ irqrestore(flags);
+ ret = OK;
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * Name: gpio_irqenable
+ *
+ * Description:
+ * Enable the GPIO IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void gpio_irqenable(int irq)
+{
+ irqstate_t flags;
+ int gpioirq = irq - NR_IRQS;
+ uint32_t base;
+ uint32_t regval;
+ int pin;
+
+ if ((unsigned)gpioirq < NR_GPIO_IRQS)
+ {
+ /* Get the base address of the GPIO module associated with this IRQ */
+
+ base = lm3s_gpiobaseaddress(gpioirq);
+ DEBUGASSERT(base != 0);
+ pin = (1 << (gpioirq & 7));
+
+ /* 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.
+ */
+
+ flags = irqsave();
+ regval = getreg32(base + LM3S_GPIO_IM_OFFSET);
+ regval |= pin;
+ putreg32(regval, base + LM3S_GPIO_IM_OFFSET);
+ irqrestore(flags);
+ }
+}
+
+/****************************************************************************
+ * Name: gpio_irqdisable
+ *
+ * Description:
+ * Disable the GPIO IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void gpio_irqdisable(int irq)
+{
+ irqstate_t flags;
+ int gpioirq = irq - NR_IRQS;
+ uint32_t base;
+ uint32_t regval;
+ int pin;
+
+ if ((unsigned)gpioirq < NR_GPIO_IRQS)
+ {
+ /* Get the base address of the GPIO module associated with this IRQ */
+
+ base = lm3s_gpiobaseaddress(gpioirq);
+ DEBUGASSERT(base != 0);
+ pin = (1 << (gpioirq & 7));
+
+ /* 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.
+ */
+
+ flags = irqsave();
+ regval = getreg32(base + LM3S_GPIO_IM_OFFSET);
+ regval &= ~pin;
+ putreg32(regval, base + LM3S_GPIO_IM_OFFSET);
+ irqrestore(flags);
+ }
+}
+
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_i2c.h b/nuttx/arch/arm/src/lm3s/lm3s_i2c.h
new file mode 100644
index 000000000..a5f0567b9
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_i2c.h
@@ -0,0 +1,247 @@
+/************************************************************************************
+ * arch/arm/src/lm3s/lm3s_i2c.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_LM3S_LM3S_I2C_H
+#define __ARCH_ARM_SRC_LM3S_LM3S_I2C_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* I2C Register Offsets *************************************************************/
+
+/* I2C Master */
+
+#define LM3S_I2CM_SA_OFFSET 0x000 /* I2C Master Slave Address */
+#define LM3S_I2CM_CS_OFFSET 0x004 /* I2C Master Control/Status */
+#define LM3S_I2CM_DR_OFFSET 0x008 /* I2C Master Data */
+#define LM3S_I2CM_TPR_OFFSET 0x00c /* I2C Master Timer Period */
+#define LM3S_I2CM_IMR_OFFSET 0x010 /* I2C Master Interrupt Mask */
+#define LM3S_I2CM_RIS_OFFSET 0x014 /* I2C Master Raw Interrupt Status */
+#define LM3S_I2CM_MIS_OFFSET 0x018 /* I2C Master Masked Interrupt Status */
+#define LM3S_I2CM_ICR_OFFSET 0x01c /* I2C Master Interrupt Clear */
+#define LM3S_I2CM_CR_OFFSET 0x020 /* I2C Master Configuration */
+
+/* I2C Slave */
+
+#define LM3S_I2CS_OAR_OFFSET 0x000 /* I2C Slave Own Address */
+#define LM3S_I2CS_CSR_OFFSET 0x004 /* I2C Slave Control/Status */
+#define LM3S_I2CS_DR_OFFSET 0x008 /* I2C Slave Data */
+#define LM3S_I2CS_IMR_OFFSET 0x00c /* I2C Slave Interrupt Mask */
+#define LM3S_I2CS_RIS_OFFSET 0x010 /* I2C Slave Raw Interrupt Status */
+#define LM3S_I2CS_MIS_OFFSET 0x014 /* I2C Slave Masked Interrupt Status */
+#define LM3S_I2CS_ICR_OFFSET 0x018 /* I2C Slave Interrupt Clear */
+
+/* I2C Register Addresses ***********************************************************/
+
+#if LM3S_NI2C > 0
+
+/* I2C Master */
+
+#define LM3S_I2CM_BASE(n) (LM3S_I2CM0_BASE + (n)*0x1000)
+#define LM3S_I2CM_SA(n) (LM3S_I2CM_BASE(n) + LM3S_I2CM_SA_OFFSET)
+#define LM3S_I2CM_CS(n) (LM3S_I2CM_BASE(n) + LM3S_I2CM_CS_OFFSET)
+#define LM3S_I2CM_DR(n) (LM3S_I2CM_BASE(n) + LM3S_I2CM_DR_OFFSET)
+#define LM3S_I2CM_TPR(n) (LM3S_I2CM_BASE(n) + LM3S_I2CM_TPR_OFFSET)
+#define LM3S_I2CM_IMR(n) (LM3S_I2CM_BASE(n) + LM3S_I2CM_IMR_OFFSET)
+#define LM3S_I2CM_RIS(n) (LM3S_I2CM_BASE(n) + LM3S_I2CM_RIS_OFFSET)
+#define LM3S_I2CM_MIS(n) (LM3S_I2CM_BASE(n) + LM3S_I2CM_MIS_OFFSET)
+#define LM3S_I2CM_ICR(n) (LM3S_I2CM_BASE(n) + LM3S_I2CM_ICR_OFFSET)
+#define LM3S_I2CM_CR(n) (LM3S_I2CM_BASE(n) + LM3S_I2CM_CR_OFFSET)
+
+/* I2C Slave */
+
+#define LM3S_I2CS_BASE(n) (LM3S_I2CS0_BASE + (n)*0x1000)
+#define LM3S_I2CS_OAR(n) (LM3S_I2CS_BASE(n) + LM3S_I2CS_OAR_OFFSET)
+#define LM3S_I2CS_CSR(n) (LM3S_I2CS_BASE(n) + LM3S_I2CS_CSR_OFFSET)
+#define LM3S_I2CS_DR(n) (LM3S_I2CS_BASE(n) + LM3S_I2CS_DR_OFFSET)
+#define LM3S_I2CS_IMR(n) (LM3S_I2CS_BASE(n) + LM3S_I2CS_IMR_OFFSET)
+#define LM3S_I2CS_RIS(n) (LM3S_I2CS_BASE(n) + LM3S_I2CS_RIS_OFFSET)
+#define LM3S_I2CS_MIS(n) (LM3S_I2CS_BASE(n) + LM3S_I2CS_MIS_OFFSET)
+#define LM3S_I2CS_ICR(n) (LM3S_I2CS_BASE(n) + LM3S_I2CS_ICR_OFFSET)
+
+/* I2C0 Master */
+
+#define LM3S_I2CM0_SA (LM3S_I2CM0_BASE + LM3S_I2CM_SA_OFFSET)
+#define LM3S_I2CM0_CS (LM3S_I2CM0_BASE + LM3S_I2CM_CS_OFFSET)
+#define LM3S_I2CM0_DR (LM3S_I2CM0_BASE + LM3S_I2CM_DR_OFFSET)
+#define LM3S_I2CM0_TPR (LM3S_I2CM0_BASE + LM3S_I2CM_TPR_OFFSET)
+#define LM3S_I2CM0_IMR (LM3S_I2CM0_BASE + LM3S_I2CM_IMR_OFFSET)
+#define LM3S_I2CM0_RIS (LM3S_I2CM0_BASE + LM3S_I2CM_RIS_OFFSET)
+#define LM3S_I2CM0_MIS (LM3S_I2CM0_BASE + LM3S_I2CM_MIS_OFFSET)
+#define LM3S_I2CM0_ICR (LM3S_I2CM0_BASE + LM3S_I2CM_ICR_OFFSET)
+#define LM3S_I2CM0_CR (LM3S_I2CM0_BASE + LM3S_I2CM_CR_OFFSET)
+
+/* I2C0 Slave */
+
+#define LM3S_I2CS0_OAR (LM3S_I2CS0_BASE + LM3S_I2CS_OAR_OFFSET)
+#define LM3S_I2CS0_CSR (LM3S_I2CS0_BASE + LM3S_I2CS_CSR_OFFSET)
+#define LM3S_I2CS0_DR (LM3S_I2CS0_BASE + LM3S_I2CS_DR_OFFSET)
+#define LM3S_I2CS0_IMR (LM3S_I2CS0_BASE + LM3S_I2CS_IMR_OFFSET)
+#define LM3S_I2CS0_RIS (LM3S_I2CS0_BASE + LM3S_I2CS_RIS_OFFSET)
+#define LM3S_I2CS0_MIS (LM3S_I2CS0_BASE + LM3S_I2CS_MIS_OFFSET)
+#define LM3S_I2CS0_ICR (LM3S_I2CS0_BASE + LM3S_I2CS_ICR_OFFSET)
+
+#if LM3S_NI2C > 1
+
+/* I2C1 Master */
+
+#define LM3S_I2CM1_SA (LM3S_I2CM1_BASE + LM3S_I2CM_SA_OFFSET)
+#define LM3S_I2CM1_CS (LM3S_I2CM1_BASE + LM3S_I2CM_CS_OFFSET)
+#define LM3S_I2CM1_DR (LM3S_I2CM1_BASE + LM3S_I2CM_DR_OFFSET)
+#define LM3S_I2CM1_TPR (LM3S_I2CM1_BASE + LM3S_I2CM_TPR_OFFSET)
+#define LM3S_I2CM1_IMR (LM3S_I2CM1_BASE + LM3S_I2CM_IMR_OFFSET)
+#define LM3S_I2CM1_RIS (LM3S_I2CM1_BASE + LM3S_I2CM_RIS_OFFSET)
+#define LM3S_I2CM1_MIS (LM3S_I2CM1_BASE + LM3S_I2CM_MIS_OFFSET)
+#define LM3S_I2CM1_ICR (LM3S_I2CM1_BASE + LM3S_I2CM_ICR_OFFSET)
+#define LM3S_I2CM1_CR (LM3S_I2CM1_BASE + LM3S_I2CM_CR_OFFSET)
+
+/* I2C1 Slave */
+
+#define LM3S_I2CS1_OAR (LM3S_I2CS1_BASE + LM3S_I2CS_OAR_OFFSET)
+#define LM3S_I2CS1_CSR (LM3S_I2CS1_BASE + LM3S_I2CS_CSR_OFFSET)
+#define LM3S_I2CS1_DR (LM3S_I2CS1_BASE + LM3S_I2CS_DR_OFFSET)
+#define LM3S_I2CS1_IMR (LM3S_I2CS1_BASE + LM3S_I2CS_IMR_OFFSET)
+#define LM3S_I2CS1_RIS (LM3S_I2CS1_BASE + LM3S_I2CS_RIS_OFFSET)
+#define LM3S_I2CS1_MIS (LM3S_I2CS1_BASE + LM3S_I2CS_MIS_OFFSET)
+#define LM3S_I2CS1_ICR (LM3S_I2CS1_BASE + LM3S_I2CS_ICR_OFFSET)
+
+#endif
+#endif
+
+/* I2C_Register Bit Definitions *****************************************************/
+
+/* I2C Master Slave Address (I2CM_SA), offset 0x000 */
+
+#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), offset 0x004 */
+
+#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) */
+
+#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) */
+
+/* I2C Master Data (I2CM_DR), offset 0x008 */
+
+#define I2CM_DR_MASK 0xff /* Bits 7-0: Data transferred */
+
+/* I2C Master Timer Period (I2CM_TPR), offset 0x00c */
+
+#define I2CM_TPR_MASK 0xff /* Bits 7-0: SCL Clock Period */
+
+/* I2C Master Interrupt Mask (I2CM_IMR), offset 0x010 */
+
+#define I2CM_IMR_IM (1 << 0) /* Bit 0: Interrupt Mask */
+
+/* I2C Master Raw Interrupt Status (I2CM_RIS), offset 0x014 */
+
+#define I2CM_RIS_RIS (1 << 0) /* Bit 0: Raw Interrupt Status */
+
+/* I2C Master Masked Interrupt Status (I2CM_MIS), offset 0x018 */
+
+#define I2CM_MIS_MIS (1 << 0) /* Bit 0: Masked Interrupt Status */
+
+/* I2C Master Masked Interrupt Status (I2CM_ICR), offset 0x01c */
+
+#define I2CM_ICR_IC (1 << 0) /* Bit 0: Masked Interrupt Status */
+
+/* I2C Master Configuration (I2CM_CR), offset 0x020 */
+
+#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 */
+
+/* I2C Slave Own Address (I2CS_OAR), offset 0x000 */
+
+#define I2CS_OAR_MASK 0xff /* Bits 7-0: I2C Slave Own Address */
+
+/* I2C Slave Control/Status (I2CS_CSR), offset 0x004 */
+
+#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) */
+
+#define I2CS_CSR_DA (1 << 0) /* Bit 0: Device Active (write) */
+
+/* I2C Slave Data (I2CS_DR), offset 0x008 */
+
+#define I2CS_DR_MASK 0xff /* Bits 7-0: Data for Transfer */
+
+/* I2C Slave Interrupt Mask (I2CS_IMR), offset 0x00c */
+
+#define I2CM_IMR_DATAIM (1 << 0) /* Bit 0: Data Interrupt Mask */
+
+/* I2C Slave Raw Interrupt Status (I2CS_RIS), offset 0x010 */
+
+#define I2CM_RIS_DATARIS (1 << 0) /* Bit 0: Data Raw Interrupt Status */
+
+/* I2C Slave Masked Interrupt Status (I2CS_MIS), offset 0x014 */
+
+#define I2CM_MIS_DATAMIS (1 << 0) /* Bit 0: Data Masked Interrupt Status */
+
+/* I2C Slave Interrupt Clear (I2CS_ICR), offset 0x018 */
+
+#define I2CM_ICR_DATAIC (1 << 0) /* Bit 0: Data Interrupt Clear */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LM3S_LM3S_I2C_H */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_internal.h b/nuttx/arch/arm/src/lm3s/lm3s_internal.h
new file mode 100644
index 000000000..9bfd67a5e
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_internal.h
@@ -0,0 +1,546 @@
+/************************************************************************************
+ * arch/arm/src/lm3s/lm3s_internal.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_LM3S_LM3S_INTERNAL_H
+#define __ARCH_ARM_SRC_LM3S_LM3S_INTERNAL_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "up_internal.h"
+#include "chip.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* The LM3S69xx 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 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 /* 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 */
+
+/* Bit-encoded input to lm3s_configgpio() *******************************************/
+
+/* Encoding:
+ * FFFS SPPP IIIn nnnn nnnn nnnn VPPP PBBB
+ *
+ * These bits set the primary function of the pin:
+ * FFFn nnnn nnnn nnnn nnnn nnnn nnnn nnnn
+ */
+
+#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 (Comparator) */
+#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
+ * nnnS SPPP nnnn nnnn nnnn nnnn nnnn nnnn
+ */
+
+#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
+ * nnnn nnnn IIIn nnnn nnnn nnnn nnnn nnnn
+ */
+
+#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 */
+
+/* If the pin is an GPIO digital output, then this identifies the initial output value:
+ * nnnn nnnn nnnn nnnn nnnn nnnn Vnnn nnnn
+ */
+
+#define GPIO_VALUE_SHIFT 7 /* Bit 7: 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
+ * nnnn nnnn nnnn nnnn nnnn nnnn nPPP Pnnn
+ */
+
+#define GPIO_PORT_SHIFT 3 /* Bit 3-6: 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_PORTJ (8 << GPIO_PORT_SHIFT) /* GPIOJ */
+
+/* This identifies the bit in the port:
+ * nnnn nnnn nnnn nnnn nnnn nnnn nnnn nBBB
+ */
+
+#define GPIO_NUMBER_SHIFT 0 /* Bits 0-2: GPIO number: 0-7 */
+#define GPIO_NUMBER_MASK (7 << GPIO_NUMBER_SHIFT)
+
+/* The following lists the input value to lm3s_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_PFODIO | 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_PFODIO | 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 LM3S chip"
+#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: up_lowsetup
+ *
+ * Description:
+ * Called at the very beginning of _start. Performs low level initialization.
+ *
+ ****************************************************************************/
+
+EXTERN void up_lowsetup(void);
+
+/****************************************************************************
+ * Name: lm3s_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.
+ *
+ ****************************************************************************/
+
+EXTERN void lm3s_clockconfig(uint32_t newrcc, uint32_t newrcc2);
+
+/****************************************************************************
+ * Name: up_clockconfig
+ *
+ * Description:
+ * Called early in the bootsequence (before .data and .bss are available)
+ * in order to configure initial clocking.
+ *
+ ****************************************************************************/
+
+EXTERN void up_clockconfig(void);
+
+/****************************************************************************
+ * Name: lm3s_configgpio
+ *
+ * Description:
+ * Configure a GPIO pin based on bit-encoded description of the pin.
+ *
+ ****************************************************************************/
+
+EXTERN int lm3s_configgpio(uint32_t cfgset);
+
+/****************************************************************************
+ * Name: lm3s_gpiowrite
+ *
+ * Description:
+ * Write one or zero to the selected GPIO pin
+ *
+ ****************************************************************************/
+
+EXTERN void lm3s_gpiowrite(uint32_t pinset, bool value);
+
+/****************************************************************************
+ * Name: lm3s_gpioread
+ *
+ * Description:
+ * Read one or zero from the selected GPIO pin
+ *
+ ****************************************************************************/
+
+EXTERN bool lm3s_gpioread(uint32_t pinset, bool value);
+
+/****************************************************************************
+ * Function: lm3s_dumpgpio
+ *
+ * Description:
+ * Dump all GPIO registers associated with the provided base address
+ *
+ ****************************************************************************/
+
+EXTERN int lm3s_dumpgpio(uint32_t pinset, const char *msg);
+
+/****************************************************************************
+ * Name: gpio_irqinitialize
+ *
+ * Description:
+ * Initialize all vectors to the unexpected interrupt handler
+ *
+ ****************************************************************************/
+
+EXTERN int weak_function gpio_irqinitialize(void);
+
+/****************************************************************************
+ * Function: lm3s_ethinitialize
+ *
+ * Description:
+ * Initialize the Ethernet driver for one interface. If the LM3S 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 LM3S_NETHCONTROLLERS > 1
+EXTERN int lm3s_ethinitialize(int intf);
+#endif
+
+/****************************************************************************
+ * The external functions, lm3s_spiselect, lm3s_spistatus, and
+ * lm3s_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.h).
+ * All other methods (including up_spiinitialize()) are provided by common
+ * logic. To use this common SPI logic on your board:
+ *
+ * 1. Provide logic in lm3s_boardinitialize() to configure SPI chip select
+ * pins.
+ * 2. Provide lm3s_spiselect() and lm3s_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 your NuttX configuration, provide
+ * the lm3s_spicmddata() 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 up_spiinitialize() in your low level application
+ * initialization logic
+ * 5. The handle returned by up_spiinitialize() 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;
+EXTERN void lm3s_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t lm3s_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+#ifdef CONFIG_SPI_CMDDATA
+EXTERN int lm3s_spicmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+#endif
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_LM3S_LM3S_INTERNAL_H */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_irq.c b/nuttx/arch/arm/src/lm3s/lm3s_irq.c
new file mode 100644
index 000000000..aa0ed6c87
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_irq.c
@@ -0,0 +1,456 @@
+/****************************************************************************
+ * arch/arm/src/lm3s/lm3s_irq.c
+ * arch/arm/src/chip/lm3s_irq.c
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "nvic.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+#include "lm3s_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Enable NVIC debug features that are probably only desireable during
+ * bringup
+ */
+
+#undef LM3S_IRQ_DEBUG
+
+/* 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
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lm3s_dumpnvic
+ *
+ * Description:
+ * Dump some interesting NVIC registers
+ *
+ ****************************************************************************/
+
+#if defined(LM3S_IRQ_DEBUG) && defined (CONFIG_DEBUG)
+static void lm3s_dumpnvic(const char *msg, int irq)
+{
+ irqstate_t flags;
+
+ flags = irqsave();
+ slldbg("NVIC (%s, irq=%d):\n", msg, irq);
+ slldbg(" INTCTRL: %08x VECTAB: %08x\n",
+ getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB));
+#if 0
+ slldbg(" 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
+ slldbg(" IRQ ENABLE: %08x %08x\n",
+ getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE));
+ slldbg(" SYSH_PRIO: %08x %08x %08x\n",
+ getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY),
+ getreg32(NVIC_SYSH12_15_PRIORITY));
+ slldbg(" 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));
+ slldbg(" %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));
+ slldbg(" %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));
+ irqrestore(flags);
+}
+#else
+# define lm3s_dumpnvic(msg, irq)
+#endif
+
+/****************************************************************************
+ * Name: lm3s_nmi, lm3s_busfault, lm3s_usagefault, lm3s_pendsv,
+ * lm3s_dbgmonitor, lm3s_pendsv, lm3s_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 lm3s_nmi(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! NMI received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lm3s_busfault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Bus fault recived\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lm3s_usagefault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Usage fault received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lm3s_pendsv(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! PendSV received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lm3s_dbgmonitor(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Debug Monitor receieved\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lm3s_reserved(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Reserved interrupt\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: lm3s_irqinfo
+ *
+ * Description:
+ * Given an IRQ number, provide the register and bit setting to enable or
+ * disable the irq.
+ *
+ ****************************************************************************/
+
+static int lm3s_irqinfo(int irq, uint32_t *regaddr, uint32_t *bit)
+{
+ DEBUGASSERT(irq >= LM3S_IRQ_NMI && irq < NR_IRQS);
+
+ /* Check for external interrupt */
+
+ if (irq >= LM3S_IRQ_INTERRUPTS)
+ {
+ if (irq < LM3S_IRQ_INTERRUPTS + 32)
+ {
+ *regaddr = NVIC_IRQ0_31_ENABLE;
+ *bit = 1 << (irq - LM3S_IRQ_INTERRUPTS);
+ }
+ else if (irq < NR_IRQS)
+ {
+ *regaddr = NVIC_IRQ32_63_ENABLE;
+ *bit = 1 << (irq - LM3S_IRQ_INTERRUPTS - 32);
+ }
+ else
+ {
+ return ERROR; /* Invalid interrupt */
+ }
+ }
+
+ /* Handler processor exceptions. Only a few can be disabled */
+
+ else
+ {
+ *regaddr = NVIC_SYSHCON;
+ if (irq == LM3S_IRQ_MEMFAULT)
+ {
+ *bit = NVIC_SYSHCON_MEMFAULTENA;
+ }
+ else if (irq == LM3S_IRQ_BUSFAULT)
+ {
+ *bit = NVIC_SYSHCON_BUSFAULTENA;
+ }
+ else if (irq == LM3S_IRQ_USAGEFAULT)
+ {
+ *bit = NVIC_SYSHCON_USGFAULTENA;
+ }
+ else if (irq == LM3S_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)
+{
+ /* Disable all interrupts */
+
+ putreg32(0, NVIC_IRQ0_31_ENABLE);
+ putreg32(0, NVIC_IRQ32_63_ENABLE);
+
+ /* Set all interrrupts (and exceptions) to the default priority */
+
+ putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);
+
+ putreg32(DEFPRIORITY32, NVIC_IRQ0_3_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ4_7_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ8_11_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ12_15_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ16_19_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ20_23_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ24_27_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ28_31_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ32_35_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ36_39_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ40_43_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ44_47_PRIORITY);
+
+ /* currents_regs is non-NULL only while processing an interrupt */
+
+ current_regs = NULL;
+
+ /* Initialize support for GPIO interrupts if included in this build */
+
+#ifndef CONFIG_LM3S_DISABLE_GPIO_IRQS
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (gpio_irqinitialize != NULL)
+#endif
+ {
+ gpio_irqinitialize();
+ }
+#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(LM3S_IRQ_SVCALL, up_svcall);
+ irq_attach(LM3S_IRQ_HARDFAULT, up_hardfault);
+
+ /* Set the priority of the SVCall interrupt */
+
+#ifdef CONFIG_ARCH_IRQPRIO
+/* up_prioritize_irq(LM3S_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
+#endif
+
+ /* If the MPU is enabled, then attach and enable the Memory Management
+ * Fault handler.
+ */
+
+#ifdef CONFIG_ARMV7M_MPU
+ irq_attach(LM3S_IRQ_MEMFAULT, up_memfault);
+ up_enable_irq(LM3S_IRQ_MEMFAULT);
+#endif
+
+ /* Attach all other processor exceptions (except reset and sys tick) */
+
+#ifdef CONFIG_DEBUG
+ irq_attach(LM3S_IRQ_NMI, lm3s_nmi);
+#ifndef CONFIG_ARMV7M_MPU
+ irq_attach(LM3S_IRQ_MEMFAULT, up_memfault);
+#endif
+ irq_attach(LM3S_IRQ_BUSFAULT, lm3s_busfault);
+ irq_attach(LM3S_IRQ_USAGEFAULT, lm3s_usagefault);
+ irq_attach(LM3S_IRQ_PENDSV, lm3s_pendsv);
+ irq_attach(LM3S_IRQ_DBGMONITOR, lm3s_dbgmonitor);
+ irq_attach(LM3S_IRQ_RESERVED, lm3s_reserved);
+#endif
+
+ lm3s_dumpnvic("initial", NR_IRQS);
+
+#ifndef CONFIG_SUPPRESS_INTERRUPTS
+
+ /* And finally, enable interrupts */
+
+ setbasepri(NVIC_SYSH_PRIORITY_MAX);
+ irqrestore(0);
+#endif
+}
+
+/****************************************************************************
+ * Name: up_disable_irq
+ *
+ * Description:
+ * Disable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_disable_irq(int irq)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (lm3s_irqinfo(irq, &regaddr, &bit) == 0)
+ {
+ /* Clear the appropriate bit in the register to enable the interrupt */
+
+ regval = getreg32(regaddr);
+ regval &= ~bit;
+ putreg32(regval, regaddr);
+ }
+ lm3s_dumpnvic("disable", irq);
+}
+
+/****************************************************************************
+ * Name: up_enable_irq
+ *
+ * Description:
+ * Enable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_enable_irq(int irq)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (lm3s_irqinfo(irq, &regaddr, &bit) == 0)
+ {
+ /* Set the appropriate bit in the register to enable the interrupt */
+
+ regval = getreg32(regaddr);
+ regval |= bit;
+ putreg32(regval, regaddr);
+ }
+ lm3s_dumpnvic("enable", irq);
+}
+
+/****************************************************************************
+ * Name: up_maskack_irq
+ *
+ * Description:
+ * Mask the IRQ and acknowledge it
+ *
+ ****************************************************************************/
+
+void up_maskack_irq(int irq)
+{
+ up_disable_irq(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 >= LM3S_IRQ_MEMFAULT && irq < NR_IRQS && (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
+
+ if (irq < LM3S_IRQ_INTERRUPTS)
+ {
+ irq -= 4;
+ regaddr = NVIC_SYSH_PRIORITY(irq);
+ }
+ else
+ {
+ irq -= LM3S_IRQ_INTERRUPTS;
+ regaddr = NVIC_IRQ_PRIORITY(irq);
+ }
+
+ regval = getreg32(regaddr);
+ shift = ((irq & 3) << 3);
+ regval &= ~(0xff << shift);
+ regval |= (priority << shift);
+ putreg32(regval, regaddr);
+
+ lm3s_dumpnvic("prioritize", irq);
+ return OK;
+}
+#endif
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_lowputc.c b/nuttx/arch/arm/src/lm3s/lm3s_lowputc.c
new file mode 100644
index 000000000..69ac56a9d
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_lowputc.c
@@ -0,0 +1,308 @@
+/**************************************************************************
+ * arch/arm/src/lm3s/lm3s_lowputc.c
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <stdint.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "lm3s_internal.h"
+
+/**************************************************************************
+ * Pre-processor Definitions
+ **************************************************************************/
+
+/* Configuration **********************************************************/
+
+#if LM3S_NUARTS < 2
+# undef CONFIG_UART1_DISABLE
+# undef CONFIG_UART1_SERIAL_CONSOLE
+# define CONFIG_UART1_DISABLE 1
+#endif
+
+#if LM3S_NUARTS < 3
+# undef CONFIG_UART2_DISABLE
+# undef CONFIG_UART2_SERIAL_CONSOLE
+# define CONFIG_UART2_DISABLE 1
+#endif
+
+/* Is there a serial console? */
+
+#if defined(CONFIG_UART0_SERIAL_CONSOLE) && !defined(CONFIG_UART0_DISABLE)
+# undef CONFIG_UART1_SERIAL_CONSOLE
+# undef CONFIG_UART2_SERIAL_CONSOLE
+# define HAVE_CONSOLE 1
+#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && !defined(CONFIG_UART1_DISABLE)
+# undef CONFIG_UART0_SERIAL_CONSOLE
+# undef CONFIG_UART2_SERIAL_CONSOLE
+# define HAVE_CONSOLE 1
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && !defined(CONFIG_UART2_DISABLE)
+# undef CONFIG_UART0_SERIAL_CONSOLE
+# undef CONFIG_UART1_SERIAL_CONSOLE
+# define HAVE_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 HAVE_CONSOLE
+#endif
+
+/* Select UART parameters for the selected console */
+
+#if defined(CONFIG_UART0_SERIAL_CONSOLE)
+# define LM3S_CONSOLE_BASE LM3S_UART0_BASE
+# define LM3S_CONSOLE_BAUD CONFIG_UART0_BAUD
+# define LM3S_CONSOLE_BITS CONFIG_UART0_BITS
+# define LM3S_CONSOLE_PARITY CONFIG_UART0_PARITY
+# define LM3S_CONSOLE_2STOP CONFIG_UART0_2STOP
+#elif defined(CONFIG_UART1_SERIAL_CONSOLE)
+# define LM3S_CONSOLE_BASE LM3S_UART1_BASE
+# define LM3S_CONSOLE_BAUD CONFIG_UART1_BAUD
+# define LM3S_CONSOLE_BITS CONFIG_UART1_BITS
+# define LM3S_CONSOLE_PARITY CONFIG_UART1_PARITY
+# define LM3S_CONSOLE_2STOP CONFIG_UART1_2STOP
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE)
+# define LM3S_CONSOLE_BASE LM3S_UART2_BASE
+# define LM3S_CONSOLE_BAUD CONFIG_UART2_BAUD
+# define LM3S_CONSOLE_BITS CONFIG_UART2_BITS
+# define LM3S_CONSOLE_PARITY CONFIG_UART2_PARITY
+# define LM3S_CONSOLE_2STOP CONFIG_UART2_2STOP
+#else
+# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting"
+#endif
+
+/* Get LCRH settings */
+
+#if LM3S_CONSOLE_BITS == 5
+# define UART_LCRH_NBITS UART_LCRH_WLEN_5BITS
+#elif LM3S_CONSOLE_BITS == 6
+# define UART_LCRH_NBITS UART_LCRH_WLEN_6BITS
+#elif LM3S_CONSOLE_BITS == 7
+# define UART_LCRH_NBITS UART_LCRH_WLEN_7BITS
+#elif LM3S_CONSOLE_BITS == 8
+# define UART_LCRH_NBITS UART_LCRH_WLEN_8BITS
+#else
+# error "Number of bits not supported"
+#endif
+
+#if LM3S_CONSOLE_PARITY == 0
+# define UART_LCRH_PARITY (0)
+#elif LM3S_CONSOLE_PARITY == 1
+# define UART_LCRH_PARITY UART_LCRH_PEN
+#elif LM3S_CONSOLE_PARITY == 2
+# define UART_LCRH_PARITY (UART_LCRH_PEN|UART_LCRH_EPS)
+#else
+# error "Invalid parity selection"
+#endif
+
+#if LM3S_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 LM3S_BRDDEN (16 * LM3S_CONSOLE_BAUD)
+#define LM3S_BRDI (SYSCLK_FREQUENCY / LM3S_BRDDEN)
+#define LM3S_REMAINDER (SYSCLK_FREQUENCY - LM3S_BRDDEN * LM3S_BRDI)
+#define LM3S_DIVFRAC ((LM3S_REMAINDER * 64 + (LM3S_BRDDEN/2)) / LM3S_BRDDEN)
+
+/* For example: LM3S_CONSOLE_BAUD = 115,200, SYSCLK_FREQUENCY = 50,000,000:
+ *
+ * LM3S_BRDDEN = (16 * 115,200) = 1,843,200
+ * LM3S_BRDI = 50,000,000 / 1,843,200 = 27
+ * LM3S_REMAINDER = 50,000,000 - 1,843,200 * 27 = 233,600
+ * LM3S_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
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * 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 FIFO is not full */
+
+ while ((getreg32(LM3S_CONSOLE_BASE+LM3S_UART_FR_OFFSET) & UART_FR_TXFF) != 0);
+
+ /* Then send the character */
+
+ putreg32((uint32_t)ch, LM3S_CONSOLE_BASE+LM3S_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)
+{
+ uint32_t regval;
+#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG)
+ uint32_t ctl;
+#endif
+
+ /* Enable the selected UARTs and configure GPIO pins to need by the
+ * the selected UARTs. NOTE: The serial driver later depends on
+ * this pin configuration -- whether or not a serial console is selected.
+ */
+
+#ifndef CONFIG_UART0_DISABLE
+ regval = getreg32(LM3S_SYSCON_RCGC1);
+ regval |= SYSCON_RCGC1_UART0;
+ putreg32(regval, LM3S_SYSCON_RCGC1);
+
+ lm3s_configgpio(GPIO_UART0_RX);
+ lm3s_configgpio(GPIO_UART0_TX);
+#endif
+
+#ifndef CONFIG_UART1_DISABLE
+ regval = getreg32(LM3S_SYSCON_RCGC1);
+ regval |= SYSCON_RCGC1_UART1;
+ putreg32(regval, LM3S_SYSCON_RCGC1);
+
+ lm3s_configgpio(GPIO_UART1_RX);
+ lm3s_configgpio(GPIO_UART1_TX);
+#endif
+
+ /* Enable the selected console device */
+
+#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG)
+ /* Disable the UART by clearing the UARTEN bit in the UART CTL register */
+
+ ctl = getreg32(LM3S_CONSOLE_BASE+LM3S_UART_CTL_OFFSET);
+ ctl &= ~UART_CTL_UARTEN;
+ putreg32(ctl, LM3S_CONSOLE_BASE+LM3S_UART_CTL_OFFSET);
+
+ /* Write the integer portion of the BRD to the UART IBRD register */
+
+ putreg32(LM3S_BRDI, LM3S_CONSOLE_BASE+LM3S_UART_IBRD_OFFSET);
+
+ /* Write the fractional portion of the BRD to the UART FBRD register */
+
+ putreg32(LM3S_DIVFRAC, LM3S_CONSOLE_BASE+LM3S_UART_FBRD_OFFSET);
+
+ /* Write the desired serial parameters to the UART LCRH register */
+
+ putreg32(UART_LCRH_VALUE, LM3S_CONSOLE_BASE+LM3S_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, LM3S_CONSOLE_BASE+LM3S_UART_CTL_OFFSET);
+#endif
+
+}
+
+
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_memorymap.h b/nuttx/arch/arm/src/lm3s/lm3s_memorymap.h
new file mode 100644
index 000000000..be0d8b58d
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_memorymap.h
@@ -0,0 +1,360 @@
+/************************************************************************************
+ * arch/arm/src/lm3s/lm3s_memorymap.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_LM3S_LM3S_MEMORYMAP_H
+#define __ARCH_ARM_SRC_LM3S_LM3S_MEMORYMAP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+/************************************************************************************
+ * 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 LM3S_FLASH_BASE 0x00000000 /* -0x0003ffff: On-chip FLASH */
+ /* -0x1fffffff: Reserved */
+# define LM3S_SRAM_BASE 0x20000000 /* -0x2000ffff: Bit-banded on-chip SRAM */
+ /* -0x21ffffff: Reserved */
+# define LM3S_ASRAM_BASE 0x22000000 /* -0x221fffff: Bit-band alias of 20000000- */
+ /* -0x3fffffff: Reserved */
+# define LM3S_PERIPH_BASE 0x40000000 /* -0x4001ffff: FiRM Peripherals */
+ /* -0x41ffffff: Peripherals */
+# define LM3S_APERIPH_BASE 0x42000000 /* -0x43ffffff: Bit-band alise of 40000000- */
+ /* -0xdfffffff: Reserved */
+# define LM3S_ITM_BASE 0xe0000000 /* -0xe0000fff: Instrumentation Trace Macrocell */
+# define LM3S_DWT_BASE 0xe0001000 /* -0xe0001fff: Data Watchpoint and Trace */
+# define LM3S_FPB_BASE 0xe0002000 /* -0xe0002fff: Flash Patch and Breakpoint */
+ /* -0xe000dfff: Reserved */
+# define LM3S_NVIC_BASE 0xe000e000 /* -0xe000efff: Nested Vectored Interrupt Controller */
+ /* -0xe003ffff: Reserved */
+# define LM3S_TPIU_BASE 0xe0040000 /* -0xe0040fff: Trace Port Interface Unit */
+ /* -0xffffffff: Reserved */
+#elif defined(CONFIG_ARCH_CHIP_LM3S9B96)
+# define LM3S_FLASH_BASE 0x00000000 /* -0x0003ffff: On-chip FLASH */
+ /* -0x1fffffff: Reserved */
+# define LM3S_SRAM_BASE 0x20000000 /* -0x2000ffff: Bit-banded on-chip SRAM */
+ /* -0x21ffffff: Reserved */
+# define LM3S_ASRAM_BASE 0x22000000 /* -0x221fffff: Bit-band alias of 20000000- */
+ /* -0x3fffffff: Reserved */
+# define LM3S_PERIPH_BASE 0x40000000 /* -0x4001ffff: FiRM Peripherals */
+ /* -0x41ffffff: Peripherals */
+# define LM3S_APERIPH_BASE 0x42000000 /* -0x43ffffff: Bit-band alise of 40000000- */
+ /* -0x5fffffff: Reserved */
+# define LM3S_EPI0RAM_BASE 0x60000000 /* -0xDfffffff: EPI0 mapped peripheral and RAM */
+# define LM3S_ITM_BASE 0xe0000000 /* -0xe0000fff: Instrumentation Trace Macrocell */
+# define LM3S_DWT_BASE 0xe0001000 /* -0xe0001fff: Data Watchpoint and Trace */
+# define LM3S_FPB_BASE 0xe0002000 /* -0xe0002fff: Flash Patch and Breakpoint */
+ /* -0xe000dfff: Reserved */
+# define LM3S_NVIC_BASE 0xe000e000 /* -0xe000efff: Nested Vectored Interrupt Controller */
+ /* -0xe003ffff: Reserved */
+# define LM3S_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 LM3S_WDOG_BASE (LM3S_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer */
+ /* -0x03fff: Reserved */
+# define LM3S_GPIOA_BASE (LM3S_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */
+# define LM3S_GPIOB_BASE (LM3S_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */
+# define LM3S_GPIOC_BASE (LM3S_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */
+# define LM3S_GPIOD_BASE (LM3S_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */
+# define LM3S_SSI0_BASE (LM3S_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */
+# define LM3S_SSI1_BASE (LM3S_PERIPH_BASE + 0x09000) /* -0x09fff: SSI1 */
+ /* -0x0bfff: Reserved */
+# define LM3S_UART0_BASE (LM3S_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */
+# define LM3S_UART1_BASE (LM3S_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */
+ /* -0x1ffff: Reserved */
+/* Peripheral Base Addresses */
+
+# define LM3S_I2CM0_BASE (LM3S_PERIPH_BASE + 0x20000) /* -0x207ff: I2C Master 0 */
+# define LM3S_I2CS0_BASE (LM3S_PERIPH_BASE + 0x20800) /* -0x20fff: I2C Slave 0 */
+# define LM3S_I2CM1_BASE (LM3S_PERIPH_BASE + 0x21000) /* -0x217ff: I2C Master 1 */
+# define LM3S_I2CS1_BASE (LM3S_PERIPH_BASE + 0x21800) /* -0x21fff: I2C Slave 1 */
+ /* -0x23fff: Reserved */
+# define LM3S_GPIOE_BASE (LM3S_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */
+# define LM3S_GPIOF_BASE (LM3S_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */
+# define LM3S_GPIOG_BASE (LM3S_PERIPH_BASE + 0x26000) /* -0x26fff: GPIO Port G */
+# define LM3S_GPIOH_BASE (LM3S_PERIPH_BASE + 0x27000) /* -0x27fff: GPIO Port H */
+ /* -0x2ffff: Reserved */
+# define LM3S_TIMER0_BASE (LM3S_PERIPH_BASE + 0x30000) /* -0x30fff: Timer 0 */
+# define LM3S_TIMER1_BASE (LM3S_PERIPH_BASE + 0x31000) /* -0x31fff: Timer 1 */
+# define LM3S_TIMER2_BASE (LM3S_PERIPH_BASE + 0x32000) /* -0x32fff: Timer 2 */
+# define LM3S_TIMER3_BASE (LM3S_PERIPH_BASE + 0x33000) /* -0x33fff: Timer 3 */
+ /* -0x37fff: Reserved */
+# define LM3S_ADC_BASE (LM3S_PERIPH_BASE + 0x38000) /* -0x38fff: ADC */
+ /* -0x3bfff: Reserved */
+# define LM3S_COMPARE_BASE (LM3S_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */
+ /* -0x47fff: Reserved */
+# define LM3S_ETHCON_BASE (LM3S_PERIPH_BASE + 0x48000) /* -0x48fff: Ethernet Controller */
+ /* -0xfcfff: Reserved */
+# define LM3S_HIBERNATE_BASE (LM3S_PERIPH_BASE + 0xfc000) /* -0xfcfff: Ethernet Controller */
+# define LM3S_FLASHCON_BASE (LM3S_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */
+# define LM3S_SYSCON_BASE (LM3S_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */
+ /* -0x1ffffff: Reserved */
+#elif defined(CONFIG_ARCH_CHIP_LM3S6432)
+/* FiRM Peripheral Base Addresses */
+
+# define LM3S_WDOG_BASE (LM3S_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer */
+ /* -0x03fff: Reserved */
+# define LM3S_GPIOA_BASE (LM3S_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */
+# define LM3S_GPIOB_BASE (LM3S_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */
+# define LM3S_GPIOC_BASE (LM3S_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */
+# define LM3S_GPIOD_BASE (LM3S_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */
+# define LM3S_SSI0_BASE (LM3S_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */
+ /* -0x0bfff: Reserved */
+# define LM3S_UART0_BASE (LM3S_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */
+# define LM3S_UART1_BASE (LM3S_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */
+ /* -0x1ffff: Reserved */
+/* Peripheral Base Addresses */
+
+# define LM3S_I2CM0_BASE (LM3S_PERIPH_BASE + 0x20000) /* -0x207ff: I2C Master 0 */
+# define LM3S_I2CS0_BASE (LM3S_PERIPH_BASE + 0x20800) /* -0x20fff: I2C Slave 0 */
+ /* -0x23fff: Reserved */
+# define LM3S_GPIOE_BASE (LM3S_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */
+# define LM3S_GPIOF_BASE (LM3S_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */
+# define LM3S_GPIOG_BASE (LM3S_PERIPH_BASE + 0x26000) /* -0x26fff: GPIO Port G */
+ /* -0x27fff: Reserved */
+# define LM3S_PWM0_BASE (LM3S_PERIPH_BASE + 0x28000) /* -0x28fff: PWM */
+ /* -0x2ffff: Reserved */
+# define LM3S_TIMER0_BASE (LM3S_PERIPH_BASE + 0x30000) /* -0x30fff: Timer 0 */
+# define LM3S_TIMER1_BASE (LM3S_PERIPH_BASE + 0x31000) /* -0x31fff: Timer 1 */
+# define LM3S_TIMER2_BASE (LM3S_PERIPH_BASE + 0x32000) /* -0x32fff: Timer 2 */
+ /* -0x37fff: Reserved */
+# define LM3S_ADC_BASE (LM3S_PERIPH_BASE + 0x38000) /* -0x38fff: ADC */
+ /* -0x3bfff: Reserved */
+# define LM3S_COMPARE_BASE (LM3S_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */
+ /* -0x47fff: Reserved */
+# define LM3S_ETHCON_BASE (LM3S_PERIPH_BASE + 0x48000) /* -0x48fff: Ethernet Controller */
+ /* -0xfcfff: Reserved */
+# define LM3S_HIBERNATE_BASE (LM3S_PERIPH_BASE + 0xfc000) /* -0xfcfff: Ethernet Controller */
+# define LM3S_FLASHCON_BASE (LM3S_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */
+# define LM3S_SYSCON_BASE (LM3S_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */
+ /* -0x1ffffff: Reserved */
+
+#elif defined(CONFIG_ARCH_CHIP_LM3S6965)
+/* FiRM Peripheral Base Addresses */
+
+# define LM3S_WDOG_BASE (LM3S_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer */
+ /* -0x03fff: Reserved */
+# define LM3S_GPIOA_BASE (LM3S_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */
+# define LM3S_GPIOB_BASE (LM3S_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */
+# define LM3S_GPIOC_BASE (LM3S_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */
+# define LM3S_GPIOD_BASE (LM3S_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */
+# define LM3S_SSI0_BASE (LM3S_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */
+ /* -0x0bfff: Reserved */
+# define LM3S_UART0_BASE (LM3S_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */
+# define LM3S_UART1_BASE (LM3S_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */
+# define LM3S_UART2_BASE (LM3S_PERIPH_BASE + 0x0e000) /* -0x0dfff: UART2 */
+ /* -0x1ffff: Reserved */
+/* Peripheral Base Addresses */
+
+# define LM3S_I2CM0_BASE (LM3S_PERIPH_BASE + 0x20000) /* -0x207ff: I2C Master 0 */
+# define LM3S_I2CS0_BASE (LM3S_PERIPH_BASE + 0x20800) /* -0x20fff: I2C Slave 0 */
+# define LM3S_I2CM1_BASE (LM3S_PERIPH_BASE + 0x21000) /* -0x217ff: I2C Master 1 */
+# define LM3S_I2CS1_BASE (LM3S_PERIPH_BASE + 0x21800) /* -0x21fff: I2C Slave 1 */
+ /* -0x23fff: Reserved */
+# define LM3S_GPIOE_BASE (LM3S_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */
+# define LM3S_GPIOF_BASE (LM3S_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */
+# define LM3S_GPIOG_BASE (LM3S_PERIPH_BASE + 0x26000) /* -0x26fff: GPIO Port G */
+ /* -0x27fff: Reserved */
+# define LM3S_PWM0_BASE (LM3S_PERIPH_BASE + 0x28000) /* -0x28fff: PWM */
+ /* -0x2bfff: Reserved */
+# define LM3S_QEI0_BASE (LM3S_PERIPH_BASE + 0x2c000) /* -0x2cfff: QEI0 */
+# define LM3S_QEI1_BASE (LM3S_PERIPH_BASE + 0x2d000) /* -0x2dfff: QEI1 */
+ /* -0x2ffff: Reserved */
+# define LM3S_TIMER0_BASE (LM3S_PERIPH_BASE + 0x30000) /* -0x30fff: Timer 0 */
+# define LM3S_TIMER1_BASE (LM3S_PERIPH_BASE + 0x31000) /* -0x31fff: Timer 1 */
+# define LM3S_TIMER2_BASE (LM3S_PERIPH_BASE + 0x32000) /* -0x32fff: Timer 2 */
+# define LM3S_TIMER3_BASE (LM3S_PERIPH_BASE + 0x33000) /* -0x33fff: Timer 3 */
+ /* -0x37fff: Reserved */
+# define LM3S_ADC_BASE (LM3S_PERIPH_BASE + 0x38000) /* -0x38fff: ADC */
+ /* -0x3bfff: Reserved */
+# define LM3S_COMPARE_BASE (LM3S_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */
+ /* -0x47fff: Reserved */
+# define LM3S_ETHCON_BASE (LM3S_PERIPH_BASE + 0x48000) /* -0x48fff: Ethernet Controller */
+ /* -0xfcfff: Reserved */
+# define LM3S_HIBERNATE_BASE (LM3S_PERIPH_BASE + 0xfc000) /* -0xfcfff: Ethernet Controller */
+# define LM3S_FLASHCON_BASE (LM3S_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */
+# define LM3S_SYSCON_BASE (LM3S_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */
+ /* -0x1ffffff: Reserved */
+#elif defined(CONFIG_ARCH_CHIP_LM3S8962)
+/* FiRM Peripheral Base Addresses */
+
+# define LM3S_WDOG_BASE (LM3S_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer */
+ /* -0x03fff: Reserved */
+# define LM3S_GPIOA_BASE (LM3S_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */
+# define LM3S_GPIOB_BASE (LM3S_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */
+# define LM3S_GPIOC_BASE (LM3S_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */
+# define LM3S_GPIOD_BASE (LM3S_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */
+# define LM3S_SSI0_BASE (LM3S_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */
+ /* -0x0bfff: Reserved */
+# define LM3S_UART0_BASE (LM3S_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */
+# define LM3S_UART1_BASE (LM3S_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */
+ /* -0x1ffff: Reserved */
+/* Peripheral Base Addresses */
+
+# define LM3S_I2CM0_BASE (LM3S_PERIPH_BASE + 0x20000) /* -0x207ff: I2C Master 0 */
+# define LM3S_I2CS0_BASE (LM3S_PERIPH_BASE + 0x20800) /* -0x20fff: I2C Slave 0 */
+ /* -0x23fff: Reserved */
+# define LM3S_GPIOE_BASE (LM3S_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */
+# define LM3S_GPIOF_BASE (LM3S_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */
+# define LM3S_GPIOG_BASE (LM3S_PERIPH_BASE + 0x26000) /* -0x26fff: GPIO Port G */
+ /* -0x27fff: Reserved */
+# define LM3S_PWM0_BASE (LM3S_PERIPH_BASE + 0x28000) /* -0x28fff: PWM */
+ /* -0x2bfff: Reserved */
+# define LM3S_QEI0_BASE (LM3S_PERIPH_BASE + 0x2c000) /* -0x2cfff: QEI0 */
+# define LM3S_QEI1_BASE (LM3S_PERIPH_BASE + 0x2d000) /* -0x2dfff: QEI1 */
+ /* -0x2ffff: Reserved */
+# define LM3S_TIMER0_BASE (LM3S_PERIPH_BASE + 0x30000) /* -0x30fff: Timer 0 */
+# define LM3S_TIMER1_BASE (LM3S_PERIPH_BASE + 0x31000) /* -0x31fff: Timer 1 */
+# define LM3S_TIMER2_BASE (LM3S_PERIPH_BASE + 0x32000) /* -0x32fff: Timer 2 */
+# define LM3S_TIMER3_BASE (LM3S_PERIPH_BASE + 0x33000) /* -0x33fff: Timer 3 */
+ /* -0x37fff: Reserved */
+# define LM3S_ADC_BASE (LM3S_PERIPH_BASE + 0x38000) /* -0x38fff: ADC */
+ /* -0x3bfff: Reserved */
+# define LM3S_COMPARE_BASE (LM3S_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */
+ /* -0x3fffff: Reserved */
+# define LM3S_CANCON_BASE (LM3S_PERIPH_BASE + 0x40000) /* -0x40fff: CAN Controller */
+ /* -0x47fff: Reserved */
+# define LM3S_ETHCON_BASE (LM3S_PERIPH_BASE + 0x48000) /* -0x48fff: Ethernet Controller */
+ /* -0xfcfff: Reserved */
+# define LM3S_HIBERNATE_BASE (LM3S_PERIPH_BASE + 0xfc000) /* -0xfcfff: Hibernation Controller */
+# define LM3S_FLASHCON_BASE (LM3S_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */
+# define LM3S_SYSCON_BASE (LM3S_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */
+ /* -0x1ffffff: Reserved */
+#elif defined(CONFIG_ARCH_CHIP_LM3S9B96)
+/* FiRM Peripheral Base Addresses */
+
+# define LM3S_WDOG_BASE (LM3S_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer */
+ /* -0x03fff: Reserved */
+# define LM3S_GPIOA_BASE (LM3S_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */
+# define LM3S_GPIOB_BASE (LM3S_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */
+# define LM3S_GPIOC_BASE (LM3S_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */
+# define LM3S_GPIOD_BASE (LM3S_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */
+# define LM3S_SSI0_BASE (LM3S_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */
+# define LM3S_SSI1_BASE (LM3S_PERIPH_BASE + 0x09000) /* -0x09fff: SSI0 */
+ /* -0x0bfff: Reserved */
+# define LM3S_UART0_BASE (LM3S_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */
+# define LM3S_UART1_BASE (LM3S_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */
+# define LM3S_UART2_BASE (LM3S_PERIPH_BASE + 0x0e000) /* -0x0dfff: UART2 */
+ /* -0x1ffff: Reserved */
+/* Peripheral Base Addresses */
+
+# define LM3S_I2CM0_BASE (LM3S_PERIPH_BASE + 0x20000) /* -0x207ff: I2C Master 0 */
+# define LM3S_I2CS0_BASE (LM3S_PERIPH_BASE + 0x20800) /* -0x20fff: I2C Slave 0 */
+# define LM3S_I2CM1_BASE (LM3S_PERIPH_BASE + 0x21000) /* -0x217ff: I2C Master 1 */
+# define LM3S_I2CS1_BASE (LM3S_PERIPH_BASE + 0x21800) /* -0x21fff: I2C Slave 1 */
+ /* -0x23fff: Reserved */
+# define LM3S_GPIOE_BASE (LM3S_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */
+# define LM3S_GPIOF_BASE (LM3S_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */
+# define LM3S_GPIOG_BASE (LM3S_PERIPH_BASE + 0x26000) /* -0x26fff: GPIO Port G */
+# define LM3S_GPIOH_BASE (LM3S_PERIPH_BASE + 0x27000) /* -0x27fff: GPIO Port H */
+
+# define LM3S_PWM0_BASE (LM3S_PERIPH_BASE + 0x28000) /* -0x28fff: PWM */
+ /* -0x2bfff: Reserved */
+# define LM3S_QEI0_BASE (LM3S_PERIPH_BASE + 0x2c000) /* -0x2cfff: QEI0 */
+# define LM3S_QEI1_BASE (LM3S_PERIPH_BASE + 0x2d000) /* -0x2dfff: QEI1 */
+ /* -0x2ffff: Reserved */
+# define LM3S_TIMER0_BASE (LM3S_PERIPH_BASE + 0x30000) /* -0x30fff: Timer 0 */
+# define LM3S_TIMER1_BASE (LM3S_PERIPH_BASE + 0x31000) /* -0x31fff: Timer 1 */
+# define LM3S_TIMER2_BASE (LM3S_PERIPH_BASE + 0x32000) /* -0x32fff: Timer 2 */
+# define LM3S_TIMER3_BASE (LM3S_PERIPH_BASE + 0x33000) /* -0x33fff: Timer 3 */
+ /* -0x37fff: Reserved */
+# define LM3S_ADC0_BASE (LM3S_PERIPH_BASE + 0x38000) /* -0x38fff: ADC 0 */
+# define LM3S_ADC1_BASE (LM3S_PERIPH_BASE + 0x39000) /* -0x39fff: ADC 1 */
+ /* -0x3bfff: Reserved */
+# define LM3S_COMPARE_BASE (LM3S_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */
+# define LM3S_GPIOJ_BASE (LM3S_PERIPH_BASE + 0x3d000) /* -0x3dfff: GPIO Port J */
+ /* -0x3ffff: Reserved */
+# define LM3S_CAN0_BASE (LM3S_PERIPH_BASE + 0x40000) /* -0x40fff: CAN 0 */
+# define LM3S_CAN1_BASE (LM3S_PERIPH_BASE + 0x41000) /* -0x41fff: CAN 1 */
+ /* -0x47fff: Reserved */
+# define LM3S_ETHCON_BASE (LM3S_PERIPH_BASE + 0x48000) /* -0x48fff: Ethernet Controller */
+ /* -0x49fff: Reserved */
+# define LM3S_USB_BASE (LM3S_PERIPH_BASE + 0x50000) /* -0x50fff: USB */
+ /* -0x53fff: Reserved */
+# define LM3S_I2S0_BASE (LM3S_PERIPH_BASE + 0x54000) /* -0x54fff: I2S 0 */
+ /* -0x57fff: Reserved */
+# define LM3S_GPIOAAHB_BASE (LM3S_PERIPH_BASE + 0x58000) /* -0x58fff: GPIO Port A (AHB aperture) */
+# define LM3S_GPIOBAHB_BASE (LM3S_PERIPH_BASE + 0x59000) /* -0x59fff: GPIO Port B (AHB aperture) */
+# define LM3S_GPIOCAHB_BASE (LM3S_PERIPH_BASE + 0x5A000) /* -0x5afff: GPIO Port C (AHB aperture) */
+# define LM3S_GPIODAHB_BASE (LM3S_PERIPH_BASE + 0x5B000) /* -0x5bfff: GPIO Port D (AHB aperture) */
+# define LM3S_GPIOEAHB_BASE (LM3S_PERIPH_BASE + 0x5C000) /* -0x5cfff: GPIO Port E (AHB aperture) */
+# define LM3S_GPIOFAHB_BASE (LM3S_PERIPH_BASE + 0x5D000) /* -0x5dfff: GPIO Port F (AHB aperture) */
+# define LM3S_GPIOGAHB_BASE (LM3S_PERIPH_BASE + 0x5E000) /* -0x5efff: GPIO Port G (AHB aperture) */
+# define LM3S_GPIOHAHB_BASE (LM3S_PERIPH_BASE + 0x5F000) /* -0x5ffff: GPIO Port H (AHB aperture) */
+# define LM3S_GPIOJAHB_BASE (LM3S_PERIPH_BASE + 0x60000) /* -0x60fff: GPIO Port J (AHB aperture) */
+ /* -0xcffff: Reserved */
+# define LM3S_EPI0_BASE (LM3S_PERIPH_BASE + 0xD0000) /* -0xd0fff: EPI 0 */
+ /* -0xfcfff: Reserved */
+# define LM3S_FLASHCON_BASE (LM3S_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */
+# define LM3S_SYSCON_BASE (LM3S_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */
+# define LM3S_UDMA_BASE (LM3S_PERIPH_BASE + 0xff000) /* -0xfffff: System Control */
+ /* -0x1ffffff: Reserved */
+#else
+# error "Peripheral base addresses not specified for this LM3S chip"
+#endif
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Function Prototypes
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LM3S_LM3S_MEMORYMAP_H */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_serial.c b/nuttx/arch/arm/src/lm3s/lm3s_serial.c
new file mode 100644
index 000000000..51f9ce955
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_serial.c
@@ -0,0 +1,1066 @@
+/****************************************************************************
+ * arch/arm/src/lm3s/lm3s_serial.c
+ *
+ * Copyright (C) 2009-2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+
+#include <arch/serial.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+#include "os_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Some sanity checks *******************************************************/
+
+#if LM3S_NUARTS < 2
+# undef CONFIG_UART1_DISABLE
+# undef CONFIG_UART1_SERIAL_CONSOLE
+# define CONFIG_UART1_DISABLE 1
+#endif
+
+#if LM3S_NUARTS < 3
+# undef CONFIG_UART2_DISABLE
+# undef CONFIG_UART2_SERIAL_CONSOLE
+# define CONFIG_UART2_DISABLE 1
+#endif
+
+/* Is there a UART enabled? */
+
+#if defined(CONFIG_UART0_DISABLE) && defined(CONFIG_UART1_DISABLE)
+# error "No UARTs enabled"
+#endif
+
+/* Is there a serial console? */
+
+#if defined(CONFIG_UART0_SERIAL_CONSOLE) && !defined(CONFIG_UART0_DISABLE)
+# undef CONFIG_UART1_SERIAL_CONSOLE
+# undef CONFIG_UART2_SERIAL_CONSOLE
+# define HAVE_CONSOLE 1
+#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && !defined(CONFIG_UART1_DISABLE)
+# undef CONFIG_UART0_SERIAL_CONSOLE
+# undef CONFIG_UART2_SERIAL_CONSOLE
+# define HAVE_CONSOLE 1
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && !defined(CONFIG_UART2_DISABLE)
+# undef CONFIG_UART0_SERIAL_CONSOLE
+# undef CONFIG_UART1_SERIAL_CONSOLE
+# define HAVE_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 HAVE_CONSOLE
+#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? */
+
+#if defined(CONFIG_UART0_SERIAL_CONSOLE)
+# define CONSOLE_DEV g_uart0port /* UART0 is console */
+# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */
+# ifndef CONFIG_UART1_DISABLE
+# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */
+# ifndef CONFIG_UART2_DISABLE
+# define TTYS2_DEV g_uart2port /* UART2 is ttyS2 */
+# else
+# undef TTYS2_DEV /* No ttyS2 */
+# endif
+# else
+# undef TTYS2_DEV /* No ttyS2 */
+# ifndef CONFIG_UART2_DISABLE
+# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */
+# else
+# undef TTYS1_DEV /* No ttyS1 */
+# endif
+# endif
+#elif defined(CONFIG_UART1_SERIAL_CONSOLE)
+# define CONSOLE_DEV g_uart1port /* UART1 is console */
+# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */
+# ifndef CONFIG_UART0_DISABLE
+# define TTYS1_DEV g_uart0port /* UART0 is ttyS1 */
+# ifndef CONFIG_UART2_DISABLE
+# define TTYS2_DEV g_uart2port /* UART2 is ttyS2 */
+# else
+# undef TTYS2_DEV /* No ttyS2 */
+# endif
+# else
+# undef TTYS2_DEV /* No ttyS2 */
+# ifndef CONFIG_UART2_DISABLE
+# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */
+# else
+# undef TTYS1_DEV /* No ttyS1 */
+# endif
+# endif
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE)
+# define CONSOLE_DEV g_uart2port /* UART2 is console */
+# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */
+# ifndef CONFIG_UART0_DISABLE
+# define TTYS1_DEV g_uart0port /* UART0 is ttyS1 */
+# ifndef CONFIG_UART2_DISABLE
+# define TTYS2_DEV g_uart2port /* UART2 is ttyS2 */
+# else
+# undef TTYS2_DEV /* No ttyS2 */
+# endif
+# else
+# undef TTYS2_DEV /* No ttyS2 */
+# ifndef CONFIG_UART2_DISABLE
+# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */
+# else
+# undef TTYS1_DEV /* No ttyS1 */
+# endif
+# endif
+#elif !defined(CONFIG_UART0_DISABLE)
+# undef CONSOLE_DEV /* No console device */
+# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */
+# ifndef CONFIG_UART1_DISABLE
+# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */
+# ifndef CONFIG_UART2_DISABLE
+# define TTYS2_DEV g_uart2port /* UART2 is ttyS2 */
+# else
+# undef TTYS2_DEV /* No ttyS2 */
+# endif
+# else
+# undef TTYS2_DEV /* No ttyS2 */
+# ifndef CONFIG_UART2_DISABLE
+# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */
+# else
+# undef TTYS1_DEV /* No ttyS1 */
+# endif
+# endif
+#elif !defined(CONFIG_UART1_DISABLE)
+# undef CONSOLE_DEV /* No console device */
+# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */
+# undef TTYS2_DEV /* No ttyS2 */
+# ifndef CONFIG_UART2_DISABLE
+# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */
+# else
+# undef TTYS1_DEV /* No ttyS1 */
+# endif
+#elif !defined(CONFIG_UART2_DISABLE)
+# undef CONSOLE_DEV /* No console device */
+# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */
+# undef TTYS1_DEV /* No ttyS1 */
+# undef TTYS2_DEV /* No ttyS2 */
+#else
+# error "No valid TTY devices"
+# undef CONSOLE_DEV /* No console device */
+# undef TTYS0_DEV /* No ttyS0 */
+# undef TTYS1_DEV /* No ttyS1 */
+# undef TTYS2_DEV /* No ttyS2 */
+#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 Variables
+ ****************************************************************************/
+
+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,
+ .send = up_send,
+ .txint = up_txint,
+ .txready = up_txready,
+ .txempty = up_txempty,
+};
+
+/* I/O buffers */
+
+#ifndef CONFIG_UART0_DISABLE
+static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE];
+static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE];
+#endif
+#ifndef CONFIG_UART1_DISABLE
+static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE];
+static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE];
+#endif
+#ifndef CONFIG_UART2_DISABLE
+static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE];
+static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE];
+#endif
+
+/* This describes the state of the LM3S uart0 port. */
+
+#ifndef CONFIG_UART0_DISABLE
+static struct up_dev_s g_uart0priv =
+{
+ .uartbase = LM3S_UART0_BASE,
+ .baud = CONFIG_UART0_BAUD,
+ .irq = LM3S_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 LM3S uart1 port. */
+
+#ifndef CONFIG_UART1_DISABLE
+static struct up_dev_s g_uart1priv =
+{
+ .uartbase = LM3S_UART1_BASE,
+ .baud = CONFIG_UART1_BAUD,
+ .irq = LM3S_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 LM3S uart1 port. */
+
+#ifndef CONFIG_UART2_DISABLE
+static struct up_dev_s g_uart2priv =
+{
+ .uartbase = LM3S_UART2_BASE,
+ .baud = CONFIG_UART2_BAUD,
+ .irq = LM3S_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
+
+/****************************************************************************
+ * 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, LM3S_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, LM3S_UART_IM_OFFSET, im);
+}
+
+/****************************************************************************
+ * 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, LM3S_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, LM3S_UART_CTL_OFFSET);
+ ctl &= ~UART_CTL_UARTEN;
+ up_serialout(priv, LM3S_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, LM3S_UART_IBRD_OFFSET, brdi);
+ up_serialout(priv, LM3S_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, LM3S_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, LM3S_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, LM3S_UART_IM_OFFSET, UART_IM_RXIM|UART_IM_RTIM);
+
+ /* Enable the FIFOs */
+
+#ifdef CONFIG_SUPPRESS_UART_CONFIG
+ lcrh = up_serialin(priv, LM3S_UART_LCRH_OFFSET);
+#endif
+ lcrh |= UART_LCRH_FEN;
+ up_serialout(priv, LM3S_UART_LCRH_OFFSET, lcrh);
+
+ /* Enable Rx, Tx, and the UART */
+
+#ifdef CONFIG_SUPPRESS_UART_CONFIG
+ ctl = up_serialin(priv, LM3S_UART_CTL_OFFSET);
+#endif
+ ctl |= (UART_CTL_UARTEN|UART_CTL_TXE|UART_CTL_RXE);
+ up_serialout(priv, LM3S_UART_CTL_OFFSET, ctl);
+
+ /* Set up the cache IM value */
+
+ priv->im = up_serialin(priv, LM3S_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;
+
+#ifndef CONFIG_UART0_DISABLE
+ if (g_uart0priv.irq == irq)
+ {
+ dev = &g_uart0port;
+ }
+ else
+#endif
+#ifndef CONFIG_UART1_DISABLE
+ if (g_uart1priv.irq == irq)
+ {
+ dev = &g_uart1port;
+ }
+ else
+#endif
+ {
+ PANIC(OSERR_INTERNAL);
+ }
+ 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, LM3S_UART_MIS_OFFSET);
+ up_serialout(priv, LM3S_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)
+{
+ struct inode *inode = filep->f_inode;
+ struct uart_dev_s *dev = inode->i_private;
+ int ret = OK;
+
+ switch (cmd)
+ {
+ 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;
+
+ 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, LM3S_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, LM3S_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, LM3S_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, LM3S_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 = irqsave();
+ 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, LM3S_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 LM3S 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, LM3S_UART_IM_OFFSET, priv->im);
+ }
+ irqrestore(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, LM3S_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, LM3S_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
+
+ /* 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
+}
+
+/****************************************************************************
+ * 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_disableuartint(priv, &im);
+ up_waittxnotfull(priv);
+ up_serialout(priv, LM3S_UART_DR_OFFSET, (uint32_t)ch);
+
+ /* Check for LF */
+
+ if (ch == '\n')
+ {
+ /* Add CR */
+
+ up_waittxnotfull(priv);
+ up_serialout(priv, LM3S_UART_DR_OFFSET, (uint32_t)'\r');
+ }
+
+ 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_CONSOLE
+ /* Check for LF */
+
+ if (ch == '\n')
+ {
+ /* Add CR */
+
+ up_lowputc('\r');
+ }
+
+ up_lowputc(ch);
+#endif
+ return ch;
+}
+
+#endif /* USE_SERIALDRIVER */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_ssi.c b/nuttx/arch/arm/src/lm3s/lm3s_ssi.c
new file mode 100644
index 000000000..c756e2b6a
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_ssi.c
@@ -0,0 +1,1573 @@
+/****************************************************************************
+ * arch/arm/src/lm32/lm3s_ssi.c
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/spi.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lm3s_internal.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 LM3S_NSSI == 0
+# undef CONFIG_SSI0_DISABLE
+# define CONFIG_SSI0_DISABLE 1
+# undef CONFIG_SSI1_DISABLE
+# define CONFIG_SSI1_DISABLE 1
+#elif LM3S_NSSI == 1
+# undef CONFIG_SSI1_DISABLE
+# define CONFIG_SSI1_DISABLE 1
+#endif
+
+/* Which SSI modules have been enabled? */
+
+#ifndef CONFIG_SSI0_DISABLE
+# define SSI0_NDX 0 /* Index to SSI0 in g_ssidev[] */
+# ifndef CONFIG_SSI1_DISABLE
+# define SSI1_NDX 1 /* Index to SSI1 in g_ssidev[] */
+# define NSSI_ENABLED 2 /* Two SSI interfaces: SSI0 & SSI1 */
+# else
+# define NSSI_ENABLED 1 /* One SSI interface: SSI0 */
+# define SSI_BASE LM3S_SSI0_BASE
+# define SSI_IRQ LM3S_IRQ_SSI0
+# endif
+#else
+# ifndef CONFIG_SSI1_DISABLE
+# define SSI1_NDX 0 /* Index to SSI1 in g_ssidev[] */
+# define NSSI_ENABLED 1 /* One SSI interface: SSI1 */
+# define SSI_BASE LM3S_SSI1_BASE
+# define SSI_IRQ LM3S_IRQ_SSI1
+# else
+# define NSSI_ENABLED 0 /* No SSI interfaces */
+# endif
+#endif
+
+/* Compile the rest of the file only if at least one SSI interface has been
+ * enabled.
+ */
+
+#if NSSI_ENABLED > 0
+
+/* The number of (16-bit) words that will fit in the Tx FIFO */
+
+#define LM3S_TXFIFO_WORDS 8
+
+/* Configuration settings */
+
+#ifndef CONFIG_SSI_TXLIMIT
+# define CONFIG_SSI_TXLIMIT (LM3S_TXFIFO_WORDS/2)
+#endif
+
+#if CONFIG_SSI_TXLIMIT < 1 || CONFIG_SSI_TXLIMIT > LM3S_TXFIFO_WORDS
+# error "Invalid range for CONFIG_SSI_TXLIMIT"
+#endif
+
+#if CONFIG_SSI_TXLIMIT && CONFIG_SSI_TXLIMIT < (LM3S_TXFIFO_WORDS/2)
+# error "CONFIG_SSI_TXLIMIT must be at least half the TX FIFO size"
+#endif
+
+/****************************************************************************
+ * Private Type Definitions
+ ****************************************************************************/
+
+struct lm3s_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 lm3s_ssidev_s *priv);
+ void (*rxword)(struct lm3s_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
+
+ /* If there is more than one device on the SPI bus, then we have to enforce
+ * mutual exclusion and remember some configuration settings to reduce the
+ * overhead of constant SPI re-configuration.
+ */
+
+#ifndef CONFIG_SPI_OWNBUS
+ 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 */
+#endif
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* SSI register access */
+
+static inline uint32_t ssi_getreg(struct lm3s_ssidev_s *priv,
+ unsigned int offset);
+static inline void ssi_putreg(struct lm3s_ssidev_s *priv, unsigned int offset,
+ uint32_t value);
+
+/* Misc helpers */
+
+static uint32_t ssi_disable(struct lm3s_ssidev_s *priv);
+static void ssi_enable(struct lm3s_ssidev_s *priv, uint32_t enable);
+static void ssi_semtake(sem_t *sem);
+#define ssi_semgive(s) sem_post(s);
+
+/* SSI data transfer */
+
+static void ssi_txnull(struct lm3s_ssidev_s *priv);
+static void ssi_txuint16(struct lm3s_ssidev_s *priv);
+static void ssi_txuint8(struct lm3s_ssidev_s *priv);
+static void ssi_rxnull(struct lm3s_ssidev_s *priv);
+static void ssi_rxuint16(struct lm3s_ssidev_s *priv);
+static void ssi_rxuint8(struct lm3s_ssidev_s *priv);
+static inline bool ssi_txfifofull(struct lm3s_ssidev_s *priv);
+static inline bool ssi_rxfifoempty(struct lm3s_ssidev_s *priv);
+#if CONFIG_SSI_TXLIMIT == 1 && defined(CONFIG_SSI_POLLWAIT)
+static inline int ssi_performtx(struct lm3s_ssidev_s *priv);
+#else
+static int ssi_performtx(struct lm3s_ssidev_s *priv);
+#endif
+static inline void ssi_performrx(struct lm3s_ssidev_s *priv);
+static int ssi_transfer(struct lm3s_ssidev_s *priv, const void *txbuffer,
+ void *rxbuffer, unsigned int nwords);
+
+/* Interrupt handling */
+
+#ifndef CONFIG_SSI_POLLWAIT
+static inline struct lm3s_ssidev_s *ssi_mapirq(int irq);
+static int ssi_interrupt(int irq, void *context);
+#endif
+
+/* SPI methods */
+
+#ifndef CONFIG_SPI_OWNBUS
+static int ssi_lock(FAR struct spi_dev_s *dev, bool lock);
+#endif
+static uint32_t ssi_setfrequencyinternal(struct lm3s_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 lm3s_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 lm3s_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 =
+{
+#ifndef CONFIG_SPI_OWNBUS
+ .lock = ssi_lock,
+#endif
+ .select = lm3s_spiselect, /* Provided externally by board logic */
+ .setfrequency = ssi_setfrequency,
+ .setmode = ssi_setmode,
+ .setbits = ssi_setbits,
+ .status = lm3s_spistatus, /* Provided externally by board logic */
+#ifdef CONFIG_SPI_CMDDATA
+ .cmddata = lm3s_spicmddata,
+#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 lm3s_ssidev_s g_ssidev[] =
+{
+#ifndef CONFIG_SSI0_DISABLE
+ {
+ .ops = &g_spiops,
+#if NSSI_ENABLED > 1
+ .base = LM3S_SSI0_BASE,
+#endif
+#if !defined(CONFIG_SSI_POLLWAIT) && NSSI_ENABLED > 1
+ .irq = LM3S_IRQ_SSI0,
+#endif
+ },
+#endif
+#ifndef CONFIG_SSI1_DISABLE
+ {
+ .ops = &g_spiops,
+#if NSSI_ENABLED > 1
+ .base = LM3S_SSI1_BASE,
+#endif
+#if !defined(CONFIG_SSI_POLLWAIT) && NSSI_ENABLED > 1
+ .irq = LM3S_IRQ_SSI1,
+#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 lm3s_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 lm3s_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 (if CONFIG_SPI_OWNBUS not defined)
+ *
+ ****************************************************************************/
+
+static uint32_t ssi_disable(struct lm3s_ssidev_s *priv)
+{
+ uint32_t retval;
+ uint32_t regval;
+
+ retval = ssi_getreg(priv, LM3S_SSI_CR1_OFFSET);
+ regval = (retval & ~SSI_CR1_SSE);
+ ssi_putreg(priv, LM3S_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 (if CONFIG_SPI_OWNBUS not defined)
+ *
+ ****************************************************************************/
+
+static void ssi_enable(struct lm3s_ssidev_s *priv, uint32_t enable)
+{
+ uint32_t regval = ssi_getreg(priv, LM3S_SSI_CR1_OFFSET);
+ regval &= ~SSI_CR1_SSE;
+ regval |= (enable & SSI_CR1_SSE);
+ ssi_putreg(priv, LM3S_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:
+ *
+ ****************************************************************************/
+
+static void ssi_semtake(sem_t *sem)
+{
+ int ret;
+ do
+ {
+ ret = sem_wait(sem);
+ }
+ while (ret < 0 && errno == EINTR);
+ DEBUGASSERT(ret == 0);
+}
+
+/****************************************************************************
+ * 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 lm3s_ssidev_s *priv)
+{
+ ssivdbg("TX: ->0xffff\n");
+ ssi_putreg(priv, LM3S_SSI_DR_OFFSET, 0xffff);
+}
+
+static void ssi_txuint16(struct lm3s_ssidev_s *priv)
+{
+ uint16_t *ptr = (uint16_t*)priv->txbuffer;
+ ssivdbg("TX: %p->%04x\n", ptr, *ptr);
+ ssi_putreg(priv, LM3S_SSI_DR_OFFSET, (uint32_t)(*ptr++));
+ priv->txbuffer = (void*)ptr;
+}
+
+static void ssi_txuint8(struct lm3s_ssidev_s *priv)
+{
+ uint8_t *ptr = (uint8_t*)priv->txbuffer;
+ ssivdbg("TX: %p->%02x\n", ptr, *ptr);
+ ssi_putreg(priv, LM3S_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 lm3s_ssidev_s *priv)
+{
+#if defined(SSI_DEBUG) && defined(CONFIG_DEBUG_VERBOSE)
+ uint32_t regval = ssi_getreg(priv, LM3S_SSI_DR_OFFSET);
+ ssivdbg("RX: discard %04x\n", regval);
+#else
+ (void)ssi_getreg(priv, LM3S_SSI_DR_OFFSET);
+#endif
+}
+
+static void ssi_rxuint16(struct lm3s_ssidev_s *priv)
+{
+ uint16_t *ptr = (uint16_t*)priv->rxbuffer;
+ *ptr = (uint16_t)ssi_getreg(priv, LM3S_SSI_DR_OFFSET);
+ ssivdbg("RX: %p<-%04x\n", ptr, *ptr);
+ priv->rxbuffer = (void*)(++ptr);
+}
+
+static void ssi_rxuint8(struct lm3s_ssidev_s *priv)
+{
+ uint8_t *ptr = (uint8_t*)priv->rxbuffer;
+ *ptr = (uint8_t)ssi_getreg(priv, LM3S_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 lm3s_ssidev_s *priv)
+{
+ return (ssi_getreg(priv, LM3S_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 lm3s_ssidev_s *priv)
+{
+ return (ssi_getreg(priv, LM3S_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 lm3s_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 lm3s_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, LM3S_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, LM3S_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 lm3s_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, LM3S_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, LM3S_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 (if CONFIG_SPI_OWNBUS not defined)
+ *
+ ****************************************************************************/
+
+static int ssi_transfer(struct lm3s_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 = irqsave();
+ ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x\n",
+ priv->ntxwords, priv->nrxwords, priv->nwords,
+ ssi_getreg(priv, LM3S_SSI_SR_OFFSET));
+
+ ntxd = ssi_performtx(priv);
+
+ /* 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, LM3S_SSI_SR_OFFSET),
+ ssi_getreg(priv, LM3S_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");
+ irqrestore(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);
+
+ /* 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 lm3s_ssidev_s *ssi_mapirq(int irq)
+{
+ switch (irq)
+ {
+#ifndef CONFIG_SSI0_DISABLE
+ case LM3S_IRQ_SSI0:
+ return &g_ssidev[SSI0_NDX];
+#endif
+#ifndef CONFIG_SSI1_DISABLE
+ case LM3S_IRQ_SSI1:
+ return &g_ssidev[SSI1_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 lm3s_ssidev_s *priv = ssi_mapirq(irq);
+ uint32_t regval;
+ int ntxd;
+
+ DEBUGASSERT(priv != NULL);
+
+ /* Clear pending interrupts */
+
+ regval = ssi_getreg(priv, LM3S_SSI_RIS_OFFSET);
+ ssi_putreg(priv, LM3S_SSI_ICR_OFFSET, regval);
+
+ /* Check for Rx FIFO overruns */
+
+#ifdef CONFIG_DEBUG
+ if ((regval & SSI_RIS_ROR) != 0)
+ {
+ lldbg("Rx FIFO Overrun!\n");
+ }
+#endif
+
+ ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x\n",
+ priv->ntxwords, priv->nrxwords, priv->nwords,
+ ssi_getreg(priv, LM3S_SSI_SR_OFFSET));
+
+ /* Handle outgoing Tx FIFO transfers */
+
+ ntxd = 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, LM3S_SSI_SR_OFFSET),
+ ssi_getreg(priv, LM3S_SSI_IM_OFFSET));
+
+ /* Check if the transfer is complete */
+
+ if (priv->nrxwords >= priv->nwords)
+ {
+ /* Yes.. Disable all SSI interrupt sources */
+
+ ssi_putreg(priv, LM3S_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
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_OWNBUS
+static int ssi_lock(FAR struct spi_dev_s *dev, bool lock)
+{
+ FAR struct lm3s_ssidev_s *priv = (FAR struct lm3s_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;
+}
+#endif
+
+/****************************************************************************
+ * 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 (if CONFIG_SPI_OWNBUS not defined)
+ *
+ ****************************************************************************/
+
+static uint32_t ssi_setfrequencyinternal(struct lm3s_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? */
+
+#ifndef CONFIG_SPI_OWNBUS
+ if (frequency != priv->frequency)
+ {
+#endif
+ /* "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, LM3S_SSI_CPSR_OFFSET, cpsdvsr);
+
+ /* Set SCR */
+
+ regval = ssi_getreg(priv, LM3S_SSI_CR0_OFFSET);
+ regval &= ~SSI_CR0_SCR_MASK;
+ regval |= (scr << SSI_CR0_SCR_SHIFT);
+ ssi_putreg(priv, LM3S_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.
+ */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->frequency = frequency;
+ priv->actual = actual;
+ }
+ return priv->actual;
+#else
+ return actual;
+#endif
+}
+
+static uint32_t ssi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
+{
+ struct lm3s_ssidev_s *priv = (struct lm3s_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 (if CONFIG_SPI_OWNBUS not defined)
+ *
+ ****************************************************************************/
+
+static void ssi_setmodeinternal(struct lm3s_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? */
+
+#ifndef CONFIG_SPI_OWNBUS
+ if (mode != priv->mode)
+ {
+#endif
+ /* 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, LM3S_SSI_CR0_OFFSET);
+ regval &= ~(SSI_CR0_FRF_MASK|SSI_CR0_SPH|SSI_CR0_SPO);
+ regval |= modebits;
+ ssi_putreg(priv, LM3S_SSI_CR0_OFFSET, regval);
+ ssivdbg("CR0: %08x\n", regval);
+
+ /* Save the mode so that subsequent re-configuratins will be faster */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->mode = mode;
+ }
+#endif
+}
+
+static void ssi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
+{
+ struct lm3s_ssidev_s *priv = (struct lm3s_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 (if CONFIG_SPI_OWNBUS not defined)
+ *
+ ****************************************************************************/
+
+static void ssi_setbitsinternal(struct lm3s_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, LM3S_SSI_CR0_OFFSET);
+ regval &= ~SSI_CR0_DSS_MASK;
+ regval |= ((nbits - 1) << SSI_CR0_DSS_SHIFT);
+ ssi_putreg(priv, LM3S_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 lm3s_ssidev_s *priv = (struct lm3s_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 lm3s_ssidev_s *priv = (struct lm3s_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 lm3s_ssidev_s *priv = (struct lm3s_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 lm3s_ssidev_s *priv = (struct lm3s_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 lm3s_ssidev_s *priv = (struct lm3s_ssidev_s *)dev;
+ (void)ssi_transfer(priv, NULL, buffer, nwords);
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_spiinitialize
+ *
+ * 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 *up_spiinitialize(int port)
+{
+ struct lm3s_ssidev_s *priv;
+ irqstate_t flags;
+ uint8_t regval;
+
+ ssidbg("port: %d\n", port);
+
+ /* Set up for the selected port */
+
+ flags = irqsave();
+ switch (port)
+ {
+#ifndef CONFIG_SSI0_DISABLE
+ case 0:
+ /* Select SSI0 */
+
+ priv = &g_ssidev[SSI0_NDX];
+
+ /* Enable the SSI0 peripheral */
+
+ regval = getreg32(LM3S_SYSCON_RCGC1);
+ regval |= SYSCON_RCGC1_SSI0;
+ putreg32(regval, LM3S_SYSCON_RCGC1);
+ ssivdbg("RCGC1: %08x\n", regval);
+
+ /* Configure SSI0 GPIOs (NOTE that SS is not initialized here, the
+ * logic in this file makes no assumptions about chip select)
+ */
+
+ lm3s_configgpio(GPIO_SSI0_CLK); /* PA2: SSI0 clock (SSI0Clk) */
+ /* lm3s_configgpio(GPIO_SSI0_FSS); PA3: SSI0 frame (SSI0Fss) */
+ lm3s_configgpio(GPIO_SSI0_RX); /* PA4: SSI0 receive (SSI0Rx) */
+ lm3s_configgpio(GPIO_SSI0_TX); /* PA5: SSI0 transmit (SSI0Tx) */
+ break;
+#endif /* CONFIG_SSI0_DISABLE */
+
+#ifndef CONFIG_SSI1_DISABLE
+ case 1:
+ /* Select SSI0 */
+
+ priv = &g_ssidev[SSI1_NDX];
+
+ /* Enable the SSI1 peripheral */
+
+ regval = getreg32(LM3S_SYSCON_RCGC1);
+ regval |= SYSCON_RCGC1_SSI1;
+ putreg32(regval, LM3S_SYSCON_RCGC1);
+ ssivdbg("RCGC1: %08x\n", regval);
+
+ /* Configure SSI1 GPIOs */
+
+ lm3s_configgpio(GPIO_SSI1_CLK); /* PE0: SSI1 clock (SSI1Clk) */
+ /* lm3s_configgpio(GPIO_SSI1_FSS); PE1: SSI1 frame (SSI1Fss) */
+ lm3s_configgpio(GPIO_SSI1_RX); /* PE2: SSI1 receive (SSI1Rx) */
+ lm3s_configgpio(GPIO_SSI1_TX); /* PE3: SSI1 transmit (SSI1Tx) */
+ break;
+#endif /* CONFIG_SSI1_DISABLE */
+
+ default:
+ irqrestore(flags);
+ return NULL;
+ }
+
+ /* Initialize the state structure */
+
+#ifndef CONFIG_SSI_POLLWAIT
+ sem_init(&priv->xfrsem, 0, 0);
+#endif
+#ifndef CONFIG_SPI_OWNBUS
+ sem_init(&priv->exclsem, 0, 1);
+#endif
+
+ /* Set all CR1 fields to reset state. This will be master mode. */
+
+ ssi_putreg(priv, LM3S_SSI_CR1_OFFSET, 0);
+
+ /* Set all CR0 fields to the reset state. This will also select Freescale SPI mode. */
+
+ ssi_putreg(priv, LM3S_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, LM3S_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 */
+
+ irqrestore(flags);
+ return (FAR struct spi_dev_s *)priv;
+}
+
+#endif /* NSSI_ENABLED > 0 */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_ssi.h b/nuttx/arch/arm/src/lm3s/lm3s_ssi.h
new file mode 100644
index 000000000..482dab326
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_ssi.h
@@ -0,0 +1,235 @@
+/************************************************************************************
+ * arch/arm/src/lm3s/lm3s_ssi.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_LM3S_LM3S_SSI_H
+#define __ARCH_ARM_SRC_LM3S_LM3S_SSI_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+#include <sys/types.h>
+
+#if LM3S_NSSI > 0
+
+/************************************************************************************
+ * Definitions
+ ************************************************************************************/
+
+/* SSI register offsets *************************************************************/
+
+#define LM3S_SSI_CR0_OFFSET 0x000 /* SSI Control 0 */
+#define LM3S_SSI_CR1_OFFSET 0x004 /* SSI Control 1 */
+#define LM3S_SSI_DR_OFFSET 0x008 /* SSI Data */
+#define LM3S_SSI_SR_OFFSET 0x00c /* SSI Status */
+#define LM3S_SSI_CPSR_OFFSET 0x010 /* SSI Clock Prescale */
+#define LM3S_SSI_IM_OFFSET 0x014 /* SSI Interrupt Mask */
+#define LM3S_SSI_RIS_OFFSET 0x018 /* SSI Raw Interrupt Status */
+#define LM3S_SSI_MIS_OFFSET 0x01c /* SSI Masked Interrupt Status */
+#define LM3S_SSI_ICR_OFFSET 0x020 /* SSI Interrupt Clear */
+#define LM3S_SSI_PERIPHID4_OFFSET 0xfd0 /* SSI Peripheral Identification 4 */
+#define LM3S_SSI_PERIPHID5_OFFSET 0xfd4 /* SSI Peripheral Identification 5 */
+#define LM3S_SSI_PERIPHID6_OFFSET 0xfd8 /* SSI Peripheral Identification 6 */
+#define LM3S_SSI_PERIPHID7_OFFSET 0xfdc /* SSI Peripheral Identification 7 */
+#define LM3S_SSI_PERIPHID0_OFFSET 0xfe0 /* SSI Peripheral Identification 0 */
+#define LM3S_SSI_PERIPHID1_OFFSET 0xfe4 /* SSI Peripheral Identification 1 */
+#define LM3S_SSI_PERIPHID2_OFFSET 0xfe8 /* SSI Peripheral Identification 2 */
+#define LM3S_SSI_PERIPHID3_OFFSET 0xfec /* SSI Peripheral Identification 3 */
+#define LM3S_SSI_PCELLID0_OFFSET 0xff0 /* SSI PrimeCell Identification 0 */
+#define LM3S_SSI_PCELLID1_OFFSET 0xff4 /* SSI PrimeCell Identification 1 */
+#define LM3S_SSI_PCELLID2_OFFSET 0xff8 /* SSI PrimeCell Identification 2 */
+#define LM3S_SSI_PCELLID3_OFFSET 0xffc /* SSI PrimeCell Identification 3 */
+
+/* SSI register addresses ***********************************************************/
+
+#define LM3S_SSI0_CR0 (LM3S_SSI0_BASE + LM3S_SSI_CR0_OFFSET)
+#define LM3S_SSI0_CR1 (LM3S_SSI0_BASE + LM3S_SSI_CR1_OFFSET)
+#define LM3S_SSI0_DR (LM3S_SSI0_BASE + LM3S_SSI_DR_OFFSET)
+#define LM3S_SSI0_SR (LM3S_SSI0_BASE + LM3S_SSI_SR_OFFSET)
+#define LM3S_SSI0_CPSR (LM3S_SSI0_BASE + LM3S_SSI_CPSR_OFFSET)
+#define LM3S_SSI0_IM (LM3S_SSI0_BASE + LM3S_SSI_IM_OFFSET)
+#define LM3S_SSI0_RIS (LM3S_SSI0_BASE + LM3S_SSI_RIS_OFFSET)
+#define LM3S_SSI0_MIS (LM3S_SSI0_BASE + LM3S_SSI_MIS_OFFSET)
+#define LM3S_SSI0_ICR (LM3S_SSI0_BASE + LM3S_SSI_ICR_OFFSET)
+#define LM3S_SSI0_PERIPHID4 (LM3S_SSI0_BASE + LM3S_SSI_PERIPHID4_OFFSET)
+#define LM3S_SSI0_PERIPHID5 (LM3S_SSI0_BASE + LM3S_SSI_PERIPHID5_OFFSET)
+#define LM3S_SSI0_PERIPHID6 (LM3S_SSI0_BASE + LM3S_SSI_PERIPHID6_OFFSET)
+#define LM3S_SSI0_PERIPHID7 (LM3S_SSI0_BASE + LM3S_SSI_PERIPHID7_OFFSET)
+#define LM3S_SSI0_PERIPHID0 (LM3S_SSI0_BASE + LM3S_SSI_PERIPHID0_OFFSET)
+#define LM3S_SSI0_PERIPHID1 (LM3S_SSI0_BASE + LM3S_SSI_PERIPHID1_OFFSET)
+#define LM3S_SSI0_PERIPHID2 (LM3S_SSI0_BASE + LM3S_SSI_PERIPHID2_OFFSET)
+#define LM3S_SSI0_PERIPHID3 (LM3S_SSI0_BASE + LM3S_SSI_PERIPHID3_OFFSET)
+#define LM3S_SSI0_PCELLID0 (LM3S_SSI0_BASE + LM3S_SSI_PCELLID0_OFFSET)
+#define LM3S_SSI0_PCELLID1 (LM3S_SSI0_BASE + LM3S_SSI_PCELLID1_OFFSET)
+#define LM3S_SSI0_PCELLID2 (LM3S_SSI0_BASE + LM3S_SSI_PCELLID2_OFFSET)
+#define LM3S_SSI0_PCELLID3 (LM3S_SSI0_BASE + LM3S_SSI_PCELLID3_OFFSET)
+
+#if LM3S_NSSI > 1
+#define LM3S_SSI1_CR0 (LM3S_SSI1_BASE + LM3S_SSI_CR0_OFFSET)
+#define LM3S_SSI1_CR1 (LM3S_SSI1_BASE + LM3S_SSI_CR1_OFFSET)
+#define LM3S_SSI1_DR (LM3S_SSI1_BASE + LM3S_SSI_DR_OFFSET)
+#define LM3S_SSI1_SR (LM3S_SSI1_BASE + LM3S_SSI_SR_OFFSET)
+#define LM3S_SSI1_CPSR (LM3S_SSI1_BASE + LM3S_SSI_CPSR_OFFSET)
+#define LM3S_SSI1_IM (LM3S_SSI1_BASE + LM3S_SSI_IM_OFFSET)
+#define LM3S_SSI1_RIS (LM3S_SSI1_BASE + LM3S_SSI_RIS_OFFSET)
+#define LM3S_SSI1_MIS (LM3S_SSI1_BASE + LM3S_SSI_MIS_OFFSET)
+#define LM3S_SSI1_ICR (LM3S_SSI1_BASE + LM3S_SSI_ICR_OFFSET)
+#define LM3S_SSI1_PERIPHID4 (LM3S_SSI1_BASE + LM3S_SSI_PERIPHID4_OFFSET)
+#define LM3S_SSI1_PERIPHID5 (LM3S_SSI1_BASE + LM3S_SSI_PERIPHID5_OFFSET)
+#define LM3S_SSI1_PERIPHID6 (LM3S_SSI1_BASE + LM3S_SSI_PERIPHID6_OFFSET)
+#define LM3S_SSI1_PERIPHID7 (LM3S_SSI1_BASE + LM3S_SSI_PERIPHID7_OFFSET)
+#define LM3S_SSI1_PERIPHID0 (LM3S_SSI1_BASE + LM3S_SSI_PERIPHID0_OFFSET)
+#define LM3S_SSI1_PERIPHID1 (LM3S_SSI1_BASE + LM3S_SSI_PERIPHID1_OFFSET)
+#define LM3S_SSI1_PERIPHID2 (LM3S_SSI1_BASE + LM3S_SSI_PERIPHID2_OFFSET)
+#define LM3S_SSI1_PERIPHID3 (LM3S_SSI1_BASE + LM3S_SSI_PERIPHID3_OFFSET)
+#define LM3S_SSI1_PCELLID0 (LM3S_SSI1_BASE + LM3S_SSI_PCELLID0_OFFSET)
+#define LM3S_SSI1_PCELLID1 (LM3S_SSI1_BASE + LM3S_SSI_PCELLID1_OFFSET)
+#define LM3S_SSI1_PCELLID2 (LM3S_SSI1_BASE + LM3S_SSI_PCELLID2_OFFSET)
+#define LM3S_SSI1_PCELLID3 (LM3S_SSI1_BASE + LM3S_SSI_PCELLID3_OFFSET)
+
+#define LM3S_SSI_BASE(n) (LM3S_SSI0_BASE + (n)*0x01000)
+
+#define LM3S_SSI_CR0(n) (LM3S_SSI_BASE(n) + LM3S_SSI_CR0_OFFSET)
+#define LM3S_SSI_CR1(n) (LM3S_SSI_BASE(n) + LM3S_SSI_CR1_OFFSET)
+#define LM3S_SSI_DR(n) (LM3S_SSI_BASE(n) + LM3S_SSI_DR_OFFSET)
+#define LM3S_SSI_SR(n) (LM3S_SSI_BASE(n) + LM3S_SSI_SR_OFFSET)
+#define LM3S_SSI_CPSR(n) (LM3S_SSI_BASE(n) + LM3S_SSI_CPSR_OFFSET)
+#define LM3S_SSI_IM(n) (LM3S_SSI_BASE(n) + LM3S_SSI_IM_OFFSET)
+#define LM3S_SSI_RIS(n) (LM3S_SSI_BASE(n) + LM3S_SSI_RIS_OFFSET)
+#define LM3S_SSI_MIS(n) (LM3S_SSI_BASE(n) + LM3S_SSI_MIS_OFFSET)
+#define LM3S_SSI_ICR(n) (LM3S_SSI_BASE(n) + LM3S_SSI_ICR_OFFSET)
+#define LM3S_SSI_PERIPHID4(n) (LM3S_SSI_BASE(n) + LM3S_SSI_PERIPHID4_OFFSET)
+#define LM3S_SSI_PERIPHID5(n) (LM3S_SSI_BASE(n) + LM3S_SSI_PERIPHID5_OFFSET)
+#define LM3S_SSI_PERIPHID6(n) (LM3S_SSI_BASE(n) + LM3S_SSI_PERIPHID6_OFFSET)
+#define LM3S_SSI_PERIPHID7(n) (LM3S_SSI_BASE(n) + LM3S_SSI_PERIPHID7_OFFSET)
+#define LM3S_SSI_PERIPHID0(n) (LM3S_SSI_BASE(n) + LM3S_SSI_PERIPHID0_OFFSET)
+#define LM3S_SSI_PERIPHID1(n) (LM3S_SSI_BASE(n) + LM3S_SSI_PERIPHID1_OFFSET)
+#define LM3S_SSI_PERIPHID2(n) (LM3S_SSI_BASE(n) + LM3S_SSI_PERIPHID2_OFFSET)
+#define LM3S_SSI_PERIPHID3(n) (LM3S_SSI_BASE(n) + LM3S_SSI_PERIPHID3_OFFSET)
+#define LM3S_SSI_PCELLID0(n) (LM3S_SSI_BASE(n) + LM3S_SSI_PCELLID0_OFFSET)
+#define LM3S_SSI_PCELLID1(n) (LM3S_SSI_BASE(n) + LM3S_SSI_PCELLID1_OFFSET)
+#define LM3S_SSI_PCELLID2(n) (LM3S_SSI_BASE(n) + LM3S_SSI_PCELLID2_OFFSET)
+#define LM3S_SSI_PCELLID3(n) (LM3S_SSI_BASE(n) + LM3S_SSI_PCELLID3_OFFSET)
+#endif /* LM3S_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 /* LM3S_NSSI > 0 */
+#endif /* __ARCH_ARM_SRC_LM3S_LM3S_SSI_H */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_start.c b/nuttx/arch/arm/src/lm3s/lm3s_start.c
new file mode 100644
index 000000000..f3f762b52
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_start.c
@@ -0,0 +1,152 @@
+/****************************************************************************
+ * arch/arm/src/lm3s/lm3s_start.c
+ * arch/arm/src/chip/lm3s_start.c
+ *
+ * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/init.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "lm3s_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+extern void lm3s_vectors(void);
+
+/****************************************************************************
+ * 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 */
+
+ up_clockconfig();
+ up_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 intialized 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');
+
+ /* Initialize onboard resources */
+
+ lm3s_boardinitialize();
+ showprogress('E');
+
+ /* Then start NuttX */
+
+ showprogress('\r');
+ showprogress('\n');
+ os_start();
+
+ /* Shoulnd't get here */
+
+ for(;;);
+}
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_syscontrol.c b/nuttx/arch/arm/src/lm3s/lm3s_syscontrol.c
new file mode 100644
index 000000000..e26789d32
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_syscontrol.c
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * arch/arm/src/lm3s/lm3s_syscontrol.c
+ * arch/arm/src/chip/lm3s_syscontrol.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/init.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "lm3s_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#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_USERCC2|SYSCON_RCC2_OSCSRC2_MASK|SYSCON_RCC2_PWRDN2)
+#define RCC_DIVMASK (SYSCON_RCC_SYSDIV_MASK|SYSCON_RCC_USESYSDIV|SYSCON_RCC_IOSCDIS|SYSCON_RCC_MOSCDIS)
+#define RCC2_DIVMASK (SYSCON_RCC2_SYSDIV2_MASK)
+#define FAST_OSCDELAY (512*1024)
+#define SLOW_OSCDELAY (4*1024)
+#define PLLLOCK_DELAY (32*1024)
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lm3s_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 lm3s_delay(uint32_t delay)
+{
+ __asm__ __volatile__("1:\n"
+ "\tsubs %0, #1\n"
+ "\tbne 1b\n"
+ : "=r"(delay) : "r"(delay));
+}
+
+/****************************************************************************
+ * Name: lm3s_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 lm3s_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_30KHZ) ||
+ (rcc2src == SYSCON_RCC2_OSCSRC2_32KHZ))
+ {
+ delay = SLOW_OSCDELAY;
+ }
+ }
+
+ /* No.. using srce in RCC */
+
+ else
+ {
+ uint32_t rccsrc = rcc & SYSCON_RCC_OSCSRC_MASK;
+ if (rccsrc == SYSCON_RCC_OSCSRC_30KHZ)
+ {
+ delay = SLOW_OSCDELAY;
+ }
+ }
+
+ /* Then delay that number of loops */
+
+ lm3s_delay(delay);
+}
+
+/****************************************************************************
+ * Name: lm3s_plllock
+ *
+ * Description:
+ * The new RCC values have been selected... wait for the PLL to lock on
+ *
+ ****************************************************************************/
+
+static inline void lm3s_plllock(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(LM3S_SYSCON_RIS) & SYSCON_RIS_PLLLRIS) != 0)
+ {
+ /* Yes.. return now */
+
+ return;
+ }
+ }
+
+ /* If we get here, then PLL lock was not achieved */
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lm3s_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 lm3s_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(LM3S_SYSCON_RCC);
+ rcc2 = getreg32(LM3S_SYSCON_RCC2);
+
+ /* Temporarily bypass the PLL and system clock dividers */
+
+ rcc |= SYSCON_RCC_BYPASS;
+ rcc &= ~(SYSCON_RCC_USESYSDIV);
+ putreg32(rcc, LM3S_SYSCON_RCC);
+
+ rcc2 |= SYSCON_RCC2_BYPASS2;
+ putreg32(rcc2, LM3S_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 rest and if that is selected, most likely nothing needs to be done.
+ */
+
+ if (((rcc & SYSCON_RCC_MOSCDIS) && !(newrcc & SYSCON_RCC_MOSCDIS)) ||
+ ((rcc & SYSCON_RCC_IOSCDIS) && !(newrcc & SYSCON_RCC_IOSCDIS)))
+ {
+ /* Enable any selected osciallators (but don't disable any yet) */
+
+ rcc &= (~RCC_OSCMASK | (newrcc & RCC_OSCMASK));
+ putreg32(rcc, LM3S_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.
+ */
+
+ lm3s_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, LM3S_SYSCON_MISC);
+
+ /* Write the new RCC/RCC2 values. Order depends upon whether RCC2 or RCC
+ * is currently enabled.
+ */
+
+ if (rcc2 & SYSCON_RCC2_USERCC2)
+ {
+ putreg32(rcc2, LM3S_SYSCON_RCC2);
+ putreg32(rcc, LM3S_SYSCON_RCC);
+ }
+ else
+ {
+ putreg32(rcc, LM3S_SYSCON_RCC);
+ putreg32(rcc2, LM3S_SYSCON_RCC2);
+ }
+
+ /* Wait for the new crystal value and oscillator source to take effect */
+
+ lm3s_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, wail untill the PLL is locked */
+
+ lm3s_plllock();
+
+ /* Then enable the PLL */
+
+ rcc &= ~SYSCON_RCC_BYPASS;
+ rcc2 &= ~SYSCON_RCC2_BYPASS2;
+ }
+
+ /* Now we can set the final RCC/RCC2 values */
+
+ putreg32(rcc, LM3S_SYSCON_RCC);
+ putreg32(rcc2, LM3S_SYSCON_RCC2);
+
+ /* Wait for the system divider to be effective */
+
+ lm3s_delay(6);
+}
+
+/****************************************************************************
+ * Name: up_clockconfig
+ *
+ * Description:
+ * Called early in the bootsequence (before .data and .bss are available)
+ * in order to configure initial clocking.
+ *
+ ****************************************************************************/
+
+void up_clockconfig(void)
+{
+#ifdef CONFIG_LM3S_REVA2
+ /* Some early silicon returned an increase LDO voltage or 2.75V to work
+ * around a PLL bug
+ */
+
+ putreg32(SYSCON_LPDOPCTL_2750MV, LM3S_SYSCON_LDOPCTL);
+#endif
+
+ /* Set the clocking to run with the default settings provided in the board.h
+ * header file
+ */
+
+ lm3s_clockconfig(LM3S_RCC_VALUE, LM3S_RCC2_VALUE);
+}
+
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_syscontrol.h b/nuttx/arch/arm/src/lm3s/lm3s_syscontrol.h
new file mode 100644
index 000000000..c59b921c4
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_syscontrol.h
@@ -0,0 +1,495 @@
+/************************************************************************************
+ * arch/arm/src/lm3s/lm3s_syscontrol.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_LM3S_LM3S_SYSCONTROL_H
+#define __ARCH_ARM_SRC_LM3S_LM3S_SYSCONTROL_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* System Control Register Offsets **************************************************/
+
+#define LM3S_SYSCON_DID0_OFFSET 0x000 /* Device Identification 0 */
+#define LM3S_SYSCON_DID1_OFFSET 0x004 /* Device Identification 1 */
+#define LM3S_SYSCON_DC0_OFFSET 0x008 /* Device Capabilities 0 */
+#define LM3S_SYSCON_DC1_OFFSET 0x010 /* Device Capabilities 1 */
+#define LM3S_SYSCON_DC2_OFFSET 0x014 /* Device Capabilities 2 */
+#define LM3S_SYSCON_DC3_OFFSET 0x018 /* Device Capabilities 3 */
+#define LM3S_SYSCON_DC4_OFFSET 0x01c /* Device Capabilities 4 */
+#define LM3S_SYSCON_PBORCTL_OFFSET 0x030 /* Brown-Out Reset Control */
+#define LM3S_SYSCON_LDOPCTL_OFFSET 0x034 /* LDO Power Control */
+#define LM3S_SYSCON_SRCR0_OFFSET 0x040 /* Software Reset Control 0 */
+#define LM3S_SYSCON_SRCR1_OFFSET 0x044 /* Software Reset Control 1 */
+#define LM3S_SYSCON_SRCR2_OFFSET 0x048 /* Software Reset Control 2*/
+#define LM3S_SYSCON_RIS_OFFSET 0x050 /* Raw Interrupt Status */
+#define LM3S_SYSCON_IMC_OFFSET 0x054 /* Interrupt Mask Control */
+#define LM3S_SYSCON_MISC_OFFSET 0x058 /* Masked Interrupt Status and Clear */
+#define LM3S_SYSCON_RESC_OFFSET 0x05c /* Reset Cause */
+#define LM3S_SYSCON_RCC_OFFSET 0x060 /* Run-Mode Clock Configuration */
+#define LM3S_SYSCON_PLLCFG_OFFSET 0x064 /* XTAL to PLL Translation */
+#define LM3S_SYSCON_RCC2_OFFSET 0x070 /* Run-Mode Clock Configuration 2 */
+#define LM3S_SYSCON_RCGC0_OFFSET 0x100 /* Run Mode Clock Gating Control Register 0 */
+#define LM3S_SYSCON_RCGC1_OFFSET 0x104 /* Run Mode Clock Gating Control Register 1 */
+#define LM3S_SYSCON_RCGC2_OFFSET 0x108 /* Run Mode Clock Gating Control Register 2 */
+#define LM3S_SYSCON_SCGC0_OFFSET 0x110 /* Sleep Mode Clock Gating Control Register 0 */
+#define LM3S_SYSCON_SCGC1_OFFSET 0x114 /* Sleep Mode Clock Gating Control Register 1 */
+#define LM3S_SYSCON_SCGC2_OFFSET 0x118 /* Sleep Mode Clock Gating Control Register 2 */
+#define LM3S_SYSCON_DCGC0_OFFSET 0x120 /* Deep Sleep Mode Clock Gating Control Register 0 */
+#define LM3S_SYSCON_DCGC1_OFFSET 0x124 /* Deep Sleep Mode Clock Gating Control Register 1 */
+#define LM3S_SYSCON_DCGC2_OFFSET 0x128 /* Deep Sleep Mode Clock Gating Control Register 2 */
+#define LM3S_SYSCON_DSLPCLKCFG_OFFSET 0x144 /* Deep Sleep Clock Configuration*/
+
+/* System Control Register Addresses ************************************************/
+
+#define LM3S_SYSCON_DID0 (LM3S_SYSCON_BASE + LM3S_SYSCON_DID0_OFFSET)
+#define LM3S_SYSCON_DID1 (LM3S_SYSCON_BASE + LM3S_SYSCON_DID1_OFFSET)
+#define LM3S_SYSCON_DC0 (LM3S_SYSCON_BASE + LM3S_SYSCON_DC0_OFFSET)
+#define LM3S_SYSCON_DC1 (LM3S_SYSCON_BASE + LM3S_SYSCON_DC1_OFFSET)
+#define LM3S_SYSCON_DC2 (LM3S_SYSCON_BASE + LM3S_SYSCON_DC2_OFFSET)
+#define LM3S_SYSCON_DC3 (LM3S_SYSCON_BASE + LM3S_SYSCON_DC3_OFFSET)
+#define LM3S_SYSCON_DC4 (LM3S_SYSCON_BASE + LM3S_SYSCON_DC4_OFFSET)
+#define LM3S_SYSCON_PBORCTL (LM3S_SYSCON_BASE + LM3S_SYSCON_PBORCTL_OFFSET)
+#define LM3S_SYSCON_LDOPCTL (LM3S_SYSCON_BASE + LM3S_SYSCON_LDOPCTL_OFFSET)
+#define LM3S_SYSCON_SRCR0 (LM3S_SYSCON_BASE + LM3S_SYSCON_SRCR0_OFFSET)
+#define LM3S_SYSCON_SRCR1 (LM3S_SYSCON_BASE + LM3S_SYSCON_SRCR1_OFFSET)
+#define LM3S_SYSCON_SRCR2 (LM3S_SYSCON_BASE + LM3S_SYSCON_SRCR2_OFFSET)
+#define LM3S_SYSCON_RIS (LM3S_SYSCON_BASE + LM3S_SYSCON_RIS_OFFSET)
+#define LM3S_SYSCON_IMC (LM3S_SYSCON_BASE + LM3S_SYSCON_IMC_OFFSET)
+#define LM3S_SYSCON_MISC (LM3S_SYSCON_BASE + LM3S_SYSCON_MISC_OFFSET)
+#define LM3S_SYSCON_RESC (LM3S_SYSCON_BASE + LM3S_SYSCON_RESC_OFFSET)
+#define LM3S_SYSCON_RCC (LM3S_SYSCON_BASE + LM3S_SYSCON_RCC_OFFSET)
+#define LM3S_SYSCON_PLLCFG (LM3S_SYSCON_BASE + LM3S_SYSCON_PLLCFG_OFFSET)
+#define LM3S_SYSCON_RCC2 (LM3S_SYSCON_BASE + LM3S_SYSCON_RCC2_OFFSET)
+#define LM3S_SYSCON_RCGC0 (LM3S_SYSCON_BASE + LM3S_SYSCON_RCGC0_OFFSET)
+#define LM3S_SYSCON_RCGC1 (LM3S_SYSCON_BASE + LM3S_SYSCON_RCGC1_OFFSET)
+#define LM3S_SYSCON_RCGC2 (LM3S_SYSCON_BASE + LM3S_SYSCON_RCGC2_OFFSET)
+#define LM3S_SYSCON_SCGC0 (LM3S_SYSCON_BASE + LM3S_SYSCON_SCGC0_OFFSET)
+#define LM3S_SYSCON_SCGC1 (LM3S_SYSCON_BASE + LM3S_SYSCON_SCGC1_OFFSET)
+#define LM3S_SYSCON_SCGC2 (LM3S_SYSCON_BASE + LM3S_SYSCON_SCGC2_OFFSET)
+#define LM3S_SYSCON_DCGC0 (LM3S_SYSCON_BASE + LM3S_SYSCON_DCGC0_OFFSET)
+#define LM3S_SYSCON_DCGC1 (LM3S_SYSCON_BASE + LM3S_SYSCON_DCGC1_OFFSET)
+#define LM3S_SYSCON_DCGC2 (LM3S_SYSCON_BASE + LM3S_SYSCON_DCGC2_OFFSET)
+#define LM3S_SYSCON_DSLPCLKCFG (LM3S_SYSCON_BASE + LM3S_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_IOSC (1 << SYSCON_RCC_OSCSRC_SHIFT) /* Internal oscillator (reset) */
+# define SYSCON_RCC_OSCSRC_IOSC4 (2 << SYSCON_RCC_OSCSRC_SHIFT) /* Internal oscillator / 4 */
+# define SYSCON_RCC_OSCSRC_30KHZ (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_IOSC (1 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Internal oscillator (reset) */
+# define SYSCON_RCC2_OSCSRC2_IOSC4 (2 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Internal oscillator / 4 */
+# define SYSCON_RCC2_OSCSRC2_30KHZ (3 << SYSCON_RCC2_OSCSRC2_SHIFT) /* 30KHz internal oscillator */
+# define SYSCON_RCC2_OSCSRC2_32KHZ (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_LM3S_LM3S_SYSCONTROL_H */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_timer.h b/nuttx/arch/arm/src/lm3s/lm3s_timer.h
new file mode 100644
index 000000000..7c4166293
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_timer.h
@@ -0,0 +1,125 @@
+/************************************************************************************
+ * arch/arm/src/lm3s/lm3s_timer.h
+ *
+ * Copyright (C) 2012 Max Nekludov. All rights reserved.
+ * Author: Max Nekludov <macscomp@gmail.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_LM3S_LM3S_TIMER_H
+#define __ARCH_ARM_SRC_LM3S_LM3S_TIMER_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Timer register offsets ***********************************************************/
+
+#define TIMER_GPTMCFG_OFFSET 0x000
+#define TIMER_GPTMTAMR_OFFSET 0x004
+#define TIMER_GPTMCTL_OFFSET 0x00C
+#define TIMER_GPTMIMR_OFFSET 0x018
+#define TIMER_GPTMRIS_OFFSET 0x01C
+#define TIMER_GPTMICR_OFFSET 0x024
+#define TIMER_GPTMTAILR_OFFSET 0x028
+#define TIMER_GPTMTAR_OFFSET 0x048
+
+/* SSI register addresses ***********************************************************/
+
+#define LM3S_TIMER_BASE(n) (LM3S_TIMER0_BASE + (n)*0x01000)
+
+#define LM3S_TIMER_GPTMCFG(n) (LM3S_TIMER_BASE(n) + TIMER_GPTMCFG_OFFSET)
+#define LM3S_TIMER_GPTMTAMR(n) (LM3S_TIMER_BASE(n) + TIMER_GPTMTAMR_OFFSET)
+#define LM3S_TIMER_GPTMCTL(n) (LM3S_TIMER_BASE(n) + TIMER_GPTMCTL_OFFSET)
+#define LM3S_TIMER_GPTMIMR(n) (LM3S_TIMER_BASE(n) + TIMER_GPTMIMR_OFFSET)
+#define LM3S_TIMER_GPTMRIS(n) (LM3S_TIMER_BASE(n) + TIMER_GPTMRIS_OFFSET)
+#define LM3S_TIMER_GPTMICR(n) (LM3S_TIMER_BASE(n) + TIMER_GPTMICR_OFFSET)
+#define LM3S_TIMER_GPTMTAILR(n) (LM3S_TIMER_BASE(n) + TIMER_GPTMTAILR_OFFSET)
+#define LM3S_TIMER_GPTMTAR(n) (LM3S_TIMER_BASE(n) + TIMER_GPTMTAR_OFFSET)
+
+/* SSI register bit defitiions ******************************************************/
+
+/* GPTM Configuration (GPTMCFG), offset 0x000 */
+
+#define TIMER_GPTMCFG_CFG_SHIFT 0 /* Bits 2-0: GPTM Configuration */
+#define TIMER_GPTM_CFG_MASK (0x07 << TIMER_GPTMCFG_CFG_SHIFT)
+#define TIMER_GPTMCFG_CFG_32 (0 << TIMER_GPTMCFG_CFG_SHIFT) /* 32-bit timer configuration */
+#define TIMER_GPTMCFG_CFG_RTC (1 << TIMER_GPTMCFG_CFG_SHIFT) /* 32-bit real-time clock (RTC) counter configuration */
+#define TIMER_GPTMCFG_CFG_16 (1 << TIMER_GPTMCFG_CFG_SHIFT) /* 16-bit timer configuration */
+
+/* GPTM Timer A Mode (GPTMTAMR), offset 0x004 */
+
+#define TIMER_GPTMTAMR_TAMR_SHIFT 0 /* Bits 1-0: GPTM Timer A Mode */
+#define TIMER_GPTMTAMR_TAMR_MASK (0x03 << TIMER_GPTMTAMR_TAMR_SHIFT)
+#define TIMER_GPTMTAMR_TAMR_ONESHOT (1 << TIMER_GPTMTAMR_TAMR_SHIFT) /* One-Shot Timer mode */
+#define TIMER_GPTMTAMR_TAMR_PERIODIC (2 << TIMER_GPTMTAMR_TAMR_SHIFT) /* Periodic Timer mode */
+#define TIMER_GPTMTAMR_TAMR_CAPTURE (3 << TIMER_GPTMTAMR_TAMR_SHIFT) /* Capture mode */
+#define TIMER_GPTMTAMR_TACMR_SHIFT 2 /* Bits 2: GPTM Timer A Capture Mode */
+#define TIMER_GPTMTAMR_TACMR_MASK (0x01 << TIMER_GPTMTAMR_TACMR_SHIFT)
+#define TIMER_GPTMTAMR_TACMR_EDGECOUNT (0 << TIMER_GPTMTAMR_TACMR_SHIFT) /* Edge-Count mode */
+#define TIMER_GPTMTAMR_TACMR_EDGETIME (1 << TIMER_GPTMTAMR_TACMR_SHIFT) /* Edge-Time mode */
+#define TIMER_GPTMTAMR_TAAMS_SHIFT 3 /* Bits 3: GPTM Timer A Alternate Mode Select */
+#define TIMER_GPTMTAMR_TAAMS_MASK (0x01 << TIMER_GPTMTAMR_TAAMS_SHIFT)
+#define TIMER_GPTMTAMR_TAAMS_CAPTURE (0 << TIMER_GPTMTAMR_TAAMS_SHIFT) /* Capture mode is enabled */
+#define TIMER_GPTMTAMR_TAAMS_PWM (1 << TIMER_GPTMTAMR_TAAMS_SHIFT) /* PWM mode is enabled */
+#define TIMER_GPTMTAMR_TACDIR_SHIFT 4 /* Bits 4: GPTM Timer A Count Direction */
+#define TIMER_GPTMTAMR_TACDIR_MASK (0x01 << TIMER_GPTMTAMR_TACDIR_SHIFT)
+#define TIMER_GPTMTAMR_TACDIR_DOWN (0 << TIMER_GPTMTAMR_TACDIR_SHIFT) /* The timer counts down */
+#define TIMER_GPTMTAMR_TACDIR_UP (1 << TIMER_GPTMTAMR_TACDIR_SHIFT) /* When in one-shot or periodic mode, the timer counts up */
+#define TIMER_GPTMTAMR_TAMIE_SHIFT 5 /* Bits 5: GPTM Timer A Match Interrupt Enable */
+#define TIMER_GPTMTAMR_TAMIE_MASK (0x01 << TIMER_GPTMTAMR_TAMIE_SHIFT)
+
+/* GPTM Control (GPTMCTL), offset 0x00C */
+
+#define TIMER_GPTMCTL_TAEN_SHIFT 0 /* Bits 0: GPTM Timer A Enable */
+#define TIMER_GPTMCTL_TAEN_MASK (0x01 << TIMER_GPTMCTL_TAEN_SHIFT)
+#define TIMER_GPTMCTL_TASTALL_SHIFT 1 /* Bits 1: GPTM Timer A Stall Enable */
+#define TIMER_GPTMCTL_TASTALL_MASK (0x01 << TIMER_GPTMCTL_TASTALL_SHIFT)
+
+/* GPTM Interrupt Mask (GPTMIMR), offset 0x018 */
+
+#define TIMER_GPTMIMR_TATOIM_SHIFT 0 /* Bits 0: GPTM Timer A Time-Out Interrupt Mask */
+#define TIMER_GPTMIMR_TATOIM_MASK (0x01 << TIMER_GPTMIMR_TATOIM_SHIFT)
+
+/* GPTM Raw Interrupt Status (GPTMRIS), offset 0x01C */
+
+#define TIMER_GPTMRIS_TATORIS_SHIFT 0 /* Bits 0: GPTM Timer A Time-Out Raw Interrupt */
+#define TIMER_GPTMRIS_TATORIS_MASK (0x01 << TIMER_GPTMRIS_TATORIS_SHIFT)
+
+/* GPTM Interrupt Clear (GPTMICR), offset 0x024 */
+
+#define TIMER_GPTMICR_TATOCINT_SHIFT 0 /* Bits 0: GPTM Timer A Time-Out Raw Interrupt Clear*/
+#define TIMER_GPTMICR_TATOCINT_MASK (0x01 << TIMER_GPTMICR_TATOCINT_SHIFT)
+
+#endif /* __ARCH_ARM_SRC_LM3S_LM3S_TIMER_H */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_timerisr.c b/nuttx/arch/arm/src/lm3s/lm3s_timerisr.c
new file mode 100644
index 000000000..4d42af597
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_timerisr.c
@@ -0,0 +1,143 @@
+/****************************************************************************
+ * arch/arm/src/lm3s/lm3s_timerisr.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <time.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "nvic.h"
+#include "clock_internal.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lm3s_internal.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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize
+ * the timer interrupt.
+ *
+ ****************************************************************************/
+
+void up_timerinit(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(LM3S_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(LM3S_IRQ_SYSTICK);
+}
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_uart.h b/nuttx/arch/arm/src/lm3s/lm3s_uart.h
new file mode 100644
index 000000000..91bfb2266
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_uart.h
@@ -0,0 +1,347 @@
+/************************************************************************************
+ * arch/arm/src/lm3s/lm3s_uart.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_LM3S_LM3S_UART_H
+#define __ARCH_ARM_SRC_LM3S_LM3S_UART_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* UART register offsets ************************************************************/
+
+#define LM3S_UART_DR_OFFSET 0x000 /* UART Data */
+#define LM3S_UART_RSR_OFFSET 0x004 /* UART Receive Status */
+#define LM3S_UART_ECR_OFFSET 0x004 /* UART Error Clear */
+#define LM3S_UART_FR_OFFSET 0x018 /* UART Flag */
+#define LM3S_UART_ILPR_OFFSET 0x020 /* UART IrDA Low-Power Register */
+#define LM3S_UART_IBRD_OFFSET 0x024 /* UART Integer Baud-Rate Divisor*/
+#define LM3S_UART_FBRD_OFFSET 0x028 /* UART Fractional Baud-Rate Divisor */
+#define LM3S_UART_LCRH_OFFSET 0x02c /* UART Line Control */
+#define LM3S_UART_CTL_OFFSET 0x030 /* UART Control */
+#define LM3S_UART_IFLS_OFFSET 0x034 /* UART Interrupt FIFO Level Select */
+#define LM3S_UART_IM_OFFSET 0x038 /* UART Interrupt Mask */
+#define LM3S_UART_RIS_OFFSET 0x03c /* UART Raw Interrupt Status */
+#define LM3S_UART_MIS_OFFSET 0x040 /* UART Masked Interrupt Status */
+#define LM3S_UART_ICR_OFFSET 0x044 /* UART Interrupt Clear */
+#define LM3S_UART_PERIPHID4_OFFSET 0xfd0 /* UART Peripheral Identification 4 */
+#define LM3S_UART_PERIPHID5_OFFSET 0xfd4 /* UART Peripheral Identification 5 */
+#define LM3S_UART_PERIPHID6_OFFSET 0xfd8 /* UART Peripheral Identification 6 */
+#define LM3S_UART_PERIPHID7_OFFSET 0xfdc /* UART Peripheral Identification 7 */
+#define LM3S_UART_PERIPHID0_OFFSET 0xfe0 /* UART Peripheral Identification 0 */
+#define LM3S_UART_PERIPHID1_OFFSET 0xfe4 /* UART Peripheral Identification 1 */
+#define LM3S_UART_PERIPHID2_OFFSET 0xfe8 /* UART Peripheral Identification 2 */
+#define LM3S_UART_PERIPHID3_OFFSET 0xfec /* UART Peripheral Identification 3 */
+#define LM3S_UART_PCELLID0_OFFSET 0xff0 /* UART PrimeCell Identification 0 */
+#define LM3S_UART_PCELLID1_OFFSET 0xff4 /* UART PrimeCell Identification 1 */
+#define LM3S_UART_PCELLID2_OFFSET 0xff8 /* UART PrimeCell Identification 2 */
+#define LM3S_UART_PCELLID3_OFFSET 0xffc /* UART PrimeCell Identification 3 */
+
+/* UART register addresses **********************************************************/
+
+#define LM3S_UART_BASE(n) (LM3S_UART0_BASE + (n)*0x01000)
+
+#define LM3S_UART_DR(n) (LM3S_UART_BASE(n) + LM3S_UART_DR_OFFSET)
+#define LM3S_UART_RSR(n) (LM3S_UART_BASE(n) + LM3S_UART_RSR_OFFSET)
+#define LM3S_UART_ECR(n) (LM3S_UART_BASE(n) + LM3S_UART_ECR_OFFSET)
+#define LM3S_UART_FR(n) (LM3S_UART_BASE(n) + LM3S_UART_FR_OFFSET)
+#define LM3S_UART_ILPR(n) (LM3S_UART_BASE(n) + LM3S_UART_ILPR_OFFSET)
+#define LM3S_UART_IBRD(n) (LM3S_UART_BASE(n) + LM3S_UART_IBRD_OFFSET)
+#define LM3S_UART_FBRD(n) (LM3S_UART_BASE(n) + LM3S_UART_FBRD_OFFSET)
+#define LM3S_UART_LCRH(n) (LM3S_UART_BASE(n) + LM3S_UART_LCRH_OFFSET)
+#define LM3S_UART_CTL(n) (LM3S_UART_BASE(n) + LM3S_UART_CTL_OFFSET)
+#define LM3S_UART_IFLS(n) (LM3S_UART_BASE(n) + LM3S_UART_IFLS_OFFSET)
+#define LM3S_UART_IM(n) (LM3S_UART_BASE(n) + LM3S_UART_IM_OFFSET)
+#define LM3S_UART_RIS(n) (LM3S_UART_BASE(n) + LM3S_UART_RIS_OFFSET)
+#define LM3S_UART_MIS(n) (LM3S_UART_BASE(n) + LM3S_UART_MIS_OFFSET)
+#define LM3S_UART_ICR(n) (LM3S_UART_BASE(n) + LM3S_UART_ICR_OFFSET)
+#define LM3S_UART_PERIPHID4(n) (LM3S_UART_BASE(n) + LM3S_UART_PERIPHID4_OFFSET)
+#define LM3S_UART_PERIPHID5(n) (LM3S_UART_BASE(n) + LM3S_UART_PERIPHID5_OFFSET)
+#define LM3S_UART_PERIPHID6(n) (LM3S_UART_BASE(n) + LM3S_UART_PERIPHID6_OFFSET)
+#define LM3S_UART_PERIPHID7(n) (LM3S_UART_BASE(n) + LM3S_UART_PERIPHID7_OFFSET)
+#define LM3S_UART_PERIPHID0(n) (LM3S_UART_BASE(n) + LM3S_UART_PERIPHID0_OFFSET)
+#define LM3S_UART_PERIPHID1(n) (LM3S_UART_BASE(n) + LM3S_UART_PERIPHID1_OFFSET)
+#define LM3S_UART_PERIPHID2(n) (LM3S_UART_BASE(n) + LM3S_UART_PERIPHID2_OFFSET)
+#define LM3S_UART_PERIPHID3(n) (LM3S_UART_BASE(n) + LM3S_UART_PERIPHID3_OFFSET)
+#define LM3S_UART_PCELLID0(n) (LM3S_UART_BASE(n) + LM3S_UART_PCELLID0_OFFSET)
+#define LM3S_UART_PCELLID1(n) (LM3S_UART_BASE(n) + LM3S_UART_PCELLID1_OFFSET)
+#define LM3S_UART_PCELLID2(n) (LM3S_UART_BASE(n) + LM3S_UART_PCELLID2_OFFSET)
+#define LM3S_UART_PCELLID3(n) (LM3S_UART_BASE(n) + LM3S_UART_PCELLID3_OFFSET)
+
+#define LM3S_UART0_DR (LM3S_UART0_BASE + LM3S_UART_TDR_OFFSET)
+#define LM3S_UART0_RSR (LM3S_UART0_BASE + LM3S_UART_RSR_OFFSET)
+#define LM3S_UART0_ECR (LM3S_UART0_BASE + LM3S_UART_ECR_OFFSET)
+#define LM3S_UART0_FR (LM3S_UART0_BASE + LM3S_UART_FR_OFFSET)
+#define LM3S_UART0_ILPR (LM3S_UART0_BASE + LM3S_UART_ILPR_OFFSET)
+#define LM3S_UART0_IBRD (LM3S_UART0_BASE + LM3S_UART_IBRD_OFFSET)
+#define LM3S_UART0_FBRD (LM3S_UART0_BASE + LM3S_UART_FBRD_OFFSET)
+#define LM3S_UART0_LCRH (LM3S_UART0_BASE + LM3S_UART_LCRH_OFFSET)
+#define LM3S_UART0_CTL (LM3S_UART0_BASE + LM3S_UART_CTL_OFFSET)
+#define LM3S_UART0_IFLS (LM3S_UART0_BASE + LM3S_UART_IFLS_OFFSET)
+#define LM3S_UART0_IM (LM3S_UART0_BASE + LM3S_UART_IM_OFFSET)
+#define LM3S_UART0_RIS (LM3S_UART0_BASE + LM3S_UART_RIS_OFFSET)
+#define LM3S_UART0_MIS (LM3S_UART0_BASE + LM3S_UART_MIS_OFFSET)
+#define LM3S_UART0_ICR (LM3S_UART0_BASE + LM3S_UART_ICR_OFFSET)
+#define LM3S_UART0_PERIPHID4 (LM3S_UART0_BASE + LM3S_UART_PERIPHID4_OFFSET)
+#define LM3S_UART0_PERIPHID5 (LM3S_UART0_BASE + LM3S_UART_PERIPHID5_OFFSET)
+#define LM3S_UART0_PERIPHID6 (LM3S_UART0_BASE + LM3S_UART_PERIPHID6_OFFSET)
+#define LM3S_UART0_PERIPHID7 (LM3S_UART0_BASE + LM3S_UART_PERIPHID7_OFFSET)
+#define LM3S_UART0_PERIPHID0 (LM3S_UART0_BASE + LM3S_UART_PERIPHID0_OFFSET)
+#define LM3S_UART0_PERIPHID1 (LM3S_UART0_BASE + LM3S_UART_PERIPHID1_OFFSET)
+#define LM3S_UART0_PERIPHID2 (LM3S_UART0_BASE + LM3S_UART_PERIPHID2_OFFSET)
+#define LM3S_UART0_PERIPHID3 (LM3S_UART0_BASE + LM3S_UART_PERIPHID3_OFFSET)
+#define LM3S_UART0_PCELLID0 (LM3S_UART0_BASE + LM3S_UART_PCELLID0_OFFSET)
+#define LM3S_UART0_PCELLID1 (LM3S_UART0_BASE + LM3S_UART_PCELLID1_OFFSET)
+#define LM3S_UART0_PCELLID2 (LM3S_UART0_BASE + LM3S_UART_PCELLID2_OFFSET)
+#define LM3S_UART0_PCELLID3 (LM3S_UART0_BASE + LM3S_UART_PCELLID3_OFFSET)
+
+#define LM3S_UART1_DR (LM3S_UART1_BASE + LM3S_UART_DR_OFFSET)
+#define LM3S_UART1_RSR (LM3S_UART1_BASE + LM3S_UART_RSR_OFFSET)
+#define LM3S_UART1_ECR (LM3S_UART1_BASE + LM3S_UART_ECR_OFFSET)
+#define LM3S_UART1_FR (LM3S_UART1_BASE + LM3S_UART_FR_OFFSET)
+#define LM3S_UART1_ILPR (LM3S_UART1_BASE + LM3S_UART_ILPR_OFFSET)
+#define LM3S_UART1_IBRD (LM3S_UART1_BASE + LM3S_UART_IBRD_OFFSET)
+#define LM3S_UART1_FBRD (LM3S_UART1_BASE + LM3S_UART_FBRD_OFFSET)
+#define LM3S_UART1_LCRH (LM3S_UART1_BASE + LM3S_UART_LCRH_OFFSET)
+#define LM3S_UART1_CTL (LM3S_UART1_BASE + LM3S_UART_CTL_OFFSET)
+#define LM3S_UART1_IFLS (LM3S_UART1_BASE + LM3S_UART_IFLS_OFFSET)
+#define LM3S_UART1_IM (LM3S_UART1_BASE + LM3S_UART_IM_OFFSET)
+#define LM3S_UART1_RIS (LM3S_UART1_BASE + LM3S_UART_RIS_OFFSET)
+#define LM3S_UART1_MIS (LM3S_UART1_BASE + LM3S_UART_MIS_OFFSET)
+#define LM3S_UART1_ICR (LM3S_UART1_BASE + LM3S_UART_ICR_OFFSET)
+#define LM3S_UART1_PERIPHID4 (LM3S_UART1_BASE + LM3S_UART_PERIPHID4_OFFSET)
+#define LM3S_UART1_PERIPHID5 (LM3S_UART1_BASE + LM3S_UART_PERIPHID5_OFFSET)
+#define LM3S_UART1_PERIPHID6 (LM3S_UART1_BASE + LM3S_UART_PERIPHID6_OFFSET)
+#define LM3S_UART1_PERIPHID7 (LM3S_UART1_BASE + LM3S_UART_PERIPHID7_OFFSET)
+#define LM3S_UART1_PERIPHID0 (LM3S_UART1_BASE + LM3S_UART_PERIPHID0_OFFSET)
+#define LM3S_UART1_PERIPHID1 (LM3S_UART1_BASE + LM3S_UART_PERIPHID1_OFFSET)
+#define LM3S_UART1_PERIPHID2 (LM3S_UART1_BASE + LM3S_UART_PERIPHID2_OFFSET)
+#define LM3S_UART1_PERIPHID3 (LM3S_UART1_BASE + LM3S_UART_PERIPHID3_OFFSET)
+#define LM3S_UART1_PCELLID0 (LM3S_UART1_BASE + LM3S_UART_PCELLID0_OFFSET)
+#define LM3S_UART1_PCELLID1 (LM3S_UART1_BASE + LM3S_UART_PCELLID1_OFFSET)
+#define LM3S_UART1_PCELLID2 (LM3S_UART1_BASE + LM3S_UART_PCELLID2_OFFSET)
+#define LM3S_UART1_PCELLID3 (LM3S_UART1_BASE + LM3S_UART_PCELLID3_OFFSET)
+
+/* UART register bit settings *******************************************************/
+
+/* UART Data (DR), offset 0x000 */
+
+#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), offset 0x004 */
+
+#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), offset 0x018 */
+
+#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 */
+
+/* UART IrDA Low-Power Register (ILPR), offset 0x020 */
+
+#define UART_ILPR_DVSR_MASK (0xff) /* Bits 7-0: IrDA Low-Power Divisor */
+
+/* UART Integer Baud-Rate Divisor (IBRD), offset 0x024 */
+
+#define UART_IBRD_DIVINT_MASK (0xffff) /* Bits 15-0: Integer Baud-Rate Divisor */
+
+/* UART Fractional Baud-Rate Divisor (UARTFBRD), offset 0x028 */
+
+#define UART_FBRD_DIVFRAC_MASK (0x3f) /* Bits 5-0: Fractional Baud-Rate Divisor */
+
+/* Register 7: UART Line Control (LCRH), offset 0x02C */
+
+#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), offset 0x030 */
+
+#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 */
+#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 */
+
+/* UART Interrupt FIFO Level Select (IFLS), offset 0x034 */
+
+#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), offset 0x038 */
+
+#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 */
+
+
+/* UART Raw Interrupt Status (RIS), offset 0x03c */
+
+#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 */
+
+/* UART Masked Interrupt Status (MIS), offset 0x040 */
+
+#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 */
+
+/* UART Interrupt Clear (ICR), offset 0x044 */
+
+#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
+ */
+
+/* UART Peripheral Identification 4 (PERIPHID4), offset 0xfd0 */
+
+#define UART_PERIPHID4_MASK (0xff) /* UART Peripheral ID Register[7:0] */
+
+/* UART Peripheral Identification 5 (UARTPERIPHID5), offset 0xfd4 */
+
+#define UART_PERIPHID5_MASK (0xff) /* UART Peripheral ID Register[15:8] */
+
+/* UART Peripheral Identification 6 (UARTPERIPHID6), offset 0xfd8 */
+
+#define UART_PERIPHID6_MASK (0xff) /* UART Peripheral ID Register[23:16] */
+
+/* UART Peripheral Identification 7 (UARTPERIPHID7), offset 0xfdc */
+
+#define UART_PERIPHID7_MASK (0xff) /* UART Peripheral ID Register[31:24] */
+
+/* UART Peripheral Identification 0 (UARTPERIPHID0), offset 0xfe0 */
+
+#define UART_PERIPHID0_MASK (0xff) /* UART Peripheral ID Register[7:0] */
+
+/* UART Peripheral Identification 1 (UARTPERIPHID1), offset 0xfe4 */
+
+#define UART_PERIPHID1_MASK (0xff) /* UART Peripheral ID Register[15:8] */
+
+/* UART Peripheral Identification 2 (UARTPERIPHID2), offset 0xfe8 */
+
+#define UART_PERIPHID2_MASK (0xff) /* UART Peripheral ID Register[23:16] */
+
+/* UART Peripheral Identification 3 (UARTPERIPHID3), offset 0xfec */
+
+#define UART_PERIPHID3_MASK (0xff) /* UART Peripheral ID Register[31:24] */
+
+/* UART PrimeCell Identification 0 (CELLID0), offset 0xff0 */
+
+#define UART_CELLID0_MASK (0xff) /* UART PrimeCell ID Register[7:0] */
+
+/* UART PrimeCell Identification 1 (UARTPCELLID1), offset 0xff4 */
+
+#define UART_CELLID1_MASK (0xff) /* UART PrimeCell ID Register[15:8] */
+
+/* UART PrimeCell Identification 2 (UARTPCELLID2), offset 0xff8 */
+
+#define UART_CELLID02MASK (0xff) /* UART PrimeCell ID Register[23:16] */
+
+/* UART PrimeCell Identification 3 (UARTPCELLID3), offset 0xffc */
+
+#define UART_CELLID3_MASK (0xff) /* UART PrimeCell ID Register[31:24] */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LM3S_LM3S_UART_H */
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_vectors.S b/nuttx/arch/arm/src/lm3s/lm3s_vectors.S
new file mode 100644
index 000000000..71db122a0
--- /dev/null
+++ b/nuttx/arch/arm/src/lm3s/lm3s_vectors.S
@@ -0,0 +1,805 @@
+/************************************************************************************
+ * arch/arm/src/lm3s/lm3s_vectors.S
+ * arch/arm/src/chip/lm3s_vectors.S
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <arch/irq.h>
+
+/************************************************************************************
+ * Preprocessor Definitions
+ ************************************************************************************/
+
+/* 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-4)
+
+/* The Cortex-M3 return from interrupt is unusual. We provide the following special
+ * address to the BX instruction. The particular value also forces a return to
+ * thread mode and covers state from the main stack point, the MSP (vs. the MSP).
+ */
+
+#define EXC_RETURN 0xfffffff9
+
+/************************************************************************************
+ * Global Symbols
+ ************************************************************************************/
+
+ .globl __start
+
+ .syntax unified
+ .thumb
+ .file "lm3s_vectors.S"
+
+/************************************************************************************
+ * 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 lm3s_irqcommon
+ .endm
+
+/************************************************************************************
+ * Vectors
+ ************************************************************************************/
+
+ .section .vectors, "ax"
+ .code 16
+ .align 2
+ .globl lm3s_vectors
+ .type lm3s_vectors, function
+
+lm3s_vectors:
+
+/* Processor Exceptions */
+
+ .word IDLE_STACK /* Vector 0: Reset stack pointer */
+ .word __start /* Vector 1: Reset vector */
+ .word lm3s_nmi /* Vector 2: Non-Maskable Interrupt (NMI) */
+ .word lm3s_hardfault /* Vector 3: Hard fault */
+ .word lm3s_mpu /* Vector 4: Memory management (MPU) */
+ .word lm3s_busfault /* Vector 5: Bus fault */
+ .word lm3s_usagefault /* Vector 6: Usage fault */
+ .word lm3s_reserved /* Vector 7: Reserved */
+ .word lm3s_reserved /* Vector 8: Reserved */
+ .word lm3s_reserved /* Vector 9: Reserved */
+ .word lm3s_reserved /* Vector 10: Reserved */
+ .word lm3s_svcall /* Vector 11: SVC call */
+ .word lm3s_dbgmonitor /* Vector 12: Debug monitor */
+ .word lm3s_reserved /* Vector 13: Reserved */
+ .word lm3s_pendsv /* Vector 14: Pendable system service request */
+ .word lm3s_systick /* Vector 15: System tick */
+
+/* External Interrupts */
+
+#if defined(CONFIG_ARCH_CHIP_LM3S6918)
+ .word lm3s_gpioa /* Vector 16: GPIO Port A */
+ .word lm3s_gpiob /* Vector 17: GPIO Port B */
+ .word lm3s_gpioc /* Vector 18: GPIO Port C */
+ .word lm3s_gpiod /* Vector 19: GPIO Port D */
+ .word lm3s_gpioe /* Vector 20: GPIO Port E */
+ .word lm3s_uart0 /* Vector 21: UART 0 */
+ .word lm3s_uart1 /* Vector 22: UART 1 */
+ .word lm3s_ssi0 /* Vector 23: SSI 0 */
+ .word lm3s_i2c0 /* Vector 24: I2C 0 */
+ .word lm3s_reserved /* Vector 25: Reserved */
+ .word lm3s_reserved /* Vector 26: Reserved */
+ .word lm3s_reserved /* Vector 27: Reserved */
+ .word lm3s_reserved /* Vector 28: Reserved */
+ .word lm3s_reserved /* Vector 29: Reserved */
+ .word lm3s_adc0 /* Vector 30: ADC Sequence 0 */
+ .word lm3s_adc1 /* Vector 31: ADC Sequence 1 */
+ .word lm3s_adc2 /* Vector 32: ADC Sequence 2 */
+ .word lm3s_adc3 /* Vector 33: ADC Sequence 3 */
+ .word lm3s_wdog /* Vector 34: Watchdog Timer */
+ .word lm3s_tmr0a /* Vector 35: Timer 0 A */
+ .word lm3s_tmr0b /* Vector 36: Timer 0 B */
+ .word lm3s_tmr1a /* Vector 37: Timer 1 A */
+ .word lm3s_tmr1b /* Vector 38: Timer 1 B */
+ .word lm3s_tmr2a /* Vector 39: Timer 2 A */
+ .word lm3s_tmr2b /* Vector 40: Timer 3 B */
+ .word lm3s_cmp0 /* Vector 41: Analog Comparator 0 */
+ .word lm3s_cmp1 /* Vector 42: Analog Comparator 1 */
+ .word lm3s_reserved /* Vector 43: Reserved */
+ .word lm3s_syscon /* Vector 44: System Control */
+ .word lm3s_flashcon /* Vector 45: FLASH Control */
+ .word lm3s_gpiof /* Vector 46: GPIO Port F */
+ .word lm3s_gpiog /* Vector 47: GPIO Port G */
+ .word lm3s_gpioh /* Vector 48: GPIO Port H */
+ .word lm3s_reserved /* Vector 49: Reserved */
+ .word lm3s_ssi1 /* Vector 50: SSI 1 */
+ .word lm3s_tmr3a /* Vector 51: Timer 3 A */
+ .word lm3s_tmr3b /* Vector 52: Timer 3 B */
+ .word lm3s_i2c1 /* Vector 53: I2C 1 */
+ .word lm3s_reserved /* Vector 54: Reserved */
+ .word lm3s_reserved /* Vector 55: Reserved */
+ .word lm3s_reserved /* Vector 56: Reserved */
+ .word lm3s_reserved /* Vector 57: Reserved */
+ .word lm3s_eth /* Vector 58: Ethernet Controller */
+ .word lm3s_hib /* Vector 59: Hibernation Module */
+ .word lm3s_reserved /* Vector 60: Reserved */
+ .word lm3s_reserved /* Vector 61: Reserved */
+ .word lm3s_reserved /* Vector 62: Reserved */
+ .word lm3s_reserved /* Vector 63: Reserved */
+ .word lm3s_reserved /* Vector 64: Reserved */
+ .word lm3s_reserved /* Vector 65: Reserved */
+ .word lm3s_reserved /* Vector 66: Reserved */
+ .word lm3s_reserved /* Vector 67: Reserved */
+ .word lm3s_reserved /* Vector 68: Reserved */
+ .word lm3s_reserved /* Vector 69: Reserved */
+ .word lm3s_reserved /* Vector 70: Reserved */
+#elif defined(CONFIG_ARCH_CHIP_LM3S6432)
+ .word lm3s_gpioa /* Vector 16: GPIO Port A */
+ .word lm3s_gpiob /* Vector 17: GPIO Port B */
+ .word lm3s_gpioc /* Vector 18: GPIO Port C */
+ .word lm3s_gpiod /* Vector 19: GPIO Port D */
+ .word lm3s_gpioe /* Vector 20: GPIO Port E */
+ .word lm3s_uart0 /* Vector 21: UART 0 */
+ .word lm3s_uart1 /* Vector 22: UART 1 */
+ .word lm3s_ssi0 /* Vector 23: SSI 0 */
+ .word lm3s_i2c0 /* Vector 24: I2C 0 */
+ .word lm3s_reserved /* Vector 25: Reserved */
+ .word lm3s_pwm0 /* Vector 26: PWM Generator 0 */
+ .word lm3s_reserved /* Vector 27: Reserved */
+ .word lm3s_reserved /* Vector 28: Reserved */
+ .word lm3s_reserved /* Vector 29: Reserved */
+ .word lm3s_adc0 /* Vector 30: ADC Sequence 0 */
+ .word lm3s_adc1 /* Vector 31: ADC Sequence 1 */
+ .word lm3s_adc2 /* Vector 32: ADC Sequence 2 */
+ .word lm3s_adc3 /* Vector 33: ADC Sequence 3 */
+ .word lm3s_wdog /* Vector 34: Watchdog Timer */
+ .word lm3s_tmr0a /* Vector 35: Timer 0 A */
+ .word lm3s_tmr0b /* Vector 36: Timer 0 B */
+ .word lm3s_tmr1a /* Vector 37: Timer 1 A */
+ .word lm3s_tmr1b /* Vector 38: Timer 1 B */
+ .word lm3s_tmr2a /* Vector 39: Timer 2 A */
+ .word lm3s_tmr2b /* Vector 40: Timer 3 B */
+ .word lm3s_cmp0 /* Vector 41: Analog Comparator 0 */
+ .word lm3s_cmp1 /* Vector 42: Analog Comparator 1 */
+ .word lm3s_reserved /* Vector 43: Reserved */
+ .word lm3s_syscon /* Vector 44: System Control */
+ .word lm3s_flashcon /* Vector 45: FLASH Control */
+ .word lm3s_gpiof /* Vector 46: GPIO Port F */
+ .word lm3s_gpiog /* Vector 47: GPIO Port G */
+ .word lm3s_reserved /* Vector 48: Reserved */
+ .word lm3s_reserved /* Vector 49: Reserved */
+ .word lm3s_reserved /* Vector 50: Reserved */
+ .word lm3s_reserved /* Vector 51: Reserved */
+ .word lm3s_reserved /* Vector 52: Reserved */
+ .word lm3s_reserved /* Vector 53: Reserved */
+ .word lm3s_reserved /* Vector 54: Reserved */
+ .word lm3s_reserved /* Vector 55: Reserved */
+ .word lm3s_reserved /* Vector 56: Reserved */
+ .word lm3s_reserved /* Vector 57: Reserved */
+ .word lm3s_eth /* Vector 58: Ethernet Controller */
+ .word lm3s_reserved /* Vector 59: Reserved */
+ .word lm3s_reserved /* Vector 60: Reserved */
+ .word lm3s_reserved /* Vector 61: Reserved */
+ .word lm3s_reserved /* Vector 62: Reserved */
+ .word lm3s_reserved /* Vector 63: Reserved */
+ .word lm3s_reserved /* Vector 64: Reserved */
+ .word lm3s_reserved /* Vector 65: Reserved */
+ .word lm3s_reserved /* Vector 66: Reserved */
+ .word lm3s_reserved /* Vector 67: Reserved */
+ .word lm3s_reserved /* Vector 68: Reserved */
+ .word lm3s_reserved /* Vector 69: Reserved */
+ .word lm3s_reserved /* Vector 70: Reserved */
+#elif defined(CONFIG_ARCH_CHIP_LM3S6965)
+ .word lm3s_gpioa /* Vector 16: GPIO Port A */
+ .word lm3s_gpiob /* Vector 17: GPIO Port B */
+ .word lm3s_gpioc /* Vector 18: GPIO Port C */
+ .word lm3s_gpiod /* Vector 19: GPIO Port D */
+ .word lm3s_gpioe /* Vector 20: GPIO Port E */
+ .word lm3s_uart0 /* Vector 21: UART 0 */
+ .word lm3s_uart1 /* Vector 22: UART 1 */
+ .word lm3s_ssi0 /* Vector 23: SSI 0 */
+ .word lm3s_i2c0 /* Vector 24: I2C 0 */
+ .word lm3s_pwmfault /* Vector 25: PWM Fault */
+ .word lm3s_pwm0 /* Vector 26: PWM Generator 0 */
+ .word lm3s_pwm1 /* Vector 27: PWM Generator 1 */
+ .word lm3s_pwm2 /* Vector 28: PWM Generator 2 */
+ .word lm3s_qei0 /* Vector 29: QEI0 */
+ .word lm3s_adc0 /* Vector 30: ADC Sequence 0 */
+ .word lm3s_adc1 /* Vector 31: ADC Sequence 1 */
+ .word lm3s_adc2 /* Vector 32: ADC Sequence 2 */
+ .word lm3s_adc3 /* Vector 33: ADC Sequence 3 */
+ .word lm3s_wdog /* Vector 34: Watchdog Timer */
+ .word lm3s_tmr0a /* Vector 35: Timer 0 A */
+ .word lm3s_tmr0b /* Vector 36: Timer 0 B */
+ .word lm3s_tmr1a /* Vector 37: Timer 1 A */
+ .word lm3s_tmr1b /* Vector 38: Timer 1 B */
+ .word lm3s_tmr2a /* Vector 39: Timer 2 A */
+ .word lm3s_tmr2b /* Vector 40: Timer 3 B */
+ .word lm3s_cmp0 /* Vector 41: Analog Comparator 0 */
+ .word lm3s_cmp1 /* Vector 42: Analog Comparator 1 */
+ .word lm3s_reserved /* Vector 43: Reserved */
+ .word lm3s_syscon /* Vector 44: System Control */
+ .word lm3s_flashcon /* Vector 45: FLASH Control */
+ .word lm3s_gpiof /* Vector 46: GPIO Port F */
+ .word lm3s_gpiog /* Vector 47: GPIO Port G */
+ .word lm3s_reserved /* Vector 48: Reserved */
+ .word lm3s_uart2 /* Vector 49: UART 2 */
+ .word lm3s_reserved /* Vector 50: Reserved */
+ .word lm3s_tmr3a /* Vector 51: Timer 3 A */
+ .word lm3s_tmr3b /* Vector 52: Timer 3 B */
+ .word lm3s_i2c1 /* Vector 53: I2C 1 */
+ .word lm3s_qei1 /* Vector 54: QEI1 */
+ .word lm3s_reserved /* Vector 55: Reserved */
+ .word lm3s_reserved /* Vector 56: Reserved */
+ .word lm3s_reserved /* Vector 57: Reserved */
+ .word lm3s_eth /* Vector 58: Ethernet Controller */
+ .word lm3s_hib /* Vector 59: Hibernation Module */
+ .word lm3s_reserved /* Vector 60: Reserved */
+ .word lm3s_reserved /* Vector 61: Reserved */
+ .word lm3s_reserved /* Vector 62: Reserved */
+ .word lm3s_reserved /* Vector 63: Reserved */
+ .word lm3s_reserved /* Vector 64: Reserved */
+ .word lm3s_reserved /* Vector 65: Reserved */
+ .word lm3s_reserved /* Vector 66: Reserved */
+ .word lm3s_reserved /* Vector 67: Reserved */
+ .word lm3s_reserved /* Vector 68: Reserved */
+ .word lm3s_reserved /* Vector 69: Reserved */
+ .word lm3s_reserved /* Vector 70: Reserved */
+#elif defined(CONFIG_ARCH_CHIP_LM3S9B96)
+ .word lm3s_gpioa /* Vector 16: GPIO Port A */
+ .word lm3s_gpiob /* Vector 17: GPIO Port B */
+ .word lm3s_gpioc /* Vector 18: GPIO Port C */
+ .word lm3s_gpiod /* Vector 19: GPIO Port D */
+ .word lm3s_gpioe /* Vector 20: GPIO Port E */
+ .word lm3s_uart0 /* Vector 21: UART 0 */
+ .word lm3s_uart1 /* Vector 22: UART 1 */
+ .word lm3s_ssi0 /* Vector 23: SSI 0 */
+ .word lm3s_i2c0 /* Vector 24: I2C 0 */
+ .word lm3s_pwmfault /* Vector 25: PWM Fault */
+ .word lm3s_pwm0 /* Vector 26: PWM Generator 0 */
+ .word lm3s_pwm1 /* Vector 27: PWM Generator 1 */
+ .word lm3s_pwm2 /* Vector 28: PWM Generator 2 */
+ .word lm3s_qei0 /* Vector 29: QEI0 */
+ .word lm3s_adc0 /* Vector 30: ADC Sequence 0 */
+ .word lm3s_adc1 /* Vector 31: ADC Sequence 1 */
+ .word lm3s_adc2 /* Vector 32: ADC Sequence 2 */
+ .word lm3s_adc3 /* Vector 33: ADC Sequence 3 */
+ .word lm3s_wdog /* Vector 34: Watchdog Timer */
+ .word lm3s_tmr0a /* Vector 35: Timer 0 A */
+ .word lm3s_tmr0b /* Vector 36: Timer 0 B */
+ .word lm3s_tmr1a /* Vector 37: Timer 1 A */
+ .word lm3s_tmr1b /* Vector 38: Timer 1 B */
+ .word lm3s_tmr2a /* Vector 39: Timer 2 A */
+ .word lm3s_tmr2b /* Vector 40: Timer 3 B */
+ .word lm3s_cmp0 /* Vector 41: Analog Comparator 0 */
+ .word lm3s_cmp1 /* Vector 42: Analog Comparator 1 */
+ .word lm3s_cmp2 /* Vector 43: Reserved */
+ .word lm3s_syscon /* Vector 44: System Control */
+ .word lm3s_flashcon /* Vector 45: FLASH Control */
+ .word lm3s_gpiof /* Vector 46: GPIO Port F */
+ .word lm3s_gpiog /* Vector 47: GPIO Port G */
+ .word lm3s_gpioh /* Vector 48: GPIO Port H */
+ .word lm3s_uart2 /* Vector 49: UART 2 */
+ .word lm3s_ssi1 /* Vector 50: SSI 1 */
+ .word lm3s_tmr3a /* Vector 51: Timer 3 A */
+ .word lm3s_tmr3b /* Vector 52: Timer 3 B */
+ .word lm3s_i2c1 /* Vector 53: I2C 1 */
+ .word lm3s_qei1 /* Vector 54: QEI1 */
+ .word lm3s_can0 /* Vector 55: CAN 0 */
+ .word lm3s_can1 /* Vector 56: CAN 1 */
+ .word lm3s_reserved /* Vector 57: Reserved */
+ .word lm3s_eth /* Vector 58: Ethernet Controller */
+ .word lm3s_reserved /* Vector 59: Reserved */
+ .word lm3s_usb /* Vector 60: USB */
+ .word lm3s_pwm3 /* Vector 61: PWM 3 */
+ .word lm3s_udmasoft /* Vector 62: uDMA Software */
+ .word lm3s_udmaerror /* Vector 63: uDMA Error */
+ .word lm3s_adc1_0 /* Vector 64: ADC1 Sequence 0 */
+ .word lm3s_adc1_1 /* Vector 65: ADC1 Sequence 1 */
+ .word lm3s_adc1_2 /* Vector 66: ADC1 Sequence 2 */
+ .word lm3s_adc1_3 /* Vector 67: ADC1 Sequence 3 */
+ .word lm3s_i2s0 /* Vector 68: I2S 0 */
+ .word lm3s_epi /* Vector 69: Reserved */
+ .word lm3s_gpioj /* Vector 70: GPIO J */
+ .word lm3s_reserved /* Vector 71: Reserved */
+ #elif defined(CONFIG_ARCH_CHIP_LM3S8962)
+ .word lm3s_gpioa /* Vector 16: GPIO Port A */
+ .word lm3s_gpiob /* Vector 17: GPIO Port B */
+ .word lm3s_gpioc /* Vector 18: GPIO Port C */
+ .word lm3s_gpiod /* Vector 19: GPIO Port D */
+ .word lm3s_gpioe /* Vector 20: GPIO Port E */
+ .word lm3s_uart0 /* Vector 21: UART 0 */
+ .word lm3s_uart1 /* Vector 22: UART 1 */
+ .word lm3s_ssi0 /* Vector 23: SSI 0 */
+ .word lm3s_i2c0 /* Vector 24: I2C 0 */
+ .word lm3s_pwmfault /* Vector 25: PWM Fault */
+ .word lm3s_pwm0 /* Vector 26: PWM Generator 0 */
+ .word lm3s_pwm1 /* Vector 27: PWM Generator 1 */
+ .word lm3s_pwm2 /* Vector 28: PWM Generator 2 */
+ .word lm3s_qei0 /* Vector 29: QEI0 */
+ .word lm3s_adc0 /* Vector 30: ADC Sequence 0 */
+ .word lm3s_adc1 /* Vector 31: ADC Sequence 1 */
+ .word lm3s_adc2 /* Vector 32: ADC Sequence 2 */
+ .word lm3s_adc3 /* Vector 33: ADC Sequence 3 */
+ .word lm3s_wdog /* Vector 34: Watchdog Timer */
+ .word lm3s_tmr0a /* Vector 35: Timer 0 A */
+ .word lm3s_tmr0b /* Vector 36: Timer 0 B */
+ .word lm3s_tmr1a /* Vector 37: Timer 1 A */
+ .word lm3s_tmr1b /* Vector 38: Timer 1 B */
+ .word lm3s_tmr2a /* Vector 39: Timer 2 A */
+ .word lm3s_tmr2b /* Vector 40: Timer 3 B */
+ .word lm3s_cmp0 /* Vector 41: Analog Comparator 0 */
+ .word lm3s_reserved /* Vector 42: Reserved */
+ .word lm3s_reserved /* Vector 43: Reserved */
+ .word lm3s_syscon /* Vector 44: System Control */
+ .word lm3s_flashcon /* Vector 45: FLASH Control */
+ .word lm3s_gpiof /* Vector 46: GPIO Port F */
+ .word lm3s_gpiog /* Vector 47: GPIO Port G */
+ .word lm3s_reserved /* Vector 48: Reserved */
+ .word lm3s_reserved /* Vector 49: Reserved */
+ .word lm3s_reserved /* Vector 50: Reserved */
+ .word lm3s_tmr3a /* Vector 51: Timer 3 A */
+ .word lm3s_tmr3b /* Vector 52: Timer 3 B */
+ .word lm3s_reserved /* Vector 53: Reserved*/
+ .word lm3s_qei1 /* Vector 54: QEI1 */
+ .word lm3s_can0 /* Vector 55: Can Controller */
+ .word lm3s_reserved /* Vector 56: Reserved */
+ .word lm3s_reserved /* Vector 57: Reserved */
+ .word lm3s_eth /* Vector 58: Ethernet Controller */
+ .word lm3s_hib /* Vector 59: Hibernation Module */
+ .word lm3s_reserved /* Vector 60: Reserved */
+ .word lm3s_reserved /* Vector 61: Reserved */
+ .word lm3s_reserved /* Vector 62: Reserved */
+ .word lm3s_reserved /* Vector 63: Reserved */
+ .word lm3s_reserved /* Vector 64: Reserved */
+ .word lm3s_reserved /* Vector 65: Reserved */
+ .word lm3s_reserved /* Vector 66: Reserved */
+ .word lm3s_reserved /* Vector 67: Reserved */
+ .word lm3s_reserved /* Vector 68: Reserved */
+ .word lm3s_reserved /* Vector 69: Reserved */
+ .word lm3s_reserved /* Vector 70: Reserved */
+#else
+# error "Vectors not specified for this LM3S chip"
+#endif
+ .size lm3s_vectors, .-lm3s_vectors
+
+/************************************************************************************
+ * .text
+ ************************************************************************************/
+
+ .text
+ .type handlers, function
+ .thumb_func
+handlers:
+ HANDLER lm3s_reserved, LM3S_IRQ_RESERVED /* Unexpected/reserved vector */
+ HANDLER lm3s_nmi, LM3S_IRQ_NMI /* Vector 2: Non-Maskable Interrupt (NMI) */
+ HANDLER lm3s_hardfault, LM3S_IRQ_HARDFAULT /* Vector 3: Hard fault */
+ HANDLER lm3s_mpu, LM3S_IRQ_MEMFAULT /* Vector 4: Memory management (MPU) */
+ HANDLER lm3s_busfault, LM3S_IRQ_BUSFAULT /* Vector 5: Bus fault */
+ HANDLER lm3s_usagefault, LM3S_IRQ_USAGEFAULT /* Vector 6: Usage fault */
+ HANDLER lm3s_svcall, LM3S_IRQ_SVCALL /* Vector 11: SVC call */
+ HANDLER lm3s_dbgmonitor, LM3S_IRQ_DBGMONITOR /* Vector 12: Debug Monitor */
+ HANDLER lm3s_pendsv, LM3S_IRQ_PENDSV /* Vector 14: Penable system service request */
+ HANDLER lm3s_systick, LM3S_IRQ_SYSTICK /* Vector 15: System tick */
+
+#if defined(CONFIG_ARCH_CHIP_LM3S6918)
+ HANDLER lm3s_gpioa, LM3S_IRQ_GPIOA /* Vector 16: GPIO Port A */
+ HANDLER lm3s_gpiob, LM3S_IRQ_GPIOB /* Vector 17: GPIO Port B */
+ HANDLER lm3s_gpioc, LM3S_IRQ_GPIOC /* Vector 18: GPIO Port C */
+ HANDLER lm3s_gpiod, LM3S_IRQ_GPIOD /* Vector 19: GPIO Port D */
+ HANDLER lm3s_gpioe, LM3S_IRQ_GPIOE /* Vector 20: GPIO Port E */
+ HANDLER lm3s_uart0, LM3S_IRQ_UART0 /* Vector 21: UART 0 */
+ HANDLER lm3s_uart1, LM3S_IRQ_UART1 /* Vector 22: UART 1 */
+ HANDLER lm3s_ssi0, LM3S_IRQ_SSI0 /* Vector 23: SSI 0 */
+ HANDLER lm3s_i2c0, LM3S_IRQ_I2C0 /* Vector 24: I2C 0 */
+ HANDLER lm3s_adc0, LM3S_IRQ_ADC0 /* Vector 30: ADC Sequence 0 */
+ HANDLER lm3s_adc1, LM3S_IRQ_ADC1 /* Vector 31: ADC Sequence 1 */
+ HANDLER lm3s_adc2, LM3S_IRQ_ADC2 /* Vector 32: ADC Sequence 2 */
+ HANDLER lm3s_adc3, LM3S_IRQ_ADC3 /* Vector 33: ADC Sequence 3 */
+ HANDLER lm3s_wdog, LM3S_IRQ_WDOG /* Vector 34: Watchdog Timer */
+ HANDLER lm3s_tmr0a, LM3S_IRQ_TIMER0A /* Vector 35: Timer 0 A */
+ HANDLER lm3s_tmr0b, LM3S_IRQ_TIMER0B /* Vector 36: Timer 0 B */
+ HANDLER lm3s_tmr1a, LM3S_IRQ_TIMER1A /* Vector 37: Timer 1 A */
+ HANDLER lm3s_tmr1b, LM3S_IRQ_TIMER1B /* Vector 38: Timer 1 B */
+ HANDLER lm3s_tmr2a, LM3S_IRQ_TIMER2A /* Vector 39: Timer 2 A */
+ HANDLER lm3s_tmr2b, LM3S_IRQ_TIMER2B /* Vector 40: Timer 3 B */
+ HANDLER lm3s_cmp0, LM3S_IRQ_COMPARE0 /* Vector 41: Analog Comparator 0 */
+ HANDLER lm3s_cmp1, LM3S_IRQ_COMPARE1 /* Vector 42: Analog Comparator 1 */
+ HANDLER lm3s_syscon, LM3S_IRQ_SYSCON /* Vector 44: System Control */
+ HANDLER lm3s_flashcon, LM3S_IRQ_FLASHCON /* Vector 45: FLASH Control */
+ HANDLER lm3s_gpiof, LM3S_IRQ_GPIOF /* Vector 46: GPIO Port F */
+ HANDLER lm3s_gpiog, LM3S_IRQ_GPIOG /* Vector 47: GPIO Port G */
+ HANDLER lm3s_gpioh, LM3S_IRQ_GPIOH /* Vector 48: GPIO Port H */
+ HANDLER lm3s_ssi1, LM3S_IRQ_SSI1 /* Vector 50: SSI 1 */
+ HANDLER lm3s_tmr3a, LM3S_IRQ_TIMER3A /* Vector 51: Timer 3 A */
+ HANDLER lm3s_tmr3b, LM3S_IRQ_TIMER3B /* Vector 52: Timer 3 B */
+ HANDLER lm3s_i2c1, LM3S_IRQ_I2C1 /* Vector 53: I2C 1 */
+ HANDLER lm3s_eth, LM3S_IRQ_ETHCON /* Vector 58: Ethernet Controller */
+ HANDLER lm3s_hib, LM3S_IRQ_HIBERNATE /* Vector 59: Hibernation Module */
+#elif defined(CONFIG_ARCH_CHIP_LM3S6432)
+ HANDLER lm3s_gpioa, LM3S_IRQ_GPIOA /* Vector 16: GPIO Port A */
+ HANDLER lm3s_gpiob, LM3S_IRQ_GPIOB /* Vector 17: GPIO Port B */
+ HANDLER lm3s_gpioc, LM3S_IRQ_GPIOC /* Vector 18: GPIO Port C */
+ HANDLER lm3s_gpiod, LM3S_IRQ_GPIOD /* Vector 19: GPIO Port D */
+ HANDLER lm3s_gpioe, LM3S_IRQ_GPIOE /* Vector 20: GPIO Port E */
+ HANDLER lm3s_uart0, LM3S_IRQ_UART0 /* Vector 21: UART 0 */
+ HANDLER lm3s_uart1, LM3S_IRQ_UART1 /* Vector 22: UART 1 */
+ HANDLER lm3s_ssi0, LM3S_IRQ_SSI0 /* Vector 23: SSI 0 */
+ HANDLER lm3s_i2c0, LM3S_IRQ_I2C0 /* Vector 24: I2C 0 */
+ HANDLER lm3s_pwm0, LM3S_IRQ_PWM0 /* Vector 26: PWM Generator 0 */
+ HANDLER lm3s_adc0, LM3S_IRQ_ADC0 /* Vector 30: ADC Sequence 0 */
+ HANDLER lm3s_adc1, LM3S_IRQ_ADC1 /* Vector 31: ADC Sequence 1 */
+ HANDLER lm3s_adc2, LM3S_IRQ_ADC2 /* Vector 32: ADC Sequence 2 */
+ HANDLER lm3s_adc3, LM3S_IRQ_ADC3 /* Vector 33: ADC Sequence 3 */
+ HANDLER lm3s_wdog, LM3S_IRQ_WDOG /* Vector 34: Watchdog Timer */
+ HANDLER lm3s_tmr0a, LM3S_IRQ_TIMER0A /* Vector 35: Timer 0 A */
+ HANDLER lm3s_tmr0b, LM3S_IRQ_TIMER0B /* Vector 36: Timer 0 B */
+ HANDLER lm3s_tmr1a, LM3S_IRQ_TIMER1A /* Vector 37: Timer 1 A */
+ HANDLER lm3s_tmr1b, LM3S_IRQ_TIMER1B /* Vector 38: Timer 1 B */
+ HANDLER lm3s_tmr2a, LM3S_IRQ_TIMER2A /* Vector 39: Timer 2 A */
+ HANDLER lm3s_tmr2b, LM3S_IRQ_TIMER2B /* Vector 40: Timer 3 B */
+ HANDLER lm3s_cmp0, LM3S_IRQ_COMPARE0 /* Vector 41: Analog Comparator 0 */
+ HANDLER lm3s_cmp1, LM3S_IRQ_COMPARE1 /* Vector 42: Analog Comparator 1 */
+ HANDLER lm3s_syscon, LM3S_IRQ_SYSCON /* Vector 44: System Control */
+ HANDLER lm3s_flashcon, LM3S_IRQ_FLASHCON /* Vector 45: FLASH Control */
+ HANDLER lm3s_gpiof, LM3S_IRQ_GPIOF /* Vector 46: GPIO Port F */
+ HANDLER lm3s_gpiog, LM3S_IRQ_GPIOG /* Vector 47: GPIO Port G */
+ HANDLER lm3s_eth, LM3S_IRQ_ETHCON /* Vector 58: Ethernet Controller */
+#elif defined(CONFIG_ARCH_CHIP_LM3S6965)
+ HANDLER lm3s_gpioa, LM3S_IRQ_GPIOA /* Vector 16: GPIO Port A */
+ HANDLER lm3s_gpiob, LM3S_IRQ_GPIOB /* Vector 17: GPIO Port B */
+ HANDLER lm3s_gpioc, LM3S_IRQ_GPIOC /* Vector 18: GPIO Port C */
+ HANDLER lm3s_gpiod, LM3S_IRQ_GPIOD /* Vector 19: GPIO Port D */
+ HANDLER lm3s_gpioe, LM3S_IRQ_GPIOE /* Vector 20: GPIO Port E */
+ HANDLER lm3s_uart0, LM3S_IRQ_UART0 /* Vector 21: UART 0 */
+ HANDLER lm3s_uart1, LM3S_IRQ_UART1 /* Vector 22: UART 1 */
+ HANDLER lm3s_ssi0, LM3S_IRQ_SSI0 /* Vector 23: SSI 0 */
+ HANDLER lm3s_i2c0, LM3S_IRQ_I2C0 /* Vector 24: I2C 0 */
+ HANDLER lm3s_pwmfault, LM3S_IRQ_PWMFAULT /* Vector 25: PWM Fault */
+ HANDLER lm3s_pwm0, LM3S_IRQ_PWM0 /* Vector 26: PWM Generator 0 */
+ HANDLER lm3s_pwm1, LM3S_IRQ_PWM1 /* Vector 27: PWM Generator 1 */
+ HANDLER lm3s_pwm2, LM3S_IRQ_PWM2 /* Vector 28: PWM Generator 2 */
+ HANDLER lm3s_qei0, LM3S_IRQ_QEI0 /* Vector 29: QEI 0 */
+ HANDLER lm3s_adc0, LM3S_IRQ_ADC0 /* Vector 30: ADC Sequence 0 */
+ HANDLER lm3s_adc1, LM3S_IRQ_ADC1 /* Vector 31: ADC Sequence 1 */
+ HANDLER lm3s_adc2, LM3S_IRQ_ADC2 /* Vector 32: ADC Sequence 2 */
+ HANDLER lm3s_adc3, LM3S_IRQ_ADC3 /* Vector 33: ADC Sequence 3 */
+ HANDLER lm3s_wdog, LM3S_IRQ_WDOG /* Vector 34: Watchdog Timer */
+ HANDLER lm3s_tmr0a, LM3S_IRQ_TIMER0A /* Vector 35: Timer 0 A */
+ HANDLER lm3s_tmr0b, LM3S_IRQ_TIMER0B /* Vector 36: Timer 0 B */
+ HANDLER lm3s_tmr1a, LM3S_IRQ_TIMER1A /* Vector 37: Timer 1 A */
+ HANDLER lm3s_tmr1b, LM3S_IRQ_TIMER1B /* Vector 38: Timer 1 B */
+ HANDLER lm3s_tmr2a, LM3S_IRQ_TIMER2A /* Vector 39: Timer 2 A */
+ HANDLER lm3s_tmr2b, LM3S_IRQ_TIMER2B /* Vector 40: Timer 3 B */
+ HANDLER lm3s_cmp0, LM3S_IRQ_COMPARE0 /* Vector 41: Analog Comparator 0 */
+ HANDLER lm3s_cmp1, LM3S_IRQ_COMPARE1 /* Vector 42: Analog Comparator 1 */
+ HANDLER lm3s_syscon, LM3S_IRQ_SYSCON /* Vector 44: System Control */
+ HANDLER lm3s_flashcon, LM3S_IRQ_FLASHCON /* Vector 45: FLASH Control */
+ HANDLER lm3s_gpiof, LM3S_IRQ_GPIOF /* Vector 46: GPIO Port F */
+ HANDLER lm3s_gpiog, LM3S_IRQ_GPIOG /* Vector 47: GPIO Port G */
+ HANDLER lm3s_uart2, LM3S_IRQ_UART1 /* Vector 49: UART 1 */
+ HANDLER lm3s_tmr3a, LM3S_IRQ_TIMER3A /* Vector 51: Timer 3 A */
+ HANDLER lm3s_tmr3b, LM3S_IRQ_TIMER3B /* Vector 52: Timer 3 B */
+ HANDLER lm3s_i2c1, LM3S_IRQ_I2C1 /* Vector 53: I2C 1 */
+ HANDLER lm3s_qei1, LM3S_IRQ_QEI1 /* Vector 54: QEI 1 */
+ HANDLER lm3s_eth, LM3S_IRQ_ETHCON /* Vector 58: Ethernet Controller */
+ HANDLER lm3s_hib, LM3S_IRQ_HIBERNATE /* Vector 59: Hibernation Module */
+#elif defined(CONFIG_ARCH_CHIP_LM3S8962)
+ HANDLER lm3s_gpioa, LM3S_IRQ_GPIOA /* Vector 16: GPIO Port A */
+ HANDLER lm3s_gpiob, LM3S_IRQ_GPIOB /* Vector 17: GPIO Port B */
+ HANDLER lm3s_gpioc, LM3S_IRQ_GPIOC /* Vector 18: GPIO Port C */
+ HANDLER lm3s_gpiod, LM3S_IRQ_GPIOD /* Vector 19: GPIO Port D */
+ HANDLER lm3s_gpioe, LM3S_IRQ_GPIOE /* Vector 20: GPIO Port E */
+ HANDLER lm3s_uart0, LM3S_IRQ_UART0 /* Vector 21: UART 0 */
+ HANDLER lm3s_uart1, LM3S_IRQ_UART1 /* Vector 22: UART 1 */
+ HANDLER lm3s_ssi0, LM3S_IRQ_SSI0 /* Vector 23: SSI 0 */
+ HANDLER lm3s_i2c0, LM3S_IRQ_I2C0 /* Vector 24: I2C 0 */
+ HANDLER lm3s_pwmfault, LM3S_IRQ_PWMFAULT /* Vector 25: PWM Fault */
+ HANDLER lm3s_pwm0, LM3S_IRQ_PWM0 /* Vector 26: PWM Generator 0 */
+ HANDLER lm3s_pwm1, LM3S_IRQ_PWM1 /* Vector 27: PWM Generator 1 */
+ HANDLER lm3s_pwm2, LM3S_IRQ_PWM2 /* Vector 28: PWM Generator 2 */
+ HANDLER lm3s_qei0, LM3S_IRQ_QEI0 /* Vector 29: QEI 0 */
+ HANDLER lm3s_adc0, LM3S_IRQ_ADC0 /* Vector 30: ADC Sequence 0 */
+ HANDLER lm3s_adc1, LM3S_IRQ_ADC1 /* Vector 31: ADC Sequence 1 */
+ HANDLER lm3s_adc2, LM3S_IRQ_ADC2 /* Vector 32: ADC Sequence 2 */
+ HANDLER lm3s_adc3, LM3S_IRQ_ADC3 /* Vector 33: ADC Sequence 3 */
+ HANDLER lm3s_wdog, LM3S_IRQ_WDOG /* Vector 34: Watchdog Timer */
+ HANDLER lm3s_tmr0a, LM3S_IRQ_TIMER0A /* Vector 35: Timer 0 A */
+ HANDLER lm3s_tmr0b, LM3S_IRQ_TIMER0B /* Vector 36: Timer 0 B */
+ HANDLER lm3s_tmr1a, LM3S_IRQ_TIMER1A /* Vector 37: Timer 1 A */
+ HANDLER lm3s_tmr1b, LM3S_IRQ_TIMER1B /* Vector 38: Timer 1 B */
+ HANDLER lm3s_tmr2a, LM3S_IRQ_TIMER2A /* Vector 39: Timer 2 A */
+ HANDLER lm3s_tmr2b, LM3S_IRQ_TIMER2B /* Vector 40: Timer 3 B */
+ HANDLER lm3s_cmp0, LM3S_IRQ_COMPARE0 /* Vector 41: Analog Comparator 0 */
+ HANDLER lm3s_syscon, LM3S_IRQ_SYSCON /* Vector 44: System Control */
+ HANDLER lm3s_flashcon, LM3S_IRQ_FLASHCON /* Vector 45: FLASH Control */
+ HANDLER lm3s_gpiof, LM3S_IRQ_GPIOF /* Vector 46: GPIO Port F */
+ HANDLER lm3s_gpiog, LM3S_IRQ_GPIOG /* Vector 47: GPIO Port G */
+ HANDLER lm3s_uart2, LM3S_IRQ_UART1 /* Vector 49: UART 1 */
+ HANDLER lm3s_tmr3a, LM3S_IRQ_TIMER3A /* Vector 51: Timer 3 A */
+ HANDLER lm3s_tmr3b, LM3S_IRQ_TIMER3B /* Vector 52: Timer 3 B */
+ HANDLER lm3s_i2c1, LM3S_IRQ_I2C1 /* Vector 53: I2C 1 */
+ HANDLER lm3s_qei1, LM3S_IRQ_QEI1 /* Vector 54: QEI 1 */
+ HANDLER lm3s_can0, LM3S_IRQ_CAN0 /* Vector 55: CAN 0 */
+ HANDLER lm3s_eth, LM3S_IRQ_ETHCON /* Vector 58: Ethernet Controller */
+ HANDLER lm3s_hib, LM3S_IRQ_HIBERNATE /* Vector 59: Hibernation Module */
+#elif defined(CONFIG_ARCH_CHIP_LM3S9B96)
+ HANDLER lm3s_gpioa, LM3S_IRQ_GPIOA /* Vector 16: GPIO Port A */
+ HANDLER lm3s_gpiob, LM3S_IRQ_GPIOB /* Vector 17: GPIO Port B */
+ HANDLER lm3s_gpioc, LM3S_IRQ_GPIOC /* Vector 18: GPIO Port C */
+ HANDLER lm3s_gpiod, LM3S_IRQ_GPIOD /* Vector 19: GPIO Port D */
+ HANDLER lm3s_gpioe, LM3S_IRQ_GPIOE /* Vector 20: GPIO Port E */
+ HANDLER lm3s_uart0, LM3S_IRQ_UART0 /* Vector 21: UART 0 */
+ HANDLER lm3s_uart1, LM3S_IRQ_UART1 /* Vector 22: UART 1 */
+ HANDLER lm3s_ssi0, LM3S_IRQ_SSI0 /* Vector 23: SSI 0 */
+ HANDLER lm3s_i2c0, LM3S_IRQ_I2C0 /* Vector 24: I2C 0 */
+ HANDLER lm3s_pwmfault, LM3S_IRQ_PWMFAULT /* Vector 25: PWM Fault */
+ HANDLER lm3s_pwm0, LM3S_IRQ_PWM0 /* Vector 26: PWM Generator 0 */
+ HANDLER lm3s_pwm1, LM3S_IRQ_PWM1 /* Vector 27: PWM Generator 1 */
+ HANDLER lm3s_pwm2, LM3S_IRQ_PWM2 /* Vector 28: PWM Generator 2 */
+ HANDLER lm3s_qei0, LM3S_IRQ_QEI0 /* Vector 29: QEI 0 */
+ HANDLER lm3s_adc0, LM3S_IRQ_ADC0 /* Vector 30: ADC Sequence 0 */
+ HANDLER lm3s_adc1, LM3S_IRQ_ADC1 /* Vector 31: ADC Sequence 1 */
+ HANDLER lm3s_adc2, LM3S_IRQ_ADC2 /* Vector 32: ADC Sequence 2 */
+ HANDLER lm3s_adc3, LM3S_IRQ_ADC3 /* Vector 33: ADC Sequence 3 */
+ HANDLER lm3s_wdog, LM3S_IRQ_WDOG /* Vector 34: Watchdog Timer */
+ HANDLER lm3s_tmr0a, LM3S_IRQ_TIMER0A /* Vector 35: Timer 0 A */
+ HANDLER lm3s_tmr0b, LM3S_IRQ_TIMER0B /* Vector 36: Timer 0 B */
+ HANDLER lm3s_tmr1a, LM3S_IRQ_TIMER1A /* Vector 37: Timer 1 A */
+ HANDLER lm3s_tmr1b, LM3S_IRQ_TIMER1B /* Vector 38: Timer 1 B */
+ HANDLER lm3s_tmr2a, LM3S_IRQ_TIMER2A /* Vector 39: Timer 2 A */
+ HANDLER lm3s_tmr2b, LM3S_IRQ_TIMER2B /* Vector 40: Timer 3 B */
+ HANDLER lm3s_cmp0, LM3S_IRQ_COMPARE0 /* Vector 41: Analog Comparator 0 */
+ HANDLER lm3s_cmp1, LM3S_IRQ_COMPARE1 /* Vector 42: Analog Comparator 1 */
+ HANDLER lm3s_cmp2, LM3S_IRQ_COMPARE2 /* Vector 43: Analog Comparator 2 */
+ HANDLER lm3s_syscon, LM3S_IRQ_SYSCON /* Vector 44: System Control */
+ HANDLER lm3s_flashcon, LM3S_IRQ_FLASHCON /* Vector 45: FLASH Control */
+ HANDLER lm3s_gpiof, LM3S_IRQ_GPIOF /* Vector 46: GPIO Port F */
+ HANDLER lm3s_gpiog, LM3S_IRQ_GPIOG /* Vector 47: GPIO Port G */
+ HANDLER lm3s_gpioh, LM3S_IRQ_GPIOH /* Vector 48: GPIO Port H */
+ HANDLER lm3s_uart2, LM3S_IRQ_UART2 /* Vector 49: UART 2 */
+ HANDLER lm3s_ssi1, LM3S_IRQ_SSI1 /* Vector 50: GPIO Port H */
+ HANDLER lm3s_tmr3a, LM3S_IRQ_TIMER3A /* Vector 51: Timer 3 A */
+ HANDLER lm3s_tmr3b, LM3S_IRQ_TIMER3B /* Vector 52: Timer 3 B */
+ HANDLER lm3s_i2c1, LM3S_IRQ_I2C1 /* Vector 53: I2C 1 */
+ HANDLER lm3s_qei1, LM3S_IRQ_QEI1 /* Vector 54: QEI 1 */
+ HANDLER lm3s_can0, LM3S_IRQ_CAN0 /* Vector 55: CAN 0 */
+ HANDLER lm3s_can1, LM3S_IRQ_CAN1 /* Vector 56: CAN 1 */
+ HANDLER lm3s_eth, LM3S_IRQ_ETHCON /* Vector 58: Ethernet Controller */
+ HANDLER lm3s_usb, LM3S_IRQ_USB /* Vector 60: USB */
+ HANDLER lm3s_pwm3, LM3S_IRQ_PWM3 /* Vector 61: PWM 3 */
+ HANDLER lm3s_udmasoft, LM3S_IRQ_UDMASOFT /* Vector 62: uDMA Software */
+ HANDLER lm3s_udmaerror, LM3S_IRQ_UDMAERROR /* Vector 63: uDMA Error */
+ HANDLER lm3s_adc1_0, LM3S_IRQ_ADC1_0 /* Vector 64: ADC1 Sequence 0 */
+ HANDLER lm3s_adc1_1, LM3S_IRQ_ADC1_1 /* Vector 65: ADC1 Sequence 1 */
+ HANDLER lm3s_adc1_2, LM3S_IRQ_ADC1_2 /* Vector 66: ADC1 Sequence 2 */
+ HANDLER lm3s_adc1_3, LM3S_IRQ_ADC1_3 /* Vector 67: ADC1 Sequence 3 */
+ HANDLER lm3s_i2s0, LM3S_IRQ_I2S0 /* Vector 68: I2S 0 */
+ HANDLER lm3s_epi, LM3S_IRQ_EPI /* Vector 69: EPI */
+ HANDLER lm3s_gpioj, LM3S_IRQ_GPIOJ /* Vector 70: GPIO Port J */
+#else
+# error "Vectors not specified for this LM3S chip"
+#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
+ */
+
+lm3s_irqcommon:
+
+ /* Complete the context save */
+
+#ifdef CONFIG_NUTTX_KERNEL
+ /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
+ * (handler mode) if the state is on the MSP. It can only be on the PSP if
+ * EXC_RETURN is 0xfffffffd (unprivileged thread)
+ */
+
+ adds r2, r14, #3 /* If R14=0xfffffffd, then r2 == 0 */
+ ite ne /* Next two instructions are condition */
+ mrsne r1, msp /* R1=The main stack pointer */
+ mrseq r1, psp /* R1=The process stack pointer */
+#else
+ mrs r1, msp /* R1=The main stack pointer */
+#endif
+
+ mov r2, r1 /* R2=Copy of the main/process stack pointer */
+ add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
+ mrs r3, primask /* R3=Current PRIMASK setting */
+#ifdef CONFIG_NUTTX_KERNEL
+ stmdb r1!, {r2-r11,r14} /* Save the remaining registers plus the SP value */
+#else
+ stmdb r1!, {r2-r11} /* Save the remaining registers plus the SP value */
+#endif
+
+ /* 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 re-use the main stack for interrupt level processing.
+ */
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ ldr sp, =g_intstackbase
+ str r1, [sp, #-4]! /* Save the MSP on the interrupt stack */
+ bl up_doirq /* R0=IRQ, R1=register save (msp) */
+ ldr r1, [sp, #+4]! /* Recover R1=main stack pointer */
+#else
+ mov sp, r1 /* We are using the main stack pointer */
+ bl up_doirq /* R0=IRQ, R1=register save (msp) */
+ mov r1, sp /* 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 1f /* 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, are 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_NUTTX_KERNEL
+ 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 2f /* Re-join common logic */
+
+ /* We are returning with no context switch. We simply need to "unwind"
+ * the same stack frame that we created
+ */
+1:
+#ifdef CONFIG_NUTTX_KERNEL
+ ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
+#else
+ ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */
+#endif
+2:
+#ifdef CONFIG_NUTTX_KERNEL
+ /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
+ * (handler mode) if the state is on the MSP. It can only be on the PSP if
+ * EXC_RETURN is 0xfffffffd (unprivileged thread)
+ */
+
+ adds r0, r14, #3 /* If R14=0xfffffffd, then r0 == 0 */
+ ite ne /* Next two instructions are condition */
+ msrne msp, r1 /* R1=The main stack pointer */
+ msreq psp, r1 /* R1=The process stack pointer */
+#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 /* Load the special value */
+#endif
+
+ /* Restore the interrupt state */
+
+ msr primask, r3 /* Restore interrupts */
+
+ /* 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: up_interruptstack/g_intstackbase
+ *
+ * Description:
+ * Shouldn't happen
+ *
+ ************************************************************************************/
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ .bss
+ .global g_intstackbase
+ .align 4
+up_interruptstack:
+ .skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
+g_intstackbase:
+ .size up_interruptstack, .-up_interruptstack
+#endif
+
+/************************************************************************************
+ * .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_heapbase below.
+ */
+
+ .globl g_heapbase
+ .type g_heapbase, object
+g_heapbase:
+ .long _ebss+CONFIG_IDLETHREAD_STACKSIZE
+ .size g_heapbase, .-g_heapbase
+
+ .end
diff --git a/nuttx/arch/arm/src/lpc17xx/Kconfig b/nuttx/arch/arm/src/lpc17xx/Kconfig
new file mode 100644
index 000000000..2769fc231
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/Kconfig
@@ -0,0 +1,622 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+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"
+
+config ARCH_CHIP_LPC1752
+ bool "LPC1752"
+
+config ARCH_CHIP_LPC1754
+ bool "LPC1754"
+
+config ARCH_CHIP_LPC1756
+ bool "LPC1756"
+
+config ARCH_CHIP_LPC1758
+ bool "LPC1758"
+
+config ARCH_CHIP_LPC1759
+ bool "LPC1759"
+
+config ARCH_CHIP_LPC1764
+ bool "LPC1764"
+
+config ARCH_CHIP_LPC1765
+ bool "LPC1765"
+
+config ARCH_CHIP_LPC1766
+ bool "LPC1766"
+
+config ARCH_CHIP_LPC1767
+ bool "LPC1767"
+
+config ARCH_CHIP_LPC1768
+ bool "LPC1768"
+
+config ARCH_CHIP_LPC1769
+ bool "LPC1769"
+
+endchoice
+
+config ARCH_FAMILY_LPC175X
+ bool
+ default y if ARCH_CHIP_LPC1751 || ARCH_CHIP_LPC1752 || ARCH_CHIP_LPC1754 || ARCH_CHIP_LPC1756 || ARCH_CHIP_LPC1758 || ARCH_CHIP_LPC1759
+
+config ARCH_FAMILY_LPC176X
+ bool
+ default y if ARCH_CHIP_LPC1764 || ARCH_CHIP_LPC1765 || ARCH_CHIP_LPC1766 || ARCH_CHIP_LPC1767 || ARCH_CHIP_LPC1768 || ARCH_CHIP_LPC1769
+
+choice
+ prompt "Toolchain Selection"
+ default LPC17_CODESOURCERYW
+ depends on ARCH_CHIP_LPC17XX
+
+config LPC17_CODESOURCERYW
+ bool "CodeSourcery for Windows"
+
+config LPC17_CODESOURCERYL
+ bool "CodeSourcery for Linux"
+
+config LPC17_DEVKITARM
+ bool "DevkitARM (Windows)"
+
+config LPC17_BUILDROOT
+ bool "NuttX buildroot (Cygwin or Linux)"
+
+config LPC17_CODEREDW
+ bool "CodeRed for Windows"
+
+config LPC17_CODEREDL
+ bool "CodeRed for Windows"
+
+endchoice
+
+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_ETHERNET
+ bool "Ethernet"
+ select NET
+ select ARCH_HAVE_PHY
+ default n
+
+config LPC17_USBHOST
+ bool "USB host"
+ select USBHOST
+ 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_UART0
+ bool "UART0"
+ select ARCH_HAVE_UART0
+ default n
+
+config LPC17_UART1
+ bool "UART1"
+ select ARCH_HAVE_UART1
+ default n
+
+config LPC17_UART2
+ bool "UART2"
+ select ARCH_HAVE_UART2
+ default n
+
+config LPC17_UART3
+ bool "UART3"
+ select ARCH_HAVE_UART3
+ default n
+
+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
+
+config LPC17_SSP0
+ bool "SSP0"
+ default n
+
+config LPC17_SSP1
+ bool "SSP1"
+ 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_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_PWM
+ bool "PWM"
+ default n
+
+config LPC17_MCPWM
+ bool "MCPWM"
+ default n
+
+config LPC17_QEI
+ bool "QEI"
+ default n
+
+config LPC17_RTC
+ bool "RTC"
+ default n
+
+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
+
+config LPC17_FLASH
+ bool "FLASH"
+ default n
+
+endmenu
+
+menu "Serial driver options"
+
+config SERIAL_TERMIOS
+ bool "Serial driver TERMIOS supported"
+ depends on LPC17_UART0 || LPC17_UART1 || LPC17_UART2 || LPC17_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..
+
+config UART0_FLOWCONTROL
+ bool "UART0 flow control"
+ depends on LPC17_UART0
+ default n
+ ---help---
+ Enable UART0 flow control
+
+config UART1_FLOWCONTROL
+ bool "UART1 flow control"
+ depends on LPC17_UART1
+ default n
+ ---help---
+ Enable UART1 flow control
+
+config UART1_RINGINDICATOR
+ bool "UART1 ring indicator"
+ depends on LPC17_UART1
+ default n
+ ---help---
+ Enable UART1 ring indicator
+
+config UART2_FLOWCONTROL
+ bool "UART0 flow control"
+ depends on LPC17_UART2
+ default n
+ ---help---
+ Enable UART2 flow control
+
+config UART3_FLOWCONTROL
+ bool "UART3 flow control"
+ depends on LPC17_UART3
+ default n
+ ---help---
+ Enable UART3 flow control
+
+endmenu
+
+menu "ADC driver options"
+
+config ADC0_AVERAGE
+ int "ADC0 average"
+ depends on LPC17_ADC
+ default 200
+
+config ADC0_MASK
+ int "ADC0 mask"
+ depends on LPC17_ADC
+ default 1
+
+config ADC0_SPS
+ int "ADC0 SPS"
+ depends on LPC17_ADC
+ default 1000
+
+endmenu
+
+menu "CAN driver options"
+
+config CAN_EXTID
+ bool "CAN extended IDs"
+ depends on LPC17_CAN1 || LPC17_CAN2
+ 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"
+ depends on LPC17_CAN1 || LPC17_CAN2
+ default 6
+ ---help---
+ The number of CAN time quanta in segment 1. Default: 6
+
+config CAN_TSEG2
+ int "TSEG2 quanta"
+ depends on LPC17_CAN1 || LPC17_CAN2
+ default 4
+ ---help---
+ The number of CAN time quanta in segment 2. Default: 7
+
+config CAN_SAM
+ bool "CAN sampling"
+ depends on LPC17_CAN1 || LPC17_CAN2
+ 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"
+ depends on LPC17_CAN1 || LPC17_CAN2
+ default n
+ ---help---
+ Enable CAN loopback mode
+
+config CAN_REGDEBUG
+ bool "Register level debug"
+ depends on LPC17_CAN1 || LPC17_CAN2
+ 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"
+
+config I2C0_FREQ
+ int "I2C0 frequency"
+ depends on LPC17_I2C0
+ default 100000
+
+config I2C1_FREQ
+ int "I2C1 frequency"
+ depends on LPC17_I2C1
+ default 100000
+
+config I2C2_FREQ
+ int "I2C2 frequency"
+ depends on LPC17_I2C2
+ default 100000
+
+endmenu
+
+menu "Ethernet driver options"
+
+config PHY_AUTONEG
+ bool "Autonegiation"
+ depends on LPC17_ETHERNET
+ ---help---
+ Enable auto-negotion
+
+config PHY_SPEED100
+ bool "100Mbit/Sec"
+ depends on LPC17_ETHERNET && !PHY_AUTONEG
+ ---help---
+ Select 100Mbit vs. 10Mbit speed.
+
+config PHY_FDUPLEX
+ bool "Full duplex"
+ depends on LPC17_ETHERNET && !PHY_AUTONEG
+ ---help---
+ Select full (vs. half) duplex
+
+config NET_EMACRAM_SIZE
+ int "EMAC RAM Size"
+ depends on LPC17_ETHERNET
+ default 16384
+ ---help---
+ Size of EMAC RAM. Default: 16384 bytes
+
+config NET_NTXDESC
+ int "Number of Tx descriptors"
+ depends on LPC17_ETHERNET
+ default 18
+ ---help---
+ Configured number of Tx descriptors. Default: 18
+
+config NET_NRXDESC
+ int "Number of Rx descriptors"
+ depends on LPC17_ETHERNET
+ default 18
+ ---help---
+ Configured number of Rx descriptors. Default: 18
+
+config NET_PRIORITY
+ int "Ethernet interrupt priority"
+ depends on LPC17_ETHERNET
+ default 0
+ ---help---
+ Ethernet interrupt priority. The is default is the higest priority (0).
+
+config NET_WOL
+ bool "Wake-up on LAN"
+ depends on LPC17_ETHERNET
+ default n
+ ---help---
+ Enable Wake-up on Lan (not fully implemented).
+
+config NET_REGDEBUG
+ bool "Ethernet register-level debug"
+ depends on LPC17_ETHERNET && DEBUG
+ default n
+ ---help---
+ Enable low level register debug. Also needs DEBUG.
+
+config NET_DUMPPACKET
+ bool "Enable packet dumping"
+ depends on LPC17_ETHERNET && DEBUG
+ default n
+ ---help---
+ Dump all received and transmitted packets. Also needs DEBUG.
+
+config NET_HASH
+ bool "Hashing"
+ depends on LPC17_ETHERNET
+ default n
+ ---help---
+ Enable receipt of near-perfect match frames.
+
+config NET_MULTICAST
+ bool "Multicast"
+ depends on LPC17_ETHERNET
+ 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 "USB device driver options"
+
+config LPC17_USBDEV_EP0_MAXSIZE
+ int "EP0 Max packet size"
+ depends on LPC17_USBDEV
+ default 64
+ ---help---
+ Endpoint 0 maximum packet size. Default: 64
+
+config LPC17_USBDEV_FRAME_INTERRUPT
+ bool "USB frame interrupt"
+ depends on LPC17_USBDEV
+ 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"
+ depends on LPC17_USBDEV
+ 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"
+ depends on LPC17_USBDEV
+ default 8
+ ---help---
+ Number of DMA descriptors to allocate in SRAM. Default: 8
+
+config LPC17_USBDEV_DMA
+ bool "Enable USB device DMA"
+ depends on LPC17_USBDEV
+ default n
+ ---help---
+ Enable lpc17xx-specific DMA support
+
+config LPC17_USBDEV_NOVBUS
+ bool "Disable VBUS support"
+ depends on LPC17_USBDEV
+ default n
+ ---help---
+ Define if the hardware implementation does not support the VBUS signal
+
+config LPC17_USBDEV_NOLED
+ bool "Disable USB device LCD support"
+ depends on LPC17_USBDEV
+ default n
+ ---help---
+ Define if the hardware implementation does not support the LED output
+
+config LPC17_USBDEV_REGDEBUG
+ bool "Register level debug"
+ depends on LPC17_USBDEV && DEBUG
+ default n
+ ---help---
+ Output detailed register-level USB device debug information. Requires also DEBUG.
+
+endmenu
+
+menu "USB host driver options"
+
+config USBHOST_OHCIRAM_SIZE
+ int "OHCI RAM Size"
+ depends on LPC17_USBHOST
+ default 16384
+ ---help---
+ Total size of OHCI RAM (in AHB SRAM Bank 1). Default: 16384
+
+config USBHOST_NEDS
+ int "Number of Endpoint Descriptors"
+ depends on LPC17_USBHOST
+ default 2
+ ---help---
+ Number of endpoint descriptors. Default: 2
+
+config USBHOST_NTDS
+ int "Number of transfer descriptors"
+ depends on LPC17_USBHOST
+ default 3
+ ---help---
+ Number of transfer descriptors. Default: 3
+
+config USBHOST_TDBUFFERS
+ int "Number of descriptor buffers"
+ depends on LPC17_USBHOST
+ default 2
+ ---help---
+ Number of transfer descriptor buffers. Default: 2
+
+config USBHOST_TDBUFSIZE
+ int "Descriptor buffer size"
+ depends on LPC17_USBHOST
+ default 128
+ ---help---
+ Size of one transfer descriptor buffer. Default 128
+
+config USBHOST_IOBUFSIZE
+ int "I/O buffer size"
+ depends on LPC17_USBHOST
+ 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 USBHOST_BULK_DISABLE
+ bool "Disable bulk EPs"
+ depends on LPC17_USBHOST
+ default n
+ ---help---
+ Disable support for bulk endpoints.
+
+config USBHOST_INT_DISABLE
+ bool "Disable interupt EPs"
+ depends on LPC17_USBHOST
+ default n
+ ---help---
+ Disable support for interrupt endpoints.
+
+config USBHOST_ISOC_DISABLE
+ bool "Disable isochronous EPs"
+ depends on LPC17_USBHOST
+ default n
+ ---help---
+ Disable support for isochronous endpoints.
+
+config LPC17_USBHOST_REGDEBUG
+ bool "Register level debug"
+ depends on LPC17_USBHOST && DEBUG
+ default n
+ ---help---
+ Output detailed register-level USB host debug information. Requires also DEBUG.
+
+endmenu
diff --git a/nuttx/arch/arm/src/lpc17xx/Make.defs b/nuttx/arch/arm/src/lpc17xx/Make.defs
new file mode 100644
index 000000000..56aef87fd
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/Make.defs
@@ -0,0 +1,102 @@
+############################################################################
+# arch/arm/src/lpc17xx/Make.defs
+#
+# Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (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 = lpc17_vectors.S
+
+# Common ARM and Cortex-M3 files
+
+CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
+CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.c up_createstack.c \
+ up_mdelay.c up_udelay.c up_exit.c up_initialize.c up_memfault.c \
+ up_initialstate.c up_interruptcontext.c up_modifyreg8.c \
+ up_modifyreg16.c up_modifyreg32.c up_releasepending.c \
+ up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c \
+ up_sigdeliver.c up_unblocktask.c up_usestack.c up_doirq.c \
+ up_hardfault.c up_svcall.c up_checkstack.c
+
+ifeq ($(CONFIG_NET),y)
+ifneq ($(CONFIG_LPC17_ETHERNET),y)
+CMN_CSRCS += up_etherstub.c
+endif
+endif
+
+# Required LPC17xx files
+
+CHIP_ASRCS =
+CHIP_CSRCS = lpc17_allocateheap.c lpc17_clockconfig.c lpc17_clrpend.c \
+ lpc17_gpio.c lpc17_i2c.c lpc17_idle.c lpc17_irq.c lpc17_lowputc.c \
+ lpc17_serial.c lpc17_spi.c lpc17_ssp.c lpc17_start.c lpc17_timerisr.c
+
+# Configuration-dependent LPC17xx files
+
+ifeq ($(CONFIG_GPIO_IRQ),y)
+CHIP_CSRCS += lpc17_gpioint.c
+endif
+
+ifeq ($(CONFIG_DEBUG_GPIO),y)
+CHIP_CSRCS += lpc17_gpiodbg.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_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
diff --git a/nuttx/arch/arm/src/lpc17xx/chip.h b/nuttx/arch/arm/src/lpc17xx/chip.h
new file mode 100644
index 000000000..982482017
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/chip.h
@@ -0,0 +1,226 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/chip.h
+ *
+ * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Get customizations for each supported chip */
+
+#if defined(CONFIG_ARCH_CHIP_LPC1769) || defined(CONFIG_ARCH_CHIP_LPC1768)
+# 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_LPC1767)
+# 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_LPC1766)
+# 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_LPC1765)
+# 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_LPC1764)
+# 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_LPC1759)
+# 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_LPC1758)
+# 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_LPC1756)
+# 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_LPC1754)
+# 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_LPC1752)
+# 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_LPC1751)
+# 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 */
+#else
+# error "Unsupported LPC17xx chip"
+#endif
+
+/* Include only the memory map. Other chip hardware files should then include this
+ * file for the proper setup
+ */
+
+#include "lpc17_memorymap.h"
+
+/* 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 */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_adc.c b/nuttx/arch/arm/src/lpc17xx/lpc17_adc.c
new file mode 100644
index 000000000..ebc05d13e
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_adc.c
@@ -0,0 +1,279 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_adc.c
+ *
+ * Copyright (C) 2011 Li Zhuoyi. All rights reserved.
+ * Author: Li Zhuoyi <lzyy.cn@gmail.com>
+ * History: 0.1 2011-08-05 initial version
+ *
+ * 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.
+ *
+ ************************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+#include <nuttx/arch.h>
+#include <nuttx/analog/adc.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lpc17_internal.h"
+#include "lpc17_syscon.h"
+#include "lpc17_pinconn.h"
+#include "lpc17_adc.h"
+
+#if defined(CONFIG_LPC17_ADC)
+
+#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
+ ****************************************************************************/
+
+/* Reset the ADC device. Called early to initialize the hardware. This
+ * is called, before ao_setup() and on error conditions.
+ */
+
+static void adc_reset(FAR struct adc_dev_s *dev)
+{
+ irqstate_t flags;
+ uint32_t regval;
+ FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
+
+ flags = irqsave();
+
+ regval = getreg32(LPC17_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCADC;
+ putreg32(regval, LPC17_SYSCON_PCONP);
+
+ 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);
+
+ uint32_t clkdiv=LPC17_CCLK/8/65/priv->sps;
+ clkdiv<<=8;
+ clkdiv&=0xff00;
+ putreg32(ADC_CR_PDN|ADC_CR_BURST|clkdiv|priv->mask,LPC17_ADC_CR);
+
+ if(priv->mask&0x01)
+ lpc17_configgpio(GPIO_AD0p0);
+ else if(priv->mask&0x02)
+ lpc17_configgpio(GPIO_AD0p1);
+ else if(priv->mask&0x04)
+ lpc17_configgpio(GPIO_AD0p2);
+ else if(priv->mask&0x08)
+ lpc17_configgpio(GPIO_AD0p3);
+ else if(priv->mask&0x10)
+ lpc17_configgpio(GPIO_AD0p4);
+ else if(priv->mask&0x20)
+ lpc17_configgpio(GPIO_AD0p5);
+ else if(priv->mask&0x40)
+ lpc17_configgpio(GPIO_AD0p6);
+ else if(priv->mask&0x80)
+ lpc17_configgpio(GPIO_AD0p7);
+
+ irqrestore(flags);
+}
+
+/* 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)
+{
+ int i;
+ 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)
+ {
+ for (i = 0; i < 8; i++)
+ {
+ priv->buf[i]=0;
+ priv->count[i]=0;
+ }
+ up_enable_irq(priv->irq);
+ }
+ return ret;
+}
+
+/* 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;
+ up_disable_irq(priv->irq);
+ irq_detach(priv->irq);
+}
+
+/* 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(ADC_INTEN_GLOBAL, LPC17_ADC_INTEN);
+ else
+ putreg32(0x00, LPC17_ADC_INTEN);
+}
+
+/* All ioctl calls will be routed through this method */
+
+static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg)
+{
+ dbg("Fix me:Not Implemented\n");
+ return 0;
+}
+
+static int adc_interrupt(int irq, void *context)
+{
+ uint32_t regval;
+ FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv;
+ 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;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lpc17_adcinitialize
+ *
+ * Description:
+ * Initialize the adc
+ *
+ * Returned Value:
+ * Valid can device structure reference on succcess; a NULL on failure
+ *
+ ****************************************************************************/
+
+FAR struct adc_dev_s *lpc17_adcinitialize(void)
+{
+ return &g_adcdev;
+}
+#endif
+
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_adc.h b/nuttx/arch/arm/src/lpc17xx/lpc17_adc.h
new file mode 100644
index 000000000..6b9a58345
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_adc.h
@@ -0,0 +1,180 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_adc.h
+ *
+ * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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_ADC_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_allocateheap.c b/nuttx/arch/arm/src/lpc17xx/lpc17_allocateheap.c
new file mode 100644
index 000000000..501358716
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_allocateheap.c
@@ -0,0 +1,230 @@
+/****************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_allocateheap.c
+ *
+ * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/mm.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "lpc17_memorymap.h"
+#include "lpc17_emacram.h"
+#include "lpc17_ohciram.h"
+
+/****************************************************************************
+ * Private Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+/* The configured RAM start address must be the beginning of CPU SRAM */
+
+#if CONFIG_DRAM_START != LPC17_SRAM_BASE
+# warning "CONFIG_DRAM_START is not at LPC17_SRAM_BASE"
+# undef CONFIG_DRAM_START
+# undef CONFIG_DRAM_END
+# define CONFIG_DRAM_START LPC17_SRAM_BASE
+# define CONFIG_DRAM_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_DRAM_SIZE > LPC17_CPUSRAM_SIZE
+# warning "CONFIG_DRAM_SIZE is larger than the size of CPU SRAM"
+# undef CONFIG_DRAM_SIZE
+# undef CONFIG_DRAM_END
+# define CONFIG_DRAM_SIZE LPC17_CPUSRAM_SIZE
+# define CONFIG_DRAM_END (LPC17_SRAM_BASE+LPC17_CPUSRAM_SIZE)
+#elif CONFIG_DRAM_SIZE < LPC17_CPUSRAM_SIZE
+# warning "CONFIG_DRAM_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 */
+
+#ifdef LPC17_AHB_HEAPBASE
+# if CONFIG_MM_REGIONS < 2
+# warning "CONFIG_MM_REGIONS < 2: Available AHB SRAM Bank(s) not included in HEAP"
+# endif
+# if CONFIG_MM_REGIONS > 2
+# warning "CONFIG_MM_REGIONS > 2: Are additional regions handled by application?"
+# endif
+#else
+# if CONFIG_MM_REGIONS > 1
+# 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:
+ * The heap may be statically allocated by
+ * defining CONFIG_HEAP_BASE and CONFIG_HEAP_SIZE. If these
+ * are not defined, then this function will be called to
+ * dynamically set aside the heap region.
+ *
+ ****************************************************************************/
+
+void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
+{
+ up_ledon(LED_HEAPALLOCATE);
+ *heap_start = (FAR void*)g_heapbase;
+ *heap_size = CONFIG_DRAM_END - g_heapbase;
+}
+
+/************************************************************************
+ * 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
+
+ /* Yes... Add the AHB SRAM heap region. */
+
+ mm_addregion((FAR void*)LPC17_AHB_HEAPBASE, LPC17_AHB_HEAPSIZE);
+#endif
+}
+#endif
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_can.c b/nuttx/arch/arm/src/lpc17xx/lpc17_can.c
new file mode 100644
index 000000000..409785d29
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_can.c
@@ -0,0 +1,1306 @@
+/************************************************************************************
+ * 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 <lzyy.cn@gmail.com>
+ * Gregory Nutt <gnutt@nuttx.org>
+ * 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 <nuttx/config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+#include <nuttx/arch.h>
+#include <nuttx/can.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lpc17_internal.h"
+#include "lpc17_syscon.h"
+#include "lpc17_pinconn.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 = irqsave();
+
+ /* 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 */
+ irqrestore(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 = irqsave();
+ 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);
+ irqrestore(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 = irqsave();
+
+ /* 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);
+ irqrestore(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 = irqsave();
+
+ /* 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;
+ }
+
+ irqrestore(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_EXTID
+ hdr.ch_extid = ((rfs & CAN_RFS_FF) != 0);
+#else
+ 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 = irqsave();
+
+#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);
+ irqrestore(flags);
+ return NULL;
+ }
+
+ /* Then just perform a CAN reset operation */
+
+ can_reset(candev);
+ irqrestore(flags);
+ return candev;
+}
+#endif
+
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_can.h b/nuttx/arch/arm/src/lpc17xx/lpc17_can.h
new file mode 100644
index 000000000..e990958fd
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_can.h
@@ -0,0 +1,510 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_can.h
+ *
+ * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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_CAN_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_clockconfig.c b/nuttx/arch/arm/src/lpc17xx/lpc17_clockconfig.c
new file mode 100644
index 000000000..635090e9f
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_clockconfig.c
@@ -0,0 +1,208 @@
+/****************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_clockconfig.c
+ * arch/arm/src/chip/lpc17_clockconfig.c
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "lpc17_internal.h"
+#include "lpc17_syscon.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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.
+ *
+ ************************************************************************************/
+
+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
+
+ /* 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
+ /* Otherwise, setup up the USB clock divider to generate the USB clock from PLL0 */
+
+ putreg32(BOARD_USBCLKCFG_VALUE, LPC17_SYSCON_USBCLKCFG);
+#endif
+
+ /* 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_LP17_FLASH
+ putreg32(BOARD_FLASHCFG_VALUE, LPC17_SYSCON_FLASHCFG);
+#endif
+}
+
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_clrpend.c b/nuttx/arch/arm/src/lpc17xx/lpc17_clrpend.c
new file mode 100644
index 000000000..242f7ac4f
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <arch/irq.h>
+
+#include "nvic.h"
+#include "up_arch.h"
+#include "lpc17_internal.h"
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/lpc17xx/lpc17_dac.c b/nuttx/arch/arm/src/lpc17xx/lpc17_dac.c
new file mode 100644
index 000000000..13ac212f6
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_dac.c
@@ -0,0 +1,199 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_dac.c
+ *
+ * Copyright (C) 2011 Li Zhuoyi. All rights reserved.
+ * Author: Li Zhuoyi <lzyy.cn@gmail.com>
+ * History: 0.1 2011-08-05 initial version
+ *
+ * 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.
+ *
+ ************************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+#include <nuttx/arch.h>
+#include <nuttx/analog/dac.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lpc17_internal.h"
+#include "lpc17_syscon.h"
+#include "lpc17_pinconn.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);
+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 = irqsave();
+
+ 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);
+
+ irqrestore(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,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;
+}
+
+static int dac_interrupt(int irq, void *context)
+{
+}
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/lpc17xx/lpc17_dac.h b/nuttx/arch/arm/src/lpc17xx/lpc17_dac.h
new file mode 100644
index 000000000..a35e16eae
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_dac.h
@@ -0,0 +1,97 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_dac.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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_DAC_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_emacram.h b/nuttx/arch/arm/src/lpc17xx/lpc17_emacram.h
new file mode 100644
index 000000000..700ad7ec3
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_emacram.h
@@ -0,0 +1,242 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_emacram.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include "chip.h"
+#include "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 controlloer? 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 18
+#endif
+
+/* Number of Rx descriptors */
+
+#ifndef CONFIG_NET_NRXDESC
+# define CONFIG_NET_NRXDESC 18
+#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_BUFSIZE)
+ * and the number of Rx and Tx descriptors that can be suppored (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 == 424, then you could have
+ * ntx = nrx = 18.
+ *
+ * An example with all of the details:
+ *
+ * NTXDESC=18 NRXDESC=18 CONFIG_NET_EMACRAM_SIZE=16Kb CONFIG_NET_BUFSIZE=420:
+ * LPC17_TXDESCTAB_SIZE = 18*8 = 144
+ * LPC17_TXSTATTAB_SIZE = 18*4 = 72
+ * LPC17_TXTAB_SIZE = 216
+ *
+ * LPC17_RXDESCTAB_SIZE = 16*8 = 144
+ * LPC17_RXSTATTAB_SIZE = 16*8 = 144
+ * LPC17_TXTAB_SIZE = 288
+ *
+ * LPC17_DESCTAB_SIZE = 504
+ * LPC17_DESC_BASE = LPC17_SRAM_BANK0 + 0x00004000 - 504
+ * = LPC17_SRAM_BANK0 + 0x00003e08
+ * LPC17_TXDESC_BASE = LPC17_SRAM_BANK0 + 0x00003e08
+ * LPC17_TXSTAT_BASE = LPC17_SRAM_BANK0 + 0x00003e98
+ * LPC17_RXDESC_BASE = LPC17_SRAM_BANK0 + 0x00003ee0
+ * LPC17_RXSTAT_BASE = LPC17_SRAM_BANK0 + 0x00003f70
+ *
+ * LPC17_PKTMEM_BASE = LPC17_SRAM_BANK0
+ * LPC17_PKTMEM_SIZE = 0x00004000-504 = 0x00003e40
+ * LPC17_PKTMEM_END = LPC17_SRAM_BANK0 + 0x00003e08
+
+ * LPC17_MAXPACKET_SIZE = ((420 + 3 + 2) & ~3) = 424
+ * LPC17_NTXPKTS = 18
+ * LPC17_NRXPKTS = 18
+
+ * LPC17_TXBUFFER_SIZE = 18 * 424 = 0x00001dd0
+ * LPC17_RXBUFFER_SIZE = 18 * 424 = 0x00001dd0
+ * LPC17_BUFFER_SIZE = 0x00003ba0
+
+ * LPC17_BUFFER_BASE = LPC17_SRAM_BANK0
+ * LPC17_TXBUFFER_BASE = LPC17_SRAM_BANK0
+ * LPC17_RXBUFFER_BASE = LPC17_SRAM_BANK0 + 0x00001dd0
+ * LPC17_BUFFER_END = LPC17_SRAM_BANK0 + 0x00003ba0
+ *
+ * Then the check LPC17_BUFFER_END < LPC17_PKTMEM_END passes. The amount of
+ * unused memory is small: 0x00003e08-0x00003ba0 or about 616 bytes -- not
+ * enough for two more packets.
+ *
+ * [It is also possible, with some effort, to reclaim any unused
+ * SRAM for the use in the heap. But that has not yet been pursued.]
+ */
+
+#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_BUFSIZE + 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/nuttx/arch/arm/src/lpc17xx/lpc17_ethernet.c b/nuttx/arch/arm/src/lpc17xx/lpc17_ethernet.c
new file mode 100644
index 000000000..47a22ec2e
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_ethernet.c
@@ -0,0 +1,2509 @@
+/****************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_ethernet.c
+ *
+ * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_LPC17_ETHERNET)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <time.h>
+#include <string.h>
+#include <debug.h>
+#include <wdog.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/net/mii.h>
+
+#include <nuttx/net/uip/uip.h>
+#include <nuttx/net/uip/uipopt.h>
+#include <nuttx/net/uip/uip-arp.h>
+#include <nuttx/net/uip/uip-arch.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "lpc17_syscon.h"
+#include "lpc17_ethernet.h"
+#include "lpc17_emacram.h"
+#include "lpc17_internal.h"
+
+#include <arch/board/board.h>
+
+/* Does this chip have and ethernet controller? */
+
+#if LPC17_NETHCONTROLLERS > 0
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+/* 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_NET_MULTICAST)
+# define CONFIG_NET_MULTICAST 1
+#endif
+
+/* If the user did not specify a priority for Ethernet interrupts, set the
+ * interrupt priority to the maximum.
+ */
+
+#ifndef CONFIG_NET_PRIORITY
+# define CONFIG_NET_PRIORITY NVIC_SYSH_PRIORITY_MAX
+#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)
+#define LPC17_POLLHSEC (1*2)
+
+/* 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 uip_eth_hdr *)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_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_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_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
+ ****************************************************************************/
+
+/* EMAC statistics (debug only) */
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
+struct lpc17_statistics_s
+{
+#ifdef ENABLE_WOL
+ uint32_t wol; /* Wake-up interrupts */
+#endif
+ uint32_t rx_finished; /* Rx finished interrupts */
+ uint32_t rx_done; /* Rx done interrupts */
+ uint32_t rx_ovrerrors; /* Number of Rx overrun error interrupts */
+ uint32_t rx_errors; /* Number of Rx error interrupts (OR of other errors) */
+ uint32_t rx_packets; /* Number of packets received (sum of the following): */
+ uint32_t rx_ip; /* Number of Rx IP packets received */
+ uint32_t rx_arp; /* Number of Rx ARP packets received */
+ uint32_t rx_dropped; /* Number of dropped, unsupported Rx packets */
+ uint32_t rx_pkterr; /* Number of dropped, error in Rx descriptor */
+ uint32_t rx_pktsize; /* Number of dropped, too small or too big */
+ uint32_t rx_fragment; /* Number of dropped, packet fragments */
+
+ uint32_t tx_packets; /* Number of Tx packets queued */
+ uint32_t tx_pending; /* Number of Tx packets that had to wait for a TxDesc */
+ uint32_t tx_unpend; /* Number of pending Tx packets that were sent */
+ uint32_t tx_finished; /* Tx finished interrupts */
+ uint32_t tx_done; /* Tx done interrupts */
+ uint32_t tx_underrun; /* Number of Tx underrun error interrupts */
+ uint32_t tx_errors; /* Number of Tx error inerrupts (OR of other errors) */
+ uint32_t tx_timeouts; /* Number of Tx timeout errors */
+};
+# define EMAC_STAT(priv,name) priv->lp_stat.name++
+#else
+# define EMAC_STAT(priv,name)
+#endif
+
+/* 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 */
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
+ struct lpc17_statistics_s lp_stat;
+#endif
+
+ /* This holds the information visible to uIP/NuttX */
+
+ struct uip_driver_s lp_dev; /* Interface understood by uIP */
+};
+
+/****************************************************************************
+ * 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_uiptxpoll(struct uip_driver_s *dev);
+
+/* Interrupt handling */
+
+static void lpc17_response(struct lpc17_driver_s *priv);
+static void lpc17_rxdone(struct lpc17_driver_s *priv);
+static void lpc17_txdone(struct lpc17_driver_s *priv);
+static int lpc17_interrupt(int irq, void *context);
+
+/* Watchdog timer expirations */
+
+static void lpc17_polltimer(int argc, uint32_t arg, ...);
+static void lpc17_txtimeout(int argc, uint32_t arg, ...);
+
+/* NuttX callback functions */
+
+static int lpc17_ifup(struct uip_driver_s *dev);
+static int lpc17_ifdown(struct uip_driver_s *dev);
+static int lpc17_txavail(struct uip_driver_s *dev);
+#ifdef CONFIG_NET_IGMP
+static int lpc17_addmac(struct uip_driver_s *dev, const uint8_t *mac);
+static int lpc17_rmmac(struct uip_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) */
+
+ EMAC_STAT(priv, tx_packets);
+ 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,
+ 1, (uint32_t)priv);
+ return OK;
+}
+
+/****************************************************************************
+ * Function: lpc17_uiptxpoll
+ *
+ * Description:
+ * The transmitter is available, check if uIP has any outgoing packets ready
+ * to send. This is a callback from uip_poll(). uip_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_uiptxpoll(struct uip_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)
+ {
+ /* Send this packet. In this context, we know that there is space for
+ * at least one more packet in the descriptor list.
+ */
+
+ uip_arp_out(&priv->lp_dev);
+ 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 Tx interrupts */
+
+ 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);
+ EMAC_STAT(priv, tx_pending);
+ }
+}
+
+/****************************************************************************
+ * Function: lpc17_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 lpc17_rxdone(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 */
+
+ EMAC_STAT(priv, rx_packets);
+
+ /* 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);
+ EMAC_STAT(priv, rx_pkterr);
+ }
+
+ /* 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_BUFSIZE + CONFIG_NET_GUARDSIZE)
+ {
+ nlldbg("Too big. considx: %08x prodidx: %08x pktlen: %d rxstat: %08x\n",
+ considx, prodidx, pktlen, *rxstat);
+ EMAC_STAT(priv, rx_pktsize);
+ }
+ else if ((*rxstat & RXSTAT_INFO_LASTFLAG) == 0)
+ {
+ nlldbg("Fragment. considx: %08x prodidx: %08x pktlen: %d rxstat: %08x\n",
+ considx, prodidx, pktlen, *rxstat);
+ EMAC_STAT(priv, rx_fragment);
+ fragment = true;
+ }
+ else if (fragment)
+ {
+ nlldbg("Last fragment. considx: %08x prodidx: %08x pktlen: %d rxstat: %08x\n",
+ considx, prodidx, pktlen, *rxstat);
+ EMAC_STAT(priv, rx_fragment);
+ 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);
+
+ /* We only accept IP packets of the configured type and ARP packets */
+
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(UIP_ETHTYPE_IP6))
+#else
+ if (BUF->type == HTONS(UIP_ETHTYPE_IP))
+#endif
+ {
+ /* Handle the incoming Rx packet */
+
+ EMAC_STAT(priv, rx_ip);
+ uip_arp_ipin(&priv->lp_dev);
+ uip_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)
+ {
+ uip_arp_out(&priv->lp_dev);
+ lpc17_response(priv);
+ }
+ }
+ else if (BUF->type == htons(UIP_ETHTYPE_ARP))
+ {
+ EMAC_STAT(priv, rx_arp);
+ uip_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
+ {
+ /* Unrecognized... drop it. */
+
+ EMAC_STAT(priv, rx_dropped);
+ }
+ }
+
+ /* 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
+ *
+ * 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(struct lpc17_driver_s *priv)
+{
+ /* Cancel the pending Tx timeout */
+
+ wd_cancel(priv->lp_txtimeout);
+
+ /* Disable further Tx interrupts. Tx interrupts may be re-enabled again
+ * depending upon the result of the poll.
+ */
+
+ priv->lp_inten &= ~ETH_TXINTS;
+ lpc17_putreg(priv->lp_inten, LPC17_ETH_INTEN);
+
+ /* 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;
+ EMAC_STAT(priv, tx_unpend);
+
+ lpc17_transmit(priv);
+
+ priv->lp_inten |= ETH_RXINTS;
+ lpc17_putreg(priv->lp_inten, LPC17_ETH_INTEN);
+ }
+
+ /* Otherwise poll uIP for new XMIT data */
+
+ else
+ {
+ (void)uip_poll(&priv->lp_dev, lpc17_uiptxpoll);
+ }
+}
+
+/****************************************************************************
+ * 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)
+ {
+ EMAC_STAT(priv, wol);
+# 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);
+ EMAC_STAT(priv, rx_ovrerrors);
+ }
+
+ if ((status & ETH_INT_TXUNR) != 0)
+ {
+ nlldbg("TX Underrun. status: %08x\n", status);
+ EMAC_STAT(priv, tx_underrun);
+ }
+
+ /* 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
+ * 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);
+ EMAC_STAT(priv, rx_errors);
+ }
+
+ /* RX FINISHED -- Triggered when all receive descriptors have
+ * been processed i.e. on the transition to the situation
+ * where ProduceIndex == ConsumeIndex.
+ */
+
+ if ((status & ETH_INT_RXFIN) != 0)
+ {
+ EMAC_STAT(priv, rx_finished);
+ DEBUGASSERT(lpc17_getreg(LPC17_ETH_RXPRODIDX) == lpc17_getreg(LPC17_ETH_RXCONSIDX));
+ }
+
+ /* 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_RXDONE) != 0)
+ {
+ EMAC_STAT(priv, rx_done);
+
+ /* We have received at least one new incoming packet. */
+
+ lpc17_rxdone(priv);
+ }
+
+ /* 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() in order to
+ * clean up after the failed transmit.
+ */
+
+ if ((status & ETH_INT_TXERR) != 0)
+ {
+ nlldbg("TX Error. status: %08x\n", status);
+ EMAC_STAT(priv, tx_errors);
+ }
+
+ /* 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)
+ {
+ EMAC_STAT(priv, tx_finished);
+ }
+
+ /* 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)
+ {
+ EMAC_STAT(priv, tx_done);
+
+ /* A packet transmission just completed */
+
+ lpc17_txdone(priv);
+ }
+ }
+ }
+
+ /* 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
+ *
+ * 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(int argc, uint32_t arg, ...)
+{
+ struct lpc17_driver_s *priv = (struct lpc17_driver_s *)arg;
+
+ /* Increment statistics and dump debug info */
+
+ EMAC_STAT(priv, tx_timeouts);
+ 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 uIP for new XMIT data */
+
+ (void)uip_poll(&priv->lp_dev, lpc17_uiptxpoll);
+ }
+}
+
+/****************************************************************************
+ * Function: lpc17_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 lpc17_polltimer(int argc, uint32_t arg, ...)
+{
+ struct lpc17_driver_s *priv = (struct lpc17_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 (lpc17_txdesc(priv) == OK)
+ {
+ /* 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)uip_timer(&priv->lp_dev, lpc17_uiptxpoll, LPC17_POLLHSEC);
+ }
+
+ /* Setup the watchdog poll timer again */
+
+ (void)wd_start(priv->lp_txpoll, LPC17_WDDELAY, lpc17_polltimer, 1, arg);
+}
+
+/****************************************************************************
+ * 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 uip_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);
+
+ /* 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_NET_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_polltimer, 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 uip_driver_s *dev)
+{
+ struct lpc17_driver_s *priv = (struct lpc17_driver_s *)dev->d_private;
+ irqstate_t flags;
+
+ /* Disable the Ethernet interrupt */
+
+ flags = irqsave();
+ 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;
+ irqrestore(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * 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 uip_driver_s *dev)
+{
+ struct lpc17_driver_s *priv = (struct lpc17_driver_s *)dev->d_private;
+ irqstate_t flags;
+
+ /* Disable interrupts because this function may be called from interrupt
+ * level processing.
+ */
+
+ flags = irqsave();
+
+ /* Ignore the notification if the interface is not yet up */
+
+ 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 uIP for new XMIT data */
+
+ (void)uip_poll(&priv->lp_dev, lpc17_uiptxpoll);
+ }
+ }
+
+ irqrestore(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * 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:
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IGMP
+static int lpc17_addmac(struct uip_driver_s *dev, const uint8_t *mac)
+{
+ struct lpc17_driver_s *priv = (struct lpc17_driver_s *)dev->d_private;
+
+ /* Add the MAC address to the hardware multicast routing table */
+
+#warning "Not implemented"
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * 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 uip_driver_s *dev, const uint8_t *mac)
+{
+ struct lpc17_driver_s *priv = (struct lpc17_driver_s *)dev->d_private;
+
+ /* Add the MAC address to the hardware multicast routing table */
+
+#warning "Not implemented"
+ 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_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--)
+ {
+#ifdef CONFIG_PHY_DP83848C
+ 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);
+
+ if (phyreg == LPC17_PHYID1)
+ {
+ phyreg = lpc17_phyread(phyaddr, MII_PHYID2);
+ nvdbg("Addr: %d PHY ID2: %04x\n", phyaddr, phyreg);
+
+ if (phyreg == 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_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_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_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 = irqsave();
+
+ /* 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);
+ irqrestore(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 the interrupt */
+
+ return -EAGAIN;
+ }
+
+ /* Register the device with the OS so that socket IOCTLs can be performed */
+
+ (void)netdev_register(&priv->lp_dev);
+ 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/nuttx/arch/arm/src/lpc17xx/lpc17_ethernet.h b/nuttx/arch/arm/src/lpc17xx/lpc17_ethernet.h
new file mode 100644
index 000000000..f48c6d953
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_ethernet.h
@@ -0,0 +1,597 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_ethernet.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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_LPC17_ETHERNET_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_gpdma.c b/nuttx/arch/arm/src/lpc17xx/lpc17_gpdma.c
new file mode 100644
index 000000000..f567d52c0
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_gpdma.c
@@ -0,0 +1,226 @@
+/****************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_gpdma.c
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lpc17_internal.h"
+#include "lpc17_syscon.h"
+#include "lpc17_gpdma.h"
+
+#ifdef CONFIG_LPC17_GPDMA
+
+/****************************************************************************
+ * 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: lpc17_dmainitialize
+ *
+ * Description:
+ * Initialize the GPDMA subsystem.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void lpc17_dmainitilaize(void)
+{
+}
+
+/****************************************************************************
+ * 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)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * 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_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
+ uint32_t srcaddr, uint32_t destaddr, size_t nbytes)
+{
+ return -ENOSYS;
+}
+
+/****************************************************************************
+ * Name: lpc17_dmastart
+ *
+ * Description:
+ * Start the DMA transfer
+ *
+ ****************************************************************************/
+
+int lpc17_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
+{
+ return -ENOSYS;
+}
+
+/****************************************************************************
+ * 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)
+{
+}
+#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)
+{
+}
+#endif /* CONFIG_DEBUG_DMA */
+
+#endif /* CONFIG_LPC17_GPDMA */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_gpdma.h b/nuttx/arch/arm/src/lpc17xx/lpc17_gpdma.h
new file mode 100644
index 000000000..c0e70efa5
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_gpdma.h
@@ -0,0 +1,417 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_gpdma.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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_DMA_CHAN_OFFSET(n) (0x0100 + ((n) << 5)) /* n=0,1,...7 */
+
+#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 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)
+#define DMA_REQ_UART0RX (9)
+#define DMA_REQ_UART1TX (10)
+#define DMA_REQ_UART1RX (11)
+#define DMA_REQ_UART2TX (12)
+#define DMA_REQ_UART2RX (13)
+#define DMA_REQ_UART3TX (14)
+#define DMA_REQ_UART3RX (15)
+
+#define DMA_REQ_MAT0p0 (8)
+#define DMA_REQ_MAT0p1 (9)
+#define DMA_REQ_MAT1p0 (10)
+#define DMA_REQ_MAT1p1 (11)
+#define DMA_REQ_MAT2p0 (12)
+#define DMA_REQ_MAT2p1 (13)
+#define DMA_REQ_MAT3p0 (14)
+#define DMA_REQ_MAT3p1 (15)
+
+/* 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 */
+
+/* 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
+ */
+
+#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)
+
+/* 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_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_DWIDTH_SHIFT (21) /* Bits 21-23: Destination transfer width */
+#define DMACH_CONTROL_DWIDTH_MASK (7 << DMACH_CONTROL_DWIDTH_SHIFT)
+#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_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_SSP0RX << DMACH_CONFIG_SRCPER_SHIFT)
+# define DMACH_CONFIG_SRCPER_ADC (DMA_REQ_ADC << 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_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_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: Source peripheral */
+#define DMACH_CONFIG_DSTPER_MASK (31 << 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_SSP0RX << DMACH_CONFIG_DSTPER_SHIFT)
+# define DMACH_CONFIG_DSTPER_ADC (DMA_REQ_ADC << 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_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_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)
+# define DMACH_CONFIG_XFRTYPE_M2M (0 << DMACH_CONFIG_XFRTYPE_SHIFT) /* Memory to memory DMA */
+# define DMACH_CONFIG_XFRTYPE_M2P (1 << DMACH_CONFIG_XFRTYPE_SHIFT) /* Memory to peripheral DMA */
+# define DMACH_CONFIG_XFRTYPE_P2M (2 << DMACH_CONFIG_XFRTYPE_SHIFT) /* Peripheral to memory DMA */
+# define DMACH_CONFIG_XFRTYPE_P2P (3 << DMACH_CONFIG_XFRTYPE_SHIFT) /* Peripheral to peripheral DMA */
+#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_LPC17_GPDMA_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c b/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c
new file mode 100644
index 000000000..4cc73a3fc
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c
@@ -0,0 +1,655 @@
+/****************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_gpio.c
+ *
+ * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#include "up_arch.h"
+#include "chip.h"
+#include "lpc17_gpio.h"
+#include "lpc17_pinconn.h"
+#include "lpc17_internal.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
+};
+
+/* 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
+};
+
+const uint32_t g_lopinsel[GPIO_NPORTS] =
+{
+ LPC17_PINCONN_PINSEL0,
+ LPC17_PINCONN_PINSEL2,
+ LPC17_PINCONN_PINSEL4,
+ 0,
+ 0
+};
+
+const uint32_t g_hipinsel[GPIO_NPORTS] =
+{
+ LPC17_PINCONN_PINSEL1,
+ LPC17_PINCONN_PINSEL3,
+ 0,
+ LPC17_PINCONN_PINSEL7,
+ LPC17_PINCONN_PINSEL9
+};
+
+const uint32_t g_lopinmode[GPIO_NPORTS] =
+{
+ LPC17_PINCONN_PINMODE0,
+ LPC17_PINCONN_PINMODE2,
+ LPC17_PINCONN_PINMODE4,
+ 0,
+ 0
+};
+
+const uint32_t g_hipinmode[GPIO_NPORTS] =
+{
+ LPC17_PINCONN_PINMODE1,
+ LPC17_PINCONN_PINMODE3,
+ 0,
+ LPC17_PINCONN_PINMODE7,
+ LPC17_PINCONN_PINMODE9
+};
+
+const uint32_t g_odmode[GPIO_NPORTS] =
+{
+ LPC17_PINCONN_ODMODE0,
+ LPC17_PINCONN_ODMODE1,
+ LPC17_PINCONN_ODMODE2,
+ LPC17_PINCONN_ODMODE3,
+ LPC17_PINCONN_ODMODE4
+};
+
+/****************************************************************************
+ * 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(uint16_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
+
+/****************************************************************************
+ * 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(uint16_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(uint16_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(uint16_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_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));
+ return OK;
+}
+
+/****************************************************************************
+ * Name: lpc17_configalternate
+ *
+ * Description:
+ * Configure a GPIO alternate function pin based on bit-encoded description
+ * of the pin.
+ *
+ ****************************************************************************/
+
+static int lpc17_configalternate(uint16_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;
+}
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lpc17_configgpio
+ *
+ * Description:
+ * Configure a GPIO pin based on bit-encoded description of the pin.
+ *
+ ****************************************************************************/
+
+int lpc17_configgpio(uint16_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(uint16_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(uint16_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 0;
+}
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.h b/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.h
new file mode 100644
index 000000000..002ef3faf
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.h
@@ -0,0 +1,196 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_gpio.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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
+
+#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)
+
+#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)
+
+/* 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 (P0.12-14 nad P0.31 are reserved) */
+
+#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-13 (P0.14-31 are reserved) */
+
+#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_GPIO_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_gpiodbg.c b/nuttx/arch/arm/src/lpc17xx/lpc17_gpiodbg.c
new file mode 100644
index 000000000..dc4dac33a
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_gpiodbg.c
@@ -0,0 +1,173 @@
+/****************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_gpiodbg.c
+ *
+ * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <debug.h>
+#include <arch/irq.h>
+
+#include "up_arch.h"
+#include "chip.h"
+#include "lpc17_gpio.h"
+#include "lpc17_internal.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.
+ *
+ ****************************************************************************/
+
+static uint32_t lpc17_pinsel(unsigned int port, unsigned int pin)
+{
+ if (pin < 16)
+ {
+ return g_lopinsel[port];
+ }
+ else
+ {
+ return g_hipinsel[port];
+ }
+}
+
+/****************************************************************************
+ * Name: lpc17_pinmode
+ *
+ * Description:
+ * Get the address of the PINMODE register corresponding to this port and
+ * pin number.
+ *
+ ****************************************************************************/
+
+static uint32_t lpc17_pinmode(unsigned int port, unsigned int pin)
+{
+ if (pin < 16)
+ {
+ return g_lopinmode[port];
+ }
+ else
+ {
+ return g_hipinmode[port];
+ }
+}
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: lpc17_dumpgpio
+ *
+ * Description:
+ * Dump all GPIO registers associated with the provided base address
+ *
+ ****************************************************************************/
+
+int lpc17_dumpgpio(uint16_t pinset, const char *msg)
+{
+ irqstate_t flags;
+ uint32_t base;
+ uint32_t pinsel;
+ uint32_t pinmode;
+ 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;
+ pinsel = lpc17_pinsel(port, pin);
+ pinmode = lpc17_pinmode(port, pin);
+
+ /* The following requires exclusive access to the GPIO registers */
+
+ flags = irqsave();
+ lldbg("GPIO%c pinset: %08x -- %s\n",
+ port + '0', pinset, msg);
+
+ 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]));
+
+ 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));
+ irqrestore(flags);
+ return OK;
+}
+#endif /* CONFIG_DEBUG_GPIO */
+
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_gpioint.c b/nuttx/arch/arm/src/lpc17xx/lpc17_gpioint.c
new file mode 100644
index 000000000..66988b0b9
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_gpioint.c
@@ -0,0 +1,431 @@
+/****************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_gpioint.c
+ *
+ * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+#include <nuttx/arch.h>
+
+#include "up_arch.h"
+#include "chip.h"
+#include "lpc17_gpio.h"
+#include "lpc17_pinconn.h"
+#include "lpc17_internal.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)
+{
+ int regval;
+
+ /* 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 rising 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);
+}
+
+/****************************************************************************
+ * 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: 12 interrupts p0.0-p0.11 */
+
+ if (irq >= LPC17_VALID_FIRST0L && irq < (LPC17_VALID_FIRST0L+LPC17_VALID_NIRQS0L))
+ {
+ return 0;
+ }
+
+ /* Set 2: 16 interrupts p0.15-p0.30 */
+
+ else if (irq >= LPC17_VALID_FIRST0H && irq < (LPC17_VALID_FIRST0H+LPC17_VALID_NIRQS0H))
+ {
+ return 0;
+ }
+
+ /* Set 3: 14 interrupts p2.0-p2.13 */
+
+ else if (irq >= LPC17_VALID_FIRST2 && irq < (LPC17_VALID_FIRST2+LPC17_VALID_NIRQS2))
+ {
+ return 2;
+ }
+ 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: 12 interrupts p0.0-p0.11
+ *
+ * See arch/arm/include/lpc17xx/irq.h:
+ * LPC17_VALID_SHIFT0L 0 - Bit 0 is thre first bit in the group of 12 interrupts
+ * LPC17_VALID_FIRST0L irq - IRQ number associated with p0.0
+ * LPC17_VALID_NIRQS0L 12 - 12 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: 16 interrupts p0.15-p0.30
+ *
+ * LPC17_VALID_SHIFT0H 15 - Bit 15 is the first bit in a group of 16 interrupts
+ * LPC17_VALID_FIRST0L irq - IRQ number associated with p0.15
+ * 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;
+ }
+
+ /* Set 3: 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;
+ }
+ 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 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 EINT3 interrupt that also indicates that a GPIO interrupt has
+ * occurred. NOTE: This logic will have to be extended if EINT3 is
+ * actually used for External Interrupt 3.
+ *
+ ****************************************************************************/
+
+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);
+ }
+
+ /* Check for an interrupt on GPIO2 */
+
+ if ((intstatus & GPIOINT_IOINTSTATUS_P2INT) != 0)
+ {
+ lpc17_gpiodemux(LPC17_GPIOINT2_BASE, LPC17_VALID_GPIOINT2,
+ LPC17_VALID_FIRST2, context);
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Global 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. Note: 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);
+}
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/lpc17xx/lpc17_i2c.c b/nuttx/arch/arm/src/lpc17xx/lpc17_i2c.c
new file mode 100644
index 000000000..48d6fefce
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_i2c.c
@@ -0,0 +1,545 @@
+/*******************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_i2c.c
+ *
+ * Copyright (C) 2011 Li Zhuoyi. All rights reserved.
+ * Author: Li Zhuoyi <lzyy.cn@gmail.com>
+ * 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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/i2c.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "wdog.h"
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+#include "os_internal.h"
+
+
+#include "lpc17_internal.h"
+#include "lpc17_syscon.h"
+#include "lpc17_pinconn.h"
+#include "lpc17_i2c.h"
+
+#if defined(CONFIG_LPC17_I2C0) || defined(CONFIG_LPC17_I2C1) || defined(CONFIG_LPC17_I2C2)
+
+#ifndef GPIO_I2C1_SCL
+ #define GPIO_I2C1_SCL GPIO_I2C1_SCL_1
+ #define GPIO_I2C1_SDA GPIO_I2C1_SDA_1
+#endif
+#ifndef CONFIG_I2C0_FREQ
+ #define CONFIG_I2C0_FREQ 100000
+#endif
+#ifndef CONFIG_I2C1_FREQ
+ #define CONFIG_I2C1_FREQ 100000
+#endif
+#ifndef CONFIG_I2C2_FREQ
+ #define CONFIG_I2C2_FREQ 100000
+#endif
+
+/*******************************************************************************
+ * Definitions
+ *******************************************************************************/
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define I2C_TIMEOUT ((20 * CLK_TCK) / 1000) /* 20 mS */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+struct lpc17_i2cdev_s
+{
+ struct i2c_dev_s dev; /* Generic I2C device */
+ struct i2c_msg_s msg; /* a single message for legacy read/write */
+ 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 */
+
+ uint16_t wrcnt; /* number of bytes sent to tx fifo */
+ uint16_t rdcnt; /* number of bytes read from rx fifo */
+};
+
+static struct lpc17_i2cdev_s i2cdevices[3];
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+static int i2c_start (struct lpc17_i2cdev_s *priv);
+static void i2c_stop (struct lpc17_i2cdev_s *priv);
+static int i2c_interrupt (int irq, FAR void *context);
+static void i2c_timeout (int argc, uint32_t arg, ...);
+
+/****************************************************************************
+ * I2C device operations
+ ****************************************************************************/
+
+static uint32_t i2c_setfrequency(FAR struct i2c_dev_s *dev, uint32_t frequency);
+static int i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits);
+static int i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer, int buflen);
+static int i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen);
+static int i2c_transfer(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, int count);
+
+struct i2c_ops_s lpc17_i2c_ops =
+{
+ .setfrequency = i2c_setfrequency,
+ .setaddress = i2c_setaddress,
+ .write = i2c_write,
+ .read = i2c_read,
+#ifdef CONFIG_I2C_TRANSFER
+ .transfer = i2c_transfer
+#endif
+};
+
+/*******************************************************************************
+ * Name: lpc17_i2c_setfrequency
+ *
+ * Description:
+ * Set the frequence for the next transfer
+ *
+ *******************************************************************************/
+
+static uint32_t i2c_setfrequency(FAR struct i2c_dev_s *dev, uint32_t frequency)
+{
+ struct lpc17_i2cdev_s *priv = (struct lpc17_i2cdev_s *) dev;
+
+ 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);
+ }
+
+ /* FIXME: This function should return the actual selected frequency */
+ return frequency;
+}
+
+/*******************************************************************************
+ * Name: lpc17_i2c_setaddress
+ *
+ * Description:
+ * Set the I2C slave address for a subsequent read/write
+ *
+ *******************************************************************************/
+static int i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits)
+{
+ struct lpc17_i2cdev_s *priv = (struct lpc17_i2cdev_s *) dev;
+
+ DEBUGASSERT(dev != NULL);
+ DEBUGASSERT(nbits == 7 );
+
+ priv->msg.addr = addr<<1;
+ priv->msg.flags = 0 ;
+
+ return OK;
+}
+
+/*******************************************************************************
+ * Name: lpc17_i2c_write
+ *
+ * Description:
+ * Send a block of data on I2C using the previously selected I2C
+ * frequency and slave address.
+ *
+ *******************************************************************************/
+static int i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer, int buflen)
+{
+ struct lpc17_i2cdev_s *priv = (struct lpc17_i2cdev_s *) dev;
+ int ret;
+
+ DEBUGASSERT (dev != NULL);
+
+ priv->wrcnt=0;
+ priv->rdcnt=0;
+ priv->msg.addr &= ~0x01;
+ priv->msg.buffer = (uint8_t*)buffer;
+ priv->msg.length = buflen;
+
+ ret = i2c_start (priv);
+
+ return ret >0 ? OK : -ETIMEDOUT;
+}
+
+/*******************************************************************************
+ * Name: lpc17_i2c_read
+ *
+ * Description:
+ * Receive a block of data on I2C using the previously selected I2C
+ * frequency and slave address.
+ *
+ *******************************************************************************/
+static int i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
+{
+ struct lpc17_i2cdev_s *priv = (struct lpc17_i2cdev_s *) dev;
+ int ret;
+
+ DEBUGASSERT (dev != NULL);
+
+ priv->wrcnt=0;
+ priv->rdcnt=0;
+ priv->msg.addr |= 0x01;
+ priv->msg.buffer = buffer;
+ priv->msg.length = buflen;
+
+ ret = i2c_start (priv);
+
+ return ret >0 ? OK : -ETIMEDOUT;
+}
+
+/*******************************************************************************
+ * Name: i2c_start
+ *
+ * Description:
+ * Perform a I2C transfer start
+ *
+ *******************************************************************************/
+static int i2c_start (struct lpc17_i2cdev_s *priv)
+{
+ int ret=-1;
+ sem_wait (&priv->mutex);
+
+ 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, i2c_timeout, 1, (uint32_t)priv);
+ sem_wait(&priv->wait);
+ wd_cancel (priv->timeout);
+ sem_post (&priv->mutex);
+
+ if( priv-> state == 0x18 || priv->state == 0x28)
+ ret=priv->wrcnt;
+ else if( priv-> state == 0x50 || priv->state == 0x58)
+ ret=priv->rdcnt;
+ return ret;
+}
+
+/*******************************************************************************
+ * Name: i2c_stop
+ *
+ * Description:
+ * Perform a I2C transfer stop
+ *
+ *******************************************************************************/
+static void 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: i2c_timeout
+ *
+ * Description:
+ * Watchdog timer for timeout of I2C operation
+ *
+ *******************************************************************************/
+
+static void i2c_timeout (int argc, uint32_t arg, ...)
+{
+ struct lpc17_i2cdev_s *priv = (struct lpc17_i2cdev_s *) arg;
+
+ irqstate_t flags = irqsave();
+ priv->state = 0xff;
+ sem_post (&priv->wait);
+ irqrestore (flags);
+}
+
+/*******************************************************************************
+ * Name: i2c_interrupt
+ *
+ * Description:
+ * The I2C Interrupt Handler
+ *
+ *******************************************************************************/
+
+static int i2c_interrupt (int irq, FAR void *context)
+{
+ struct lpc17_i2cdev_s *priv;
+#ifdef CONFIG_LPC17_I2C0
+ if (irq == LPC17_IRQ_I2C0)
+ {
+ priv=&i2cdevices[0];
+ }
+ else
+#endif
+#ifdef CONFIG_LPC17_I2C1
+ if (irq == LPC17_IRQ_I2C1)
+ {
+ priv=&i2cdevices[1];
+ }
+ else
+#endif
+#ifdef CONFIG_LPC17_I2C2
+ if (irq == LPC17_IRQ_I2C2)
+ {
+ priv=&i2cdevices[2];
+ }
+ else
+#endif
+ {
+ PANIC(OSERR_INTERNAL);
+ }
+/*
+ * refrence UM10360 19.10.5
+ */
+ uint32_t state = getreg32(priv->base+LPC17_I2C_STAT_OFFSET);
+ putreg32(I2C_CONCLR_SIC,priv->base+LPC17_I2C_CONCLR_OFFSET);
+ priv->state=state;
+ state &=0xf8;
+ switch (state)
+ {
+ case 0x00: //Bus Error
+ case 0x20:
+ case 0x30:
+ case 0x38:
+ case 0x48:
+ i2c_stop(priv);
+ break;
+ case 0x08: //START
+ case 0x10: //Repeat START
+ putreg32(priv->msg.addr,priv->base+LPC17_I2C_DAT_OFFSET);
+ putreg32(I2C_CONCLR_STAC,priv->base+LPC17_I2C_CONCLR_OFFSET);
+ break;
+ case 0x18:
+ priv->wrcnt=0;
+ putreg32(priv->msg.buffer[0],priv->base+LPC17_I2C_DAT_OFFSET);
+ break;
+ case 0x28:
+ priv->wrcnt++;
+ if(priv->wrcnt<priv->msg.length)
+ putreg32(priv->msg.buffer[priv->wrcnt],priv->base+LPC17_I2C_DAT_OFFSET);
+ else
+ i2c_stop(priv);
+ break;
+ case 0x40:
+ priv->rdcnt=-1;
+ putreg32(I2C_CONSET_AA,priv->base+LPC17_I2C_CONSET_OFFSET);
+ break;
+ case 0x50:
+ priv->rdcnt++;
+ if(priv->rdcnt<priv->msg.length)
+ priv->msg.buffer[priv->rdcnt]=getreg32(priv->base+LPC17_I2C_BUFR_OFFSET);
+ if(priv->rdcnt>=priv->msg.length-1)
+ putreg32(I2C_CONCLR_AAC|I2C_CONCLR_SIC,priv->base+LPC17_I2C_CONCLR_OFFSET);
+ break;
+ case 0x58:
+ i2c_stop(priv);
+ break;
+ default:
+ i2c_stop(priv);
+ break;
+ }
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+
+/*******************************************************************************
+ * Name: up_i2cinitialize
+ *
+ * Description:
+ * Initialise an I2C device
+ *
+ *******************************************************************************/
+
+struct i2c_dev_s *up_i2cinitialize(int port)
+{
+ struct lpc17_i2cdev_s *priv;
+
+ if (port>2)
+ {
+ dbg("lpc I2C Only support 0,1,2\n");
+ return NULL;
+ }
+
+ irqstate_t flags;
+ uint32_t regval;
+
+ flags = irqsave();
+
+ priv= &i2cdevices[port];
+#ifdef CONFIG_LPC17_I2C0
+ if (port==0)
+ {
+ priv= (FAR struct lpc17_i2cdev_s *)&i2cdevices[0];
+ priv->base = LPC17_I2C0_BASE;
+ priv->irqid = LPC17_IRQ_I2C0;
+
+ 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);
+
+ lpc17_configgpio(GPIO_I2C0_SCL);
+ lpc17_configgpio(GPIO_I2C0_SDA);
+
+ putreg32 (LPC17_CCLK/CONFIG_I2C0_FREQ/2, priv->base + LPC17_I2C_SCLH_OFFSET);
+ putreg32 (LPC17_CCLK/CONFIG_I2C0_FREQ/2, priv->base + LPC17_I2C_SCLL_OFFSET);
+
+ }
+ else
+#endif
+#ifdef CONFIG_LPC17_I2C1
+ if(port==1)
+ {
+ priv= (FAR struct lpc17_i2cdev_s *)&i2cdevices[1];
+ priv->base = LPC17_I2C1_BASE;
+ priv->irqid = LPC17_IRQ_I2C1;
+
+ 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);
+
+ lpc17_configgpio(GPIO_I2C1_SCL);
+ lpc17_configgpio(GPIO_I2C1_SDA);
+
+ putreg32 (LPC17_CCLK/CONFIG_I2C1_FREQ/2, priv->base + LPC17_I2C_SCLH_OFFSET);
+ putreg32 (LPC17_CCLK/CONFIG_I2C1_FREQ/2, priv->base + LPC17_I2C_SCLL_OFFSET);
+ }
+ else
+#endif
+#ifdef CONFIG_LPC17_I2C2
+ if(port==2)
+ {
+ priv= (FAR struct lpc17_i2cdev_s *)&i2cdevices[2];
+ priv->base = LPC17_I2C2_BASE;
+ priv->irqid = LPC17_IRQ_I2C2;
+
+ 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);
+
+ lpc17_configgpio(GPIO_I2C2_SCL);
+ lpc17_configgpio(GPIO_I2C2_SDA);
+
+ putreg32 (LPC17_CCLK/CONFIG_I2C2_FREQ/2, priv->base + LPC17_I2C_SCLH_OFFSET);
+ putreg32 (LPC17_CCLK/CONFIG_I2C2_FREQ/2, priv->base + LPC17_I2C_SCLL_OFFSET);
+ }
+ else
+#endif
+ {
+ return NULL;
+ }
+ 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, i2c_interrupt);
+
+ /* Enable Interrupt Handler */
+ up_enable_irq(priv->irqid);
+
+ /* Install our operations */
+ priv->dev.ops = &lpc17_i2c_ops;
+
+ return &priv->dev;
+}
+
+/*******************************************************************************
+ * Name: up_i2cuninitalize
+ *
+ * Description:
+ * Uninitialise an I2C device
+ *
+ *******************************************************************************/
+
+int up_i2cuninitialize(FAR struct i2c_dev_s * dev)
+{
+ struct lpc17_i2cdev_s *priv = (struct lpc17_i2cdev_s *) dev;
+
+ putreg32(I2C_CONCLRT_I2ENC,priv->base+LPC17_I2C_CONCLR_OFFSET);
+ up_disable_irq(priv->irqid);
+ irq_detach (priv->irqid);
+ return OK;
+}
+
+#endif
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_i2c.h b/nuttx/arch/arm/src/lpc17xx/lpc17_i2c.h
new file mode 100644
index 000000000..10e1fbeac
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_i2c.h
@@ -0,0 +1,208 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_i2c.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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_LPC17_I2C_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_i2s.h b/nuttx/arch/arm/src/lpc17xx/lpc17_i2s.h
new file mode 100644
index 000000000..638d40178
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_i2s.h
@@ -0,0 +1,190 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_i2s
+ *
+ * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_I2S_H
+#define __ARCH_ARM_SRC_LPC17XX_LPC17_I2S_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "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_LPC17_I2S_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_idle.c b/nuttx/arch/arm/src/lpc17xx/lpc17_idle.c
new file mode 100644
index 000000000..88cd817f7
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_idle.c
@@ -0,0 +1,104 @@
+/****************************************************************************
+ * arch/arm/src/lpc17/lpc17_idle.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <arch/board/board.h>
+#include <nuttx/config.h>
+
+#include <nuttx/arch.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() up_ledon(LED_IDLE)
+# define END_IDLE() up_ledoff(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/nuttx/arch/arm/src/lpc17xx/lpc17_internal.h b/nuttx/arch/arm/src/lpc17xx/lpc17_internal.h
new file mode 100644
index 000000000..8b4358196
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_internal.h
@@ -0,0 +1,854 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_internal.h
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_INTERNAL_H
+#define __ARCH_ARM_SRC_LPC17XX_LPC17_INTERNAL_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#if defined(CONFIG_LPC17_SPI) || defined(CONFIG_LPC17_SSP0) || defined(CONFIG_LPC17_SSP1)
+# include <nuttx/spi.h>
+#endif
+
+#include "up_internal.h"
+#include "chip.h"
+
+/************************************************************************************
+ * Definitions
+ ************************************************************************************/
+
+/* Configuration ********************************************************************/
+
+/* 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)
+
+/* 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 (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 (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
+ ************************************************************************************/
+
+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 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
+
+/************************************************************************************
+ * Inline Functions
+ ************************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+#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];
+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 Function Prototypes
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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.
+ *
+ ************************************************************************************/
+
+EXTERN void lpc17_clockconfig(void);
+
+/************************************************************************************
+ * 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.
+ *
+ ************************************************************************************/
+
+EXTERN void lpc17_lowsetup(void);
+
+/************************************************************************************
+ * Name: lpc17_gpioirqinitialize
+ *
+ * Description:
+ * Initialize logic to support a second level of interrupt decoding for GPIO pins.
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_GPIO_IRQ
+EXTERN 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.
+ *
+ ************************************************************************************/
+
+EXTERN int lpc17_configgpio(uint16_t cfgset);
+
+/************************************************************************************
+ * Name: lpc17_gpiowrite
+ *
+ * Description:
+ * Write one or zero to the selected GPIO pin
+ *
+ ************************************************************************************/
+
+EXTERN void lpc17_gpiowrite(uint16_t pinset, bool value);
+
+/************************************************************************************
+ * Name: lpc17_gpioread
+ *
+ * Description:
+ * Read one or zero from the selected GPIO pin
+ *
+ ************************************************************************************/
+
+EXTERN bool lpc17_gpioread(uint16_t pinset);
+
+/************************************************************************************
+ * Name: lpc17_gpioirqenable
+ *
+ * Description:
+ * Enable the interrupt for specified GPIO IRQ
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_GPIO_IRQ
+EXTERN 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
+EXTERN 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
+EXTERN int lpc17_dumpgpio(uint16_t pinset, const char *msg);
+#else
+# define lpc17_dumpgpio(p,m)
+#endif
+
+/************************************************************************************
+ * 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!
+ *
+ ************************************************************************************/
+
+EXTERN void lpc17_clrpend(int irq);
+
+/************************************************************************************
+ * Name: lpc17_spi/ssp0/ssp1select, lpc17_spi/ssp0/ssp1status, and
+ * lpc17_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.h). All other methods
+ * including up_spiinitialize()) are provided by common LPC17xx logic. To use
+ * this common SPI logic on your board:
+ *
+ * 1. Provide logic in lpc17_boardinitialize() to configure SPI/SSP chip select
+ * pins.
+ * 2. Provide lpc17_spi/ssp0/ssp1select() and lpc17_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
+ * lpc17_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 up_spiinitialize() in your low level application
+ * initialization logic
+ * 4. The handle returned by up_spiinitialize() 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_LPC17_SPI
+EXTERN void lpc17_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t lpc17_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+#ifdef CONFIG_SPI_CMDDATA
+EXTERN int lpc17_spicmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+#endif
+#endif
+
+#ifdef CONFIG_LPC17_SSP0
+EXTERN void lpc17_ssp0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t lpc17_ssp0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+#ifdef CONFIG_SPI_CMDDATA
+EXTERN int lpc17_ssp0cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+#endif
+#endif
+
+#ifdef CONFIG_LPC17_SSP1
+EXTERN void lpc17_ssp1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t lpc17_ssp1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+#ifdef CONFIG_SPI_CMDDATA
+EXTERN int lpc17_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
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_LPC17_SPI
+EXTERN void spi_flush(FAR struct spi_dev_s *dev);
+#endif
+
+#if defined(CONFIG_LPC17_SSP0) || defined(CONFIG_LPC17_SSP1)
+EXTERN void ssp_flush(FAR struct spi_dev_s *dev);
+#endif
+
+/****************************************************************************
+ * Name: lpc17_spi/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.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_SPI
+EXTERN int lpc17_spiregister(FAR struct spi_dev_s *dev,
+ spi_mediachange_t callback, void *arg);
+#endif
+
+#ifdef CONFIG_LPC17_SSP0
+EXTERN int lpc17_ssp0register(FAR struct spi_dev_s *dev,
+ spi_mediachange_t callback, void *arg);
+#endif
+
+#ifdef CONFIG_LPC17_SSP1
+EXTERN int lpc17_ssp1register(FAR struct spi_dev_s *dev,
+ spi_mediachange_t callback, void *arg);
+#endif
+#endif
+
+/****************************************************************************
+ * Name: lpc17_dmainitialize
+ *
+ * Description:
+ * Initialize the GPDMA subsystem.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_LPC17_GPDMA
+EXTERN void lpc17_dmainitilaize(void);
+#endif
+
+/****************************************************************************
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_LPC17_GPDMA
+EXTERN DMA_HANDLE lpc17_dmachannel(void);
+#endif
+
+/****************************************************************************
+ * 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
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_LPC17_GPDMA
+EXTERN void lpc17_dmafree(DMA_HANDLE handle);
+#endif
+
+/****************************************************************************
+ * Name: lpc17_dmasetup
+ *
+ * Description:
+ * Configure DMA for one transfer.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_LPC17_GPDMA
+EXTERN int lpc17_dmarxsetup(DMA_HANDLE handle,
+ uint32_t control, uint32_t config,
+ uint32_t srcaddr, uint32_t destaddr,
+ size_t nbytes);
+#endif
+
+/****************************************************************************
+ * Name: lpc17_dmastart
+ *
+ * Description:
+ * Start the DMA transfer
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_LPC17_GPDMA
+EXTERN int lpc17_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg);
+#endif
+
+/****************************************************************************
+ * 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
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_LPC17_GPDMA
+EXTERN void lpc17_dmastop(DMA_HANDLE handle);
+#endif
+
+/****************************************************************************
+ * Name: lpc17_dmasample
+ *
+ * Description:
+ * Sample DMA register contents
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_LPC17_GPDMA
+#ifdef CONFIG_DEBUG_DMA
+EXTERN void lpc17_dmasample(DMA_HANDLE handle, struct lpc17_dmaregs_s *regs);
+#else
+# define lpc17_dmasample(handle,regs)
+#endif
+#endif
+
+/****************************************************************************
+ * Name: lpc17_dmadump
+ *
+ * Description:
+ * Dump previously sampled DMA register contents
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_LPC17_GPDMA
+#ifdef CONFIG_DEBUG_DMA
+EXTERN void lpc17_dmadump(DMA_HANDLE handle, const struct lpc17_dmaregs_s *regs,
+ const char *msg);
+#else
+# define lpc17_dmadump(handle,regs,msg)
+#endif
+#endif
+
+/****************************************************************************
+ * 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
+
+/****************************************************************************
+ * Name: lpc17_dacinitialize
+ *
+ * Description:
+ * Initialize the DAC
+ *
+ * Returned Value:
+ * Valid dac device structure reference on succcess; a NULL on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_LPC17_DAC
+EXTERN FAR struct dac_dev_s *lpc17_dacinitialize(void);
+#endif
+
+/****************************************************************************
+ * 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;
+EXTERN FAR struct can_dev_s *lpc17_caninitialize(int port);
+#endif
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_INTERNAL_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_irq.c b/nuttx/arch/arm/src/lpc17xx/lpc17_irq.c
new file mode 100644
index 000000000..8af2adafe
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_irq.c
@@ -0,0 +1,471 @@
+/****************************************************************************
+ * arch/arm/src/lpc17/lpc17_irq.c
+ * arch/arm/src/chip/lpc17_irq.c
+ *
+ * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "nvic.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+#include "lpc17_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* Enable NVIC debug features that are probably only desireable during
+ * bringup
+ */
+
+#undef LPC17_IRQ_DEBUG
+
+/* 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
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lpc17_dumpnvic
+ *
+ * Description:
+ * Dump some interesting NVIC registers
+ *
+ ****************************************************************************/
+
+#if defined(LPC17_IRQ_DEBUG) && defined (CONFIG_DEBUG)
+static void lpc17_dumpnvic(const char *msg, int irq)
+{
+ irqstate_t flags;
+
+ flags = irqsave();
+ slldbg("NVIC (%s, irq=%d):\n", msg, irq);
+ slldbg(" INTCTRL: %08x VECTAB: %08x\n",
+ getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB));
+#if 0
+ slldbg(" 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
+ slldbg(" IRQ ENABLE: %08x\n", getreg32(NVIC_IRQ0_31_ENABLE));
+ slldbg(" SYSH_PRIO: %08x %08x %08x\n",
+ getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY),
+ getreg32(NVIC_SYSH12_15_PRIORITY));
+ slldbg(" 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));
+ slldbg(" %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));
+ slldbg(" %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));
+ irqrestore(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)irqsave();
+ dbg("PANIC!!! NMI received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lpc17_busfault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Bus fault recived\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lpc17_usagefault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Usage fault received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lpc17_pendsv(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! PendSV received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lpc17_dbgmonitor(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Debug Monitor receieved\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lpc17_reserved(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Reserved interrupt\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+#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, uint32_t *regaddr, uint32_t *bit)
+{
+ 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;
+ *bit = 1 << (irq - LPC17_IRQ_EXTINT);
+ }
+ else if (irq < LPC17_IRQ_NIRQS)
+ {
+ *regaddr = NVIC_IRQ32_63_ENABLE;
+ *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)
+{
+ /* Disable all interrupts */
+
+ putreg32(0, NVIC_IRQ0_31_ENABLE);
+
+ /* Set all interrrupts (and exceptions) to the default priority */
+
+ putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);
+
+ putreg32(DEFPRIORITY32, NVIC_IRQ0_3_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ4_7_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ8_11_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ12_15_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ16_19_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ20_23_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ24_27_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ28_31_PRIORITY);
+
+ putreg32(DEFPRIORITY32, NVIC_IRQ32_35_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ36_39_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ40_43_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ44_47_PRIORITY);
+
+ /* 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
+
+ /* If the MPU is enabled, then attach and enable the Memory Management
+ * Fault handler.
+ */
+
+#ifdef CONFIG_ARMV7M_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_ARMV7M_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
+ setbasepri(NVIC_SYSH_PRIORITY_MAX);
+ irqrestore(0);
+#endif
+}
+
+/****************************************************************************
+ * Name: up_disable_irq
+ *
+ * Description:
+ * Disable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_disable_irq(int irq)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (lpc17_irqinfo(irq, &regaddr, &bit) == 0)
+ {
+ /* Clear the appropriate bit in the register to enable the interrupt */
+
+ 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)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (lpc17_irqinfo(irq, &regaddr, &bit) == 0)
+ {
+ /* Set the appropriate bit in the register to enable the interrupt */
+
+ 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_maskack_irq
+ *
+ * Description:
+ * Mask the IRQ and acknowledge it
+ *
+ ****************************************************************************/
+
+void up_maskack_irq(int irq)
+{
+ up_disable_irq(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)
+ {
+ irq -= 4;
+ regaddr = NVIC_SYSH_PRIORITY(irq);
+ }
+ else
+ {
+ 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/nuttx/arch/arm/src/lpc17xx/lpc17_lowputc.c b/nuttx/arch/arm/src/lpc17xx/lpc17_lowputc.c
new file mode 100644
index 000000000..ba90c1ff6
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_lowputc.c
@@ -0,0 +1,394 @@
+/**************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_lowputc.c
+ *
+ * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "lpc17_internal.h"
+#include "lpc17_syscon.h"
+#include "lpc17_uart.h"
+#include "lpc17_serial.h"
+
+/**************************************************************************
+ * Private 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:
+ *
+ * PCLK = CCLK / divisor
+ *
+ * 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).
+ *
+ * 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
+
+/* 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
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * 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
+ */
+
+ 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);
+
+ /* 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);
+#ifdef CONFIG_UART1_FLOWCONTROL
+ 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/nuttx/arch/arm/src/lpc17xx/lpc17_mcpwm.h b/nuttx/arch/arm/src/lpc17xx/lpc17_mcpwm.h
new file mode 100644
index 000000000..370aa42de
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_mcpwm.h
@@ -0,0 +1,280 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_mcpwm.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_MCPWM_H
+#define __ARCH_ARM_SRC_LPC17XX_LPC17_MCPWM_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "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_LPC17_MCPWM_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_memorymap.h b/nuttx/arch/arm/src/lpc17xx/lpc17_memorymap.h
new file mode 100644
index 000000000..ae66b684c
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_memorymap.h
@@ -0,0 +1,136 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_memorymap.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_MEMORYMAP_H
+#define __ARCH_ARM_SRC_LPC17XX_LPC17_MEMORYMAP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#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_LPC17_MEMORYMAP_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_ohciram.h b/nuttx/arch/arm/src/lpc17xx/lpc17_ohciram.h
new file mode 100644
index 000000000..1e0564a87
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include "chip.h"
+#include "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/nuttx/arch/arm/src/lpc17xx/lpc17_pinconn.h b/nuttx/arch/arm/src/lpc17xx/lpc17_pinconn.h
new file mode 100644
index 000000000..c0e0ec916
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_pinconn.h
@@ -0,0 +1,635 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_pinconn.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_PINCONN_H
+#define __ARCH_ARM_SRC_LPC17XX_LPC17_PINCONN_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "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_LPC17_PINCONN_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_pwm.h b/nuttx/arch/arm/src/lpc17xx/lpc17_pwm.h
new file mode 100644
index 000000000..6555ce616
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_pwm.h
@@ -0,0 +1,223 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_pwm.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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 interrrupt */
+#define PWM_IR_MR1 (1 << 1) /* Bit 1: PWM match channel 1 interrrupt */
+#define PWM_IR_MR2 (1 << 2) /* Bit 2: PWM match channel 2 interrrupt */
+#define PWM_IR_MR3 (1 << 3) /* Bit 3: PWM match channel 3 interrrupt */
+#define PWM_IR_CAP0 (1 << 4) /* Bit 4: Capture input 0 interrrupt */
+#define PWM_IR_CAP1 (1 << 5) /* Bit 5: Capture input 1 interrrupt */
+ /* Bits 6-7: Reserved */
+#define PWM_IR_MR4 (1 << 8) /* Bit 8: PWM match channel 4 interrrupt */
+#define PWM_IR_MR5 (1 << 9) /* Bit 9: PWM match channel 5 interrrupt */
+#define PWM_IR_MR6 (1 << 10) /* Bit 10: PWM match channel 6 interrrupt */
+ /* 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_LPC17_PWM_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_qei.h b/nuttx/arch/arm/src/lpc17xx/lpc17_qei.h
new file mode 100644
index 000000000..d1637f943
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_qei.h
@@ -0,0 +1,190 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_qei.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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 */
+
+/* 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 */
+ /* Bits 4-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 */
+ /* Bits 13-31: reserved */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_QEI_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_rit.h b/nuttx/arch/arm/src/lpc17xx/lpc17_rit.h
new file mode 100644
index 000000000..2da0164bd
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_rit.h
@@ -0,0 +1,92 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_rit.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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_LPC17_RIT_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_rtc.h b/nuttx/arch/arm/src/lpc17xx/lpc17_rtc.h
new file mode 100644
index 000000000..195e403c1
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_rtc.h
@@ -0,0 +1,270 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_rtc.h
+ *
+ * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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 Enable register */
+ /* Bits 0-3: Reserved */
+#define RTC_AUXEN_RTCOSCF (1 << 4) /* Bit 4: RTC Oscillator Fail detect flag */
+ /* Bits 5-31: Reserved */
+/* RTC Auxiliary control 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_LPC17_RTC_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_serial.c b/nuttx/arch/arm/src/lpc17xx/lpc17_serial.c
new file mode 100644
index 000000000..5ea6348e0
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_serial.c
@@ -0,0 +1,1518 @@
+/****************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_serial.c
+ *
+ * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+#ifdef CONFIG_SERIAL_TERMIOS
+# include <termios.h>
+#endif
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+
+#include <arch/serial.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+#include "lpc17_internal.h"
+#include "lpc17_uart.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) */
+ uint8_t cclkdiv; /* Divisor needed to get PCLK from CCLK */
+ 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 Variables
+ ****************************************************************************/
+
+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,
+ .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.
+ *
+ * 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.
+ *
+ ************************************************************************************/
+
+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:
+ *
+ * PCLK = CCLK / divisor.
+ *
+ * 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;
+ }
+}
+
+/************************************************************************************
+ * 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(uint32_t clkdiv)
+{
+ uint32_t regval;
+ irqstate_t flags;
+
+ /* Step 1: Enable power on UART0 */
+
+ flags = irqsave();
+ regval = getreg32(LPC17_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCUART0;
+ putreg32(regval, LPC17_SYSCON_PCONP);
+
+ /* Step 2: Enable clocking on UART */
+
+ regval = getreg32(LPC17_SYSCON_PCLKSEL0);
+ regval &= ~SYSCON_PCLKSEL0_UART0_MASK;
+ regval |= (clkdiv << SYSCON_PCLKSEL0_UART0_SHIFT);
+ putreg32(regval, LPC17_SYSCON_PCLKSEL0);
+
+ /* Step 3: Configure I/O pins */
+
+ lpc17_configgpio(GPIO_UART0_TXD);
+ lpc17_configgpio(GPIO_UART0_RXD);
+ irqrestore(flags);
+};
+#endif
+
+#ifdef CONFIG_LPC17_UART1
+static inline void lpc17_uart1config(uint32_t clkdiv)
+{
+ uint32_t regval;
+ irqstate_t flags;
+
+ /* Step 1: Enable power on UART1 */
+
+ flags = irqsave();
+ regval = getreg32(LPC17_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCUART1;
+ putreg32(regval, LPC17_SYSCON_PCONP);
+
+ /* Step 2: Enable clocking on UART */
+
+ regval = getreg32(LPC17_SYSCON_PCLKSEL0);
+ regval &= ~SYSCON_PCLKSEL0_UART1_MASK;
+ regval |= (clkdiv << SYSCON_PCLKSEL0_UART1_SHIFT);
+ putreg32(regval, LPC17_SYSCON_PCLKSEL0);
+
+ /* Step 3: Configure I/O pins */
+
+ lpc17_configgpio(GPIO_UART1_TXD);
+ lpc17_configgpio(GPIO_UART1_RXD);
+#ifdef CONFIG_UART1_FLOWCONTROL
+ 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
+ irqrestore(flags);
+};
+#endif
+
+#ifdef CONFIG_LPC17_UART2
+static inline void lpc17_uart2config(uint32_t clkdiv)
+{
+ uint32_t regval;
+ irqstate_t flags;
+
+ /* Step 1: Enable power on UART2 */
+
+ flags = irqsave();
+ regval = getreg32(LPC17_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCUART2;
+ putreg32(regval, LPC17_SYSCON_PCONP);
+
+ /* Step 2: Enable clocking on UART */
+
+ regval = getreg32(LPC17_SYSCON_PCLKSEL1);
+ regval &= ~SYSCON_PCLKSEL1_UART2_MASK;
+ regval |= (clkdiv << SYSCON_PCLKSEL1_UART2_SHIFT);
+ putreg32(regval, LPC17_SYSCON_PCLKSEL1);
+
+ /* Step 3: Configure I/O pins */
+
+ lpc17_configgpio(GPIO_UART2_TXD);
+ lpc17_configgpio(GPIO_UART2_RXD);
+ irqrestore(flags);
+};
+#endif
+
+#ifdef CONFIG_LPC17_UART3
+static inline void lpc17_uart3config(uint32_t clkdiv)
+{
+ uint32_t regval;
+ irqstate_t flags;
+
+ /* Step 1: Enable power on UART3 */
+
+ flags = irqsave();
+ regval = getreg32(LPC17_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCUART3;
+ putreg32(regval, LPC17_SYSCON_PCONP);
+
+ /* Step 2: Enable clocking on UART */
+
+ regval = getreg32(LPC17_SYSCON_PCLKSEL1);
+ regval &= ~SYSCON_PCLKSEL1_UART3_MASK;
+ regval |= (clkdiv << SYSCON_PCLKSEL1_UART3_SHIFT);
+ putreg32(regval, LPC17_SYSCON_PCLKSEL1);
+
+ /* Step 3: Configure I/O pins */
+
+ lpc17_configgpio(GPIO_UART3_TXD);
+ lpc17_configgpio(GPIO_UART3_RXD);
+ irqrestore(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).
+ *
+ ************************************************************************************/
+
+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);
+}
+
+/****************************************************************************
+ * 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_LPC17_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 */
+
+ dl = lpc17_uartdl(priv->baud, priv->cclkdiv);
+ 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 */
+
+#ifdef CONFIG_UART1_FLOWCONTROL
+ if (priv->uartbase == LPC17_UART1_BASE)
+ {
+ up_serialout(priv, LPC17_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;
+ 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(OSERR_INTERNAL);
+ }
+ 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)
+ {
+ 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;
+
+ case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
+ {
+ irqstate_t flags = irqsave();
+ up_enablebreaks(priv, true);
+ irqrestore(flags);
+ }
+ break;
+
+ case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
+ {
+ irqstate_t flags;
+ flags = irqsave();
+ up_enablebreaks(priv, false);
+ irqrestore(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);
+
+ /* DLAB open latch */
+
+ lcr = getreg32(priv->uartbase + LPC17_UART_LCR_OFFSET);
+ up_serialout(priv, LPC17_UART_LCR_OFFSET, (lcr | UART_LCR_DLAB));
+
+ /* Set the BAUD divisor */
+
+ dl = lpc17_uartdl(priv->baud, priv->cclkdiv);
+ 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 = irqsave();
+ 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);
+ }
+
+ irqrestore(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
+ g_uart0priv.cclkdiv = lpc17_uartcclkdiv(CONFIG_UART0_BAUD);
+#ifndef CONFIG_UART0_SERIAL_CONSOLE
+ lpc17_uart0config(g_uart0priv.cclkdiv);
+#endif
+ up_disableuartint(&g_uart0priv, NULL);
+#endif
+
+#ifdef CONFIG_LPC17_UART1
+ g_uart1priv.cclkdiv = lpc17_uartcclkdiv(CONFIG_UART1_BAUD);
+#ifndef CONFIG_UART1_SERIAL_CONSOLE
+ lpc17_uart1config(g_uart1priv.cclkdiv);
+#endif
+ up_disableuartint(&g_uart1priv, NULL);
+#endif
+
+#ifdef CONFIG_LPC17_UART2
+ g_uart2priv.cclkdiv = lpc17_uartcclkdiv(CONFIG_UART2_BAUD);
+#ifndef CONFIG_UART2_SERIAL_CONSOLE
+ lpc17_uart2config(g_uart2priv.cclkdiv);
+#endif
+ up_disableuartint(&g_uart2priv, NULL);
+#endif
+
+#ifdef CONFIG_LPC17_UART3
+ g_uart3priv.cclkdiv = lpc17_uartcclkdiv(CONFIG_UART3_BAUD);
+#ifndef CONFIG_UART3_SERIAL_CONSOLE
+ lpc17_uart3config(g_uart3priv.cclkdiv);
+#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/nuttx/arch/arm/src/lpc17xx/lpc17_serial.h b/nuttx/arch/arm/src/lpc17xx/lpc17_serial.h
new file mode 100644
index 000000000..27d7da9d1
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_serial.h
@@ -0,0 +1,127 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_serial.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <arch/board/board.h>
+
+#include "lpc17_uart.h"
+#include "lpc17_syscon.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_FLOWCONTROL
+# undef CONFIG_UART2_FLOWCONTROL
+# undef CONFIG_UART3_FLOWCONTROL
+#ifndef CONFIG_LPC17_UART1
+# undef CONFIG_UART1_FLOWCONTROL
+#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/nuttx/arch/arm/src/lpc17xx/lpc17_spi.c b/nuttx/arch/arm/src/lpc17xx/lpc17_spi.c
new file mode 100644
index 000000000..a7bb15931
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_spi.c
@@ -0,0 +1,608 @@
+/****************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_spi.c
+ *
+ * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+#include <nuttx/arch.h>
+#include <nuttx/spi.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lpc17_internal.h"
+#include "lpc17_syscon.h"
+#include "lpc17_pinconn.h"
+#include "lpc17_spi.h"
+
+#ifdef CONFIG_LPC17_SPI
+
+/****************************************************************************
+ * 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
+
+/* 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_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 */
+#ifndef CONFIG_SPI_OWNBUS
+ 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 */
+#endif
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* SPI methods */
+
+#ifndef CONFIG_SPI_OWNBUS
+static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
+#endif
+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 =
+{
+#ifndef CONFIG_SPI_OWNBUS
+ .lock = spi_lock,
+#endif
+ .select = lpc17_spiselect,
+ .setfrequency = spi_setfrequency,
+ .setmode = spi_setmode,
+ .setbits = spi_setbits,
+ .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
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_OWNBUS
+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;
+}
+#endif
+
+/****************************************************************************
+ * 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);
+#ifndef CONFIG_SPI_OWNBUS
+ if (priv->frequency == frequency)
+ {
+ /* We are already at this frequency. Return the actual. */
+
+ return priv->actual;
+ }
+#endif
+
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->frequency = frequency;
+ priv->actual = actual;
+#endif
+
+ 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? */
+
+#ifndef CONFIG_SPI_OWNBUS
+ if (mode != priv->mode)
+ {
+#endif
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->mode = mode;
+ }
+#endif
+}
+
+/****************************************************************************
+ * 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);
+#ifndef CONFIG_SPI_OWNBUS
+ if (nbits != priv->nbits)
+ {
+#endif
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->nbits = nbits;
+ }
+#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(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: up_spiinitialize
+ *
+ * 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 *up_spiinitialize(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 = irqsave();
+ 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);
+ irqrestore(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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->frequency = 0;
+ priv->nbits = 8;
+ priv->mode = SPIDEV_MODE0;
+#endif
+
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ sem_init(&priv->exclsem, 0, 1);
+#endif
+ return &priv->spidev;
+}
+
+#endif /* CONFIG_LPC17_SPI */
+
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_spi.h b/nuttx/arch/arm/src/lpc17xx/lpc17_spi.h
new file mode 100644
index 000000000..880966eb1
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_spi.h
@@ -0,0 +1,141 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_spi.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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_LPC17_SPI_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c b/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c
new file mode 100644
index 000000000..76c446c7d
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c
@@ -0,0 +1,929 @@
+/****************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_ssp.c
+ *
+ * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+#include <nuttx/arch.h>
+#include <nuttx/spi.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lpc17_internal.h"
+#include "lpc17_syscon.h"
+#include "lpc17_pinconn.h"
+#include "lpc17_ssp.h"
+
+#if defined(CONFIG_LPC17_SSP0) || defined(CONFIG_LPC17_SSP1)
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* The following enable debug output from this file (needs CONFIG_DEBUG too).
+ *
+ * CONFIG_SPI_DEBUG - Define to enable basic SSP debug
+ * CONFIG_VERBOSE - Define to enable verbose SSP debug
+ */
+
+#ifdef CONFIG_SPI_DEBUG
+# define sspdbg lldbg
+# ifdef CONFIG_VERBOSE
+# define spivdbg lldbg
+# else
+# define spivdbg(x...)
+# endif
+#else
+# define sspdbg(x...)
+# define spivdbg(x...)
+#endif
+
+/* SSP Clocking.
+ *
+ * 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
+
+/****************************************************************************
+ * 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
+#ifndef CONFIG_SPI_OWNBUS
+ 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 */
+#endif
+};
+
+/****************************************************************************
+ * 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+static int ssp_lock(FAR struct spi_dev_s *dev, bool lock);
+#endif
+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
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#ifdef CONFIG_LPC17_SSP0
+static const struct spi_ops_s g_spi0ops =
+{
+#ifndef CONFIG_SPI_OWNBUS
+ .lock = ssp_lock,
+#endif
+ .select = lpc17_ssp0select, /* Provided externally */
+ .setfrequency = ssp_setfrequency,
+ .setmode = ssp_setmode,
+ .setbits = ssp_setbits,
+ .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 =
+{
+#ifndef CONFIG_SPI_OWNBUS
+ .lock = ssp_lock,
+#endif
+ .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 */
+
+/****************************************************************************
+ * 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
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_OWNBUS
+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;
+}
+#endif
+
+/****************************************************************************
+ * 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 divisor;
+ uint32_t actual;
+
+ /* Check if the requested frequence is the same as the frequency selection */
+
+ DEBUGASSERT(priv && frequency <= SSP_CLOCK / 2);
+#ifndef CONFIG_SPI_OWNBUS
+ if (priv->frequency == frequency)
+ {
+ /* We are already at this frequency. Return the actual. */
+
+ return priv->actual;
+ }
+#endif
+
+ /* frequency = SSP_CLOCK / divisor, or divisor = SSP_CLOCK / frequency */
+
+ divisor = SSP_CLOCK / 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, LPC17_SSP_CPSR_OFFSET, divisor);
+
+ /* Calculate the new actual */
+
+ actual = SSP_CLOCK / divisor;
+
+ /* Save the frequency setting */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->frequency = frequency;
+ priv->actual = actual;
+#endif
+
+ 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? */
+
+#ifndef CONFIG_SPI_OWNBUS
+ if (mode != priv->mode)
+ {
+#endif
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->mode = mode;
+ }
+#endif
+}
+
+/****************************************************************************
+ * 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);
+#ifndef CONFIG_SPI_OWNBUS
+ if (nbits != priv->nbits)
+ {
+#endif
+ /* Yes... Set CR1 appropriately */
+
+ regval = ssp_getreg(priv, LPC17_SSP_CR0_OFFSET);
+ regval &= ~SSP_CR0_DSS_MASK;
+ regval |= ((nbits - 1) << SSP_CR0_DSS_SHIFT);
+ regval = ssp_getreg(priv, LPC17_SSP_CR0_OFFSET);
+
+ /* Save the selection so the subsequence re-configurations will be faster */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->nbits = nbits;
+ }
+#endif
+}
+
+/****************************************************************************
+ * 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 = irqsave();
+ lpc17_configgpio(GPIO_SSP0_SCK);
+ lpc17_configgpio(GPIO_SSP0_MISO);
+ lpc17_configgpio(GPIO_SSP0_MOSI);
+
+ /* Configure clocking */
+
+ regval = getreg32(LPC17_SYSCON_PCLKSEL1);
+ regval &= ~SYSCON_PCLKSEL1_SSP0_MASK;
+ regval |= (SSP_PCLKSET_DIV << SYSCON_PCLKSEL1_SSP0_SHIFT);
+ putreg32(regval, LPC17_SYSCON_PCLKSEL1);
+
+ /* Enable peripheral clocking to SSP0 */
+
+ regval = getreg32(LPC17_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCSSP0;
+ putreg32(regval, LPC17_SYSCON_PCONP);
+ irqrestore(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 = irqsave();
+ lpc17_configgpio(GPIO_SSP1_SCK);
+ lpc17_configgpio(GPIO_SSP1_MISO);
+ lpc17_configgpio(GPIO_SSP1_MOSI);
+
+ /* Configure clocking */
+
+ regval = getreg32(LPC17_SYSCON_PCLKSEL0);
+ regval &= ~SYSCON_PCLKSEL0_SSP1_MASK;
+ regval |= (SSP_PCLKSET_DIV << SYSCON_PCLKSEL0_SSP1_SHIFT);
+ putreg32(regval, LPC17_SYSCON_PCLKSEL0);
+
+ /* Enable peripheral clocking to SSP0 and SSP1 */
+
+ regval = getreg32(LPC17_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCSSP1;
+ putreg32(regval, LPC17_SYSCON_PCONP);
+ irqrestore(flags);
+
+ return &g_ssp1dev;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_spiinitialize
+ *
+ * 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 *up_spiinitialize(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
+ 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->frequency = 0;
+ priv->nbits = 8;
+ priv->mode = SPIDEV_MODE0;
+#endif
+
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ sem_init(&priv->exclsem, 0, 1);
+#endif
+
+ /* 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/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.h b/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.h
new file mode 100644
index 000000000..52b88da68
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.h
@@ -0,0 +1,174 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_ssp.h
+ *
+ * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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)
+
+/* 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_LPC17_SSP_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_start.c b/nuttx/arch/arm/src/lpc17xx/lpc17_start.c
new file mode 100644
index 000000000..abbe6e213
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_start.c
@@ -0,0 +1,151 @@
+/****************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_start.c
+ * arch/arm/src/chip/lpc17_start.c
+ *
+ * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/init.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "lpc17_internal.h"
+
+/****************************************************************************
+ * Private 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)
+{
+ const uint32_t *src;
+ uint32_t *dest;
+
+ /* Configure the uart so that we can get debug output as soon as possible */
+
+ lpc17_clockconfig();
+ 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 intialized 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');
+
+ /* Initialize onboard resources */
+
+ lpc17_boardinitialize();
+ showprogress('E');
+
+ /* Then start NuttX */
+
+ showprogress('\r');
+ showprogress('\n');
+ os_start();
+
+ /* Shouldn't get here */
+
+ for(;;);
+}
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_syscon.h b/nuttx/arch/arm/src/lpc17xx/lpc17_syscon.h
new file mode 100644
index 000000000..ce8654645
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_syscon.h
@@ -0,0 +1,494 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_syscon.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_SYSCON_H
+#define __ARCH_ARM_SRC_LPC17XX_LPC17_SYSCON_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "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: PLL01Multiplier 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 << 24) /* Bit 8: PLL1 enable readback */
+#define SYSCON_PLL1STAT_PLLC (1 << 25) /* Bit 9: PLL1 connect readback */
+#define SYSCON_PLL1STAT_PLOCK (1 << 26) /* 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_OSCRANGE (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_LPC17_SYSCON_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_timer.h b/nuttx/arch/arm/src/lpc17xx/lpc17_timer.h
new file mode 100644
index 000000000..207c6d5cc
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_timer.h
@@ -0,0 +1,250 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_timer.h
+ *
+ * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "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_LPC17_TIMER_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_timerisr.c b/nuttx/arch/arm/src/lpc17xx/lpc17_timerisr.c
new file mode 100644
index 000000000..918c153a4
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_timerisr.c
@@ -0,0 +1,151 @@
+/****************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_timerisr.c
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <time.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "nvic.h"
+#include "clock_internal.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lpc17_internal.h"
+
+/****************************************************************************
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize
+ * the timer interrupt.
+ *
+ ****************************************************************************/
+
+void up_timerinit(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/nuttx/arch/arm/src/lpc17xx/lpc17_uart.h b/nuttx/arch/arm/src/lpc17xx/lpc17_uart.h
new file mode 100644
index 000000000..3664a0cb8
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_uart.h
@@ -0,0 +1,339 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_uart.h
+ *
+ * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_UART_H
+#define __ARCH_ARM_SRC_LPC17XX_LPC17_UART_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "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) */
+
+/* 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)
+#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)
+#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)
+#define LPC17_UART3_FIFOLVL (LPC17_UART3_BASE+LPC17_UART_FIFOLVL_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_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 */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_UART_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_usb.h b/nuttx/arch/arm/src/lpc17xx/lpc17_usb.h
new file mode 100644
index 000000000..8fd599584
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_usb.h
@@ -0,0 +1,778 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_usb.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_USB_H
+#define __ARCH_ARM_SRC_LPC17XX_LPC17_USB_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/usb/ohci.h>
+
+#include "chip.h"
+#include "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_LPC17_USB_H */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_usbdev.c b/nuttx/arch/arm/src/lpc17xx/lpc17_usbdev.c
new file mode 100644
index 000000000..a5cb443e4
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_usbdev.c
@@ -0,0 +1,3459 @@
+/*******************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_usbdev.c
+ *
+ * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/usb/usb.h>
+#include <nuttx/usb/usbdev.h>
+#include <nuttx/usb/usbdev_trace.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "lpc17_internal.h"
+#include "lpc17_usb.h"
+#include "lpc17_syscon.h"
+
+/*******************************************************************************
+ * 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 = irqsave();
+ 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 */
+
+ irqrestore(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 = irqsave();
+ privreq = lpc17_rqdequeue(privep);
+ irqrestore(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;
+ ret = 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
+
+#if 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);
+ }
+
+ /* 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 tranfer 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 = irqsave();
+ 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);
+
+ irqrestore(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 *)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);
+
+ 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 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);
+ 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 = irqsave();
+
+ /* 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;
+ }
+ }
+
+ irqrestore(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;
+ FAR struct lpc17_usbdev_s *priv;
+ irqstate_t flags;
+
+#ifdef CONFIG_DEBUG
+ if (!ep || !req)
+ {
+ usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_INVALIDPARMS), 0);
+ return -EINVAL;
+ }
+#endif
+ usbtrace(TRACE_EPCANCEL, privep->epphy);
+ priv = privep->dev;
+
+ flags = irqsave();
+ lpc17_cancelrequests(privep);
+ irqrestore(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 = irqsave();
+ 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);
+ }
+ irqrestore(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 = irqsave();
+ 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));
+ irqrestore(flags);
+
+ /* And return the pointer to the standard endpoint structure */
+
+ return &priv->eplist[epndx].ep;
+ }
+ }
+ /* Shouldn't get here */
+ }
+ irqrestore(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 = irqsave();
+ priv->epavail |= (1 << privep->epphy);
+ irqrestore(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 = irqsave();
+ if (DEVSTATUS_CONNECT(g_usbdev.devstatus))
+ {
+ arg |= CMD_STATUS_CONNECT;
+ }
+
+ lpc17_usbcmd(CMD_USBDEV_SETSTATUS, arg);
+ irqrestore(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 = irqsave();
+ 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);
+ irqrestore(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 = irqsave();
+ regval = lpc17_getreg(LPC17_SYSCON_USBINTST);
+ regval |= SYSCON_USBINTST_ENINTS;
+ lpc17_putreg(regval, LPC17_SYSCON_USBINTST);
+ irqrestore(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 = irqsave();
+ 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);
+ irqrestore(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/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c b/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c
new file mode 100644
index 000000000..de880cac1
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c
@@ -0,0 +1,2706 @@
+/*******************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_usbhost.c
+ *
+ * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved.
+ * Authors: Rafael Noronha <rafael@pdsolucoes.com.br>
+ * Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/usb/usb.h>
+#include <nuttx/usb/ohci.h>
+#include <nuttx/usb/usbhost.h>
+
+#include <arch/irq.h>
+
+#include "lpc17_internal.h" /* Includes default GPIO settings */
+#include <arch/board/board.h> /* May redefine GPIO settings */
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "lpc17_usb.h"
+#include "lpc17_syscon.h"
+#include "lpc17_ohciram.h"
+
+/*******************************************************************************
+ * 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
+
+/* 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;
+
+ /* The bound device class driver */
+
+ struct usbhost_class_s *class;
+
+ /* Driver status */
+
+ volatile bool connected; /* Connected to device */
+ volatile bool lowspeed; /* Low speed device attached. */
+ volatile bool rhswait; /* 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 rhssem; /* Semaphore to wait Writeback Done Head event */
+};
+
+/* 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;
+
+ /* Software specific fields */
+
+ uint8_t xfrtype; /* Transfer type. See SB_EP_ATTR_XFER_* in usb.h */
+ uint8_t interval; /* Periodic EP polling interval: 2, 4, 6, 16, or 32 */
+ volatile uint8_t tdstatus; /* TD control status bits from last Writeback Done Head event */
+ volatile bool wdhwait; /* TRUE: Thread is waiting for WDH interrupt */
+ sem_t wdhsem; /* Semaphore used to wait for Writeback Done Head event */
+ /* Unused bytes follow, depending on the size of sem_t */
+};
+
+/* 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);
+static void lpc17_putle16(uint8_t *dest, uint16_t val);
+
+/* 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
+
+/* ED list helper functions ****************************************************/
+
+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 FAR 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 FAR 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, uint32_t dirpid,
+ uint8_t *buffer, size_t buflen);
+
+/* Interrupt handling **********************************************************/
+
+static int lpc17_usbinterrupt(int irq, FAR void *context);
+
+/* USB host controller operations **********************************************/
+
+static int lpc17_wait(FAR struct usbhost_driver_s *drvr, bool connected);
+static int lpc17_enumerate(FAR struct usbhost_driver_s *drvr);
+static int lpc17_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
+ uint16_t maxpacketsize);
+static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr,
+ const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep);
+static int lpc17_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
+static int lpc17_alloc(FAR struct usbhost_driver_s *drvr,
+ FAR uint8_t **buffer, FAR size_t *maxlen);
+static int lpc17_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer);
+static int lpc17_ioalloc(FAR struct usbhost_driver_s *drvr,
+ FAR uint8_t **buffer, size_t buflen);
+static int lpc17_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer);
+static int lpc17_ctrlin(FAR struct usbhost_driver_s *drvr,
+ FAR const struct usb_ctrlreq_s *req,
+ FAR uint8_t *buffer);
+static int lpc17_ctrlout(FAR struct usbhost_driver_s *drvr,
+ FAR const struct usb_ctrlreq_s *req,
+ FAR const uint8_t *buffer);
+static int lpc17_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
+ FAR uint8_t *buffer, size_t buflen);
+static void lpc17_disconnect(FAR struct usbhost_driver_s *drvr);
+
+/* 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 =
+{
+ .drvr =
+ {
+ .wait = lpc17_wait,
+ .enumerate = lpc17_enumerate,
+ .ep0configure = lpc17_ep0configure,
+ .epalloc = lpc17_epalloc,
+ .epfree = lpc17_epfree,
+ .alloc = lpc17_alloc,
+ .free = lpc17_free,
+ .ioalloc = lpc17_ioalloc,
+ .iofree = lpc17_iofree,
+ .ctrlin = lpc17_ctrlin,
+ .ctrlout = lpc17_ctrlout,
+ .transfer = lpc17_transfer,
+ .disconnect = lpc17_disconnect,
+ },
+ .class = NULL,
+};
+
+/* 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
+
+/*******************************************************************************
+ * 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.
+ *
+ *******************************************************************************/
+
+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;
+}
+
+/*******************************************************************************
+ * 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 = irqsave();
+ ret = (struct lpc17_gtd_s *)g_tdfree;
+ if (ret)
+ {
+ g_tdfree = ((struct lpc17_list_s*)ret)->flink;
+ }
+
+ irqrestore(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 = (uint8_t *)g_iofree;
+ if (ret)
+ {
+ g_iofree = ((struct lpc17_list_s*)ret)->flink;
+ }
+ 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 = (struct lpc17_list_s *)buffer;
+ iofree->flink = g_iofree;
+ g_iofree = iofree;
+}
+#endif
+
+/*******************************************************************************
+ * 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
+ uint32_t regval;
+
+ /* 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);
+
+ /* BulkListEnable. This bit is set to enable the processing of the
+ * Bulk list. Note: once enabled, it remains. We really should
+ * never modify the bulk list while BLE is set.
+ */
+
+ regval = lpc17_getreg(LPC17_USBHOST_CTRL);
+ regval |= OHCI_CTRL_BLE;
+ lpc17_putreg(regval, LPC17_USBHOST_CTRL);
+ 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;
+ uint32_t regval;
+
+ /* Find the ED in the bulk list. NOTE: We really should never be mucking
+ * with the bulk list while BLE is set.
+ */
+
+ for (curr = (struct lpc17_ed_s *)lpc17_getreg(LPC17_USBHOST_BULKHEADED),
+ 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);
+
+ /* 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 */
+
+ lpc17_putreg(ed->hw.nexted, LPC17_USBHOST_BULKHEADED);
+
+ /* 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);
+ }
+ else
+ {
+ /* No.. set the forward link of the previous ED in the list
+ * skip over this ED.
+ */
+
+ prev->hw.nexted = ed->hw.nexted;
+ }
+ }
+
+ 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 FAR 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 quanitized 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 FAR 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)
+{
+ irqstate_t flags = irqsave();
+ int ret = -ENODEV;
+
+ /* 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.
+ */
+
+ ed->wdhwait = true;
+ ret = OK;
+ }
+
+ irqrestore(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, uint32_t dirpid,
+ uint8_t *buffer, size_t buflen)
+{
+ uint32_t toggle;
+ uint32_t regval;
+ int ret;
+
+ /* Set the request for the Writeback Done Head event well BEFORE enabling the
+ * transfer.
+ */
+
+ ret = lpc17_wdhwait(priv, EDCTRL);
+ if (ret != OK)
+ {
+ udbg("ERROR: Device disconnected\n");
+ 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 = lpc17_enqueuetd(priv, 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 = lpc17_getreg(LPC17_USBHOST_CMDST);
+ regval |= OHCI_CMDST_CLF;
+ lpc17_putreg(regval, LPC17_USBHOST_CMDST);
+
+ /* Wait for the Writeback Done Head interrupt */
+
+ lpc17_takesem(&EDCTRL->wdhsem);
+
+ /* Check the TD completion status bits */
+
+ if (EDCTRL->tdstatus == TD_CC_NOERROR)
+ {
+ ret = OK;
+ }
+ else
+ {
+ uvdbg("Bad TD completion status: %d\n", EDCTRL->tdstatus);
+ ret = -EIO;
+ }
+ }
+
+ /* Make sure that there is no outstanding request on this endpoint */
+
+ EDCTRL->wdhwait = false;
+ return ret;
+}
+
+/*******************************************************************************
+ * Name: lpc17_usbinterrupt
+ *
+ * Description:
+ * USB interrupt handler
+ *
+ *******************************************************************************/
+
+static int lpc17_usbinterrupt(int irq, FAR void *context)
+{
+ struct lpc17_usbhost_s *priv = &g_usbhost;
+ 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;
+
+ /* Notify any waiters */
+
+ if (priv->rhswait)
+ {
+ lpc17_givesem(&priv->rhssem);
+ priv->rhswait = false;
+ }
+ }
+ else
+ {
+ ulldbg("Spurious status change (connected)\n");
+ }
+
+ /* The LSDA (Low speed device attached) bit is valid
+ * when CCS == 1.
+ */
+
+ priv->lowspeed = (rhportst1 & OHCI_RHPORTST_LSDA) != 0;
+ ullvdbg("Speed:%s\n", priv->lowspeed ? "LOW" : "FULL");
+ }
+
+ /* Check if we are now disconnected */
+
+ else if (priv->connected)
+ {
+ /* Yes.. disconnect the device */
+
+ ullvdbg("Disconnected\n");
+ priv->connected = false;
+ priv->lowspeed = false;
+
+ /* Are we bound to a class instance? */
+
+ if (priv->class)
+ {
+ /* Yes.. Disconnect the class */
+
+ CLASS_DISCONNECTED(priv->class);
+ priv->class = NULL;
+ }
+
+ /* Notify any waiters for the Root Hub Status change event */
+
+ if (priv->rhswait)
+ {
+ lpc17_givesem(&priv->rhssem);
+ priv->rhswait = 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 = 0;
+
+ /* Process each TD in the write done list */
+
+ for (; td; td = next)
+ {
+ /* Get the ED in which this TD was enqueued */
+
+ struct lpc17_ed_s *ed = td->ed;
+ DEBUGASSERT(ed != NULL);
+
+ /* 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 CONFIG_DEBUG_USB
+ if (ed->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, ed->tdstatus,
+ lpc17_getreg(LPC17_USBHOST_RHPORTST1));
+ }
+#endif
+
+ /* Return the TD to the free list */
+
+ next = (struct lpc17_gtd_s *)td->hw.nexttd;
+ lpc17_tdfree(td);
+
+ /* And wake up the thread waiting for the WDH event */
+
+ if (ed->wdhwait)
+ {
+ lpc17_givesem(&ed->wdhsem);
+ ed->wdhwait = false;
+ }
+ }
+ }
+
+#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 disconneced.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * connected - TRUE: Wait for device to be connected; FALSE: wait for device
+ * to be disconnected
+ *
+ * Returned Values:
+ * Zero (OK) is returned when a device in connected. This function will not
+ * return until either (1) a device is connected or (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(FAR struct usbhost_driver_s *drvr, bool connected)
+{
+ struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
+ irqstate_t flags;
+
+ /* Are we already connected? */
+
+ flags = irqsave();
+ while (priv->connected == connected)
+ {
+ /* No... wait for the connection/disconnection */
+
+ priv->rhswait = true;
+ lpc17_takesem(&priv->rhssem);
+ }
+ irqrestore(flags);
+
+ udbg("Connected:%s\n", priv->connected ? "YES" : "NO");
+ return OK;
+}
+
+/*******************************************************************************
+ * 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 configdesc() method
+ * of the struct usbhost_class_s interface. After that, the class is in
+ * charge of the sequence of operations.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * - Only a single class bound to a single device is supported.
+ * - Called from a single thread so no mutual exclusion is required.
+ * - Never called from an interrupt handler.
+ *
+ *******************************************************************************/
+
+static int lpc17_enumerate(FAR struct usbhost_driver_s *drvr)
+{
+ struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
+
+ /* 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 */
+
+ up_mdelay(100);
+
+ /* 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);
+ up_mdelay(200);
+
+ /* Let the common usbhost_enumerate do all of the real work. Note that the
+ * FunctionAddress (USB address) is hardcoded to one.
+ */
+
+ uvdbg("Enumerate the device\n");
+ return usbhost_enumerate(drvr, 1, &priv->class);
+}
+
+/************************************************************************************
+ * 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.
+ * funcaddr - The USB address of the function containing the endpoint that EP0
+ * controls
+ * 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(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
+ uint16_t maxpacketsize)
+{
+ struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
+
+ DEBUGASSERT(drvr && funcaddr < 128 && maxpacketsize < 2048);
+
+ /* We must have exclusive access to EP0 and the control list */
+
+ lpc17_takesem(&priv->exclsem);
+
+ /* Set the EP0 ED control word */
+
+ EDCTRL->hw.ctrl = (uint32_t)funcaddr << ED_CONTROL_FA_SHIFT |
+ (uint32_t)maxpacketsize << ED_CONTROL_MPS_SHIFT;
+
+ if (priv->lowspeed)
+ {
+ EDCTRL->hw.ctrl |= ED_CONTROL_S;
+ }
+
+ /* Set the transfer type to control */
+
+ EDCTRL->xfrtype = USB_EP_ATTR_XFER_CONTROL;
+ lpc17_givesem(&priv->exclsem);
+
+ uvdbg("EP0 CTRL:%08x\n", EDCTRL->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 desciptor.
+ *
+ * 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(FAR struct usbhost_driver_s *drvr,
+ const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep)
+{
+ struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
+ 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));
+ ed->hw.ctrl = (uint32_t)(epdesc->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 */
+
+ 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 (priv->lowspeed)
+ {
+ 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_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;
+
+ case USB_EP_ATTR_XFER_CONTROL:
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ /* Was the ED successfully added? */
+
+ if (ret != OK)
+ {
+ /* 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(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;
+ 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_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;
+
+ case USB_EP_ATTR_XFER_CONTROL:
+ 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 kmalloc.
+ *
+ * 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(FAR struct usbhost_driver_s *drvr,
+ FAR uint8_t **buffer, FAR 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 kfree().
+ *
+ * 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(FAR struct usbhost_driver_s *drvr, FAR 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 kmalloc.
+ *
+ * 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(FAR struct usbhost_driver_s *drvr,
+ FAR uint8_t **buffer, size_t buflen)
+{
+ DEBUGASSERT(drvr && buffer);
+
+#if LPC17_IOBUFFERS > 0
+ if (buflen <= CONFIG_USBHOST_IOBUFSIZE)
+ {
+ FAR 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 kfree().
+ *
+ * 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(FAR struct usbhost_driver_s *drvr, FAR 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:
+ * 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.
+ * 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:
+ * - Only a single class bound to a single device is supported.
+ * - Called from a single thread so no mutual exclusion is required.
+ * - Never called from an interrupt handler.
+ *
+ *******************************************************************************/
+
+static int lpc17_ctrlin(FAR struct usbhost_driver_s *drvr,
+ FAR const struct usb_ctrlreq_s *req,
+ FAR uint8_t *buffer)
+{
+ struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
+ uint16_t len;
+ int ret;
+
+ DEBUGASSERT(drvr && 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]);
+
+ /* We must have exclusive access to EP0 and the control list */
+
+ lpc17_takesem(&priv->exclsem);
+
+ len = lpc17_getle16(req->len);
+ ret = lpc17_ctrltd(priv, GTD_STATUS_DP_SETUP, (uint8_t*)req, USB_SIZEOF_CTRLREQ);
+ if (ret == OK)
+ {
+ if (len)
+ {
+ ret = lpc17_ctrltd(priv, GTD_STATUS_DP_IN, buffer, len);
+ }
+
+ if (ret == OK)
+ {
+ ret = lpc17_ctrltd(priv, GTD_STATUS_DP_OUT, NULL, 0);
+ }
+ }
+
+ lpc17_givesem(&priv->exclsem);
+ return ret;
+}
+
+static int lpc17_ctrlout(FAR struct usbhost_driver_s *drvr,
+ FAR const struct usb_ctrlreq_s *req,
+ FAR const uint8_t *buffer)
+{
+ struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
+ uint16_t len;
+ int ret;
+
+ DEBUGASSERT(drvr && 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]);
+
+ /* We must have exclusive access to EP0 and the control list */
+
+ lpc17_takesem(&priv->exclsem);
+
+ len = lpc17_getle16(req->len);
+ ret = lpc17_ctrltd(priv, GTD_STATUS_DP_SETUP, (uint8_t*)req, USB_SIZEOF_CTRLREQ);
+ if (ret == OK)
+ {
+ if (len)
+ {
+ ret = lpc17_ctrltd(priv, GTD_STATUS_DP_OUT, (uint8_t*)buffer, len);
+ }
+
+ if (ret == OK)
+ {
+ ret = lpc17_ctrltd(priv, GTD_STATUS_DP_IN, NULL, 0);
+ }
+ }
+
+ lpc17_givesem(&priv->exclsem);
+ return ret;
+}
+
+/*******************************************************************************
+ * Name: lpc17_transfer
+ *
+ * Description:
+ * Process a request to handle a transfer descriptor. This method will
+ * enqueue the transfer request and return immediately. 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:
+ * - Only a single class bound to a single device is supported.
+ * - Called from a single thread so no mutual exclusion is required.
+ * - Never called from an interrupt handler.
+ *
+ *******************************************************************************/
+
+static int lpc17_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
+ FAR 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;
+ uint32_t dirpid;
+ uint32_t regval;
+#if LPC17_IOBUFFERS > 0
+ uint8_t *origbuf = NULL;
+#endif
+ bool in;
+ int ret;
+
+ DEBUGASSERT(priv && ed && buffer && buflen > 0);
+
+ in = (ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN;
+ 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);
+
+ /* 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 an IO buffer if the user buffer does not lie in AHB SRAM */
+
+#if LPC17_IOBUFFERS > 0
+ if ((uintptr_t)buffer < LPC17_SRAM_BANK0 ||
+ (uintptr_t)buffer >= (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);
+ ret = -ENOMEM;
+ goto errout;
+ }
+
+ /* Allocate an IO buffer in AHB SRAM */
+
+ origbuf = buffer;
+ buffer = lpc17_allocio();
+ if (!buffer)
+ {
+ uvdbg("IO buffer allocation failed\n");
+ ret = -ENOMEM;
+ goto errout;
+ }
+
+ /* 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 (!in)
+ {
+ memcpy(buffer, origbuf, buflen);
+ }
+ }
+#endif
+
+ /* Set the request for the Writeback Done Head event well BEFORE enabling the
+ * transfer.
+ */
+
+ ret = lpc17_wdhwait(priv, ed);
+ if (ret != OK)
+ {
+ udbg("ERROR: Device disconnected\n");
+ goto errout;
+ }
+
+ /* 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 = 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.
+ */
+
+ regval = lpc17_getreg(LPC17_USBHOST_CMDST);
+ regval |= OHCI_CMDST_BLF;
+ lpc17_putreg(regval, LPC17_USBHOST_CMDST);
+
+ /* Wait for the Writeback Done Head interrupt */
+
+ lpc17_takesem(&ed->wdhsem);
+
+ /* Check the TD completion status bits */
+
+ if (ed->tdstatus == TD_CC_NOERROR)
+ {
+ ret = OK;
+ }
+ else
+ {
+ uvdbg("Bad TD completion status: %d\n", ed->tdstatus);
+ ret = -EIO;
+ }
+ }
+
+errout:
+ /* Make sure that there is no outstanding request on this endpoint */
+
+ ed->wdhwait = false;
+
+ /* Free any temporary IO buffers */
+
+#if LPC17_IOBUFFERS > 0
+ if (buffer && origbuf)
+ {
+ /* 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 (in && ret == OK)
+ {
+ memcpy(origbuf, buffer, buflen);
+ }
+
+ /* Then free the temporary I/O buffer */
+
+ lpc17_freeio(buffer);
+ }
+#endif
+
+ lpc17_givesem(&priv->exclsem);
+ return ret;
+}
+
+/*******************************************************************************
+ * 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.
+ *
+ * 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(FAR struct usbhost_driver_s *drvr)
+{
+ struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
+ priv->class = 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)
+{
+ uint32_t regval;
+
+ /* Set up some default values */
+
+ (void)lpc17_ep0configure(&priv->drvr, 1, 8);
+
+ /* 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;
+
+ /* Set the head of the control list to the EP0 EDCTRL (this would have to
+ * change if we want more than on control EP queued at a time).
+ */
+
+ lpc17_putreg(LPC17_EDCTRL_ADDR, LPC17_USBHOST_CTRLHEADED);
+
+ /* ControlListEnable. This bit is set to enable the processing of the
+ * Control list. Note: once enabled, it remains enabled and we may even
+ * complete list processing before we get the bit set. We really
+ * should never modify the control list while CLE is set.
+ */
+
+ regval = lpc17_getreg(LPC17_USBHOST_CTRL);
+ regval |= OHCI_CTRL_CLE;
+ lpc17_putreg(regval, LPC17_USBHOST_CTRL);
+}
+
+/*******************************************************************************
+ * Public Functions
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Name: 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 intialized. 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_driver_s *usbhost_initialize(int controller)
+{
+ struct lpc17_usbhost_s *priv = &g_usbhost;
+ 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 */
+
+ sem_init(&priv->rhssem, 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 = irqsave();
+ regval = lpc17_getreg(LPC17_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCUSB;
+ lpc17_putreg(regval, LPC17_SYSCON_PCONP);
+ irqrestore(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 ED 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
+
+ /* 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 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 = irqsave();
+ regval = lpc17_getreg(LPC17_SYSCON_USBINTST);
+ regval |= SYSCON_USBINTST_ENINTS;
+ lpc17_putreg(regval, LPC17_SYSCON_USBINTST);
+ irqrestore(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 &priv->drvr;
+}
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_vectors.S b/nuttx/arch/arm/src/lpc17xx/lpc17_vectors.S
new file mode 100644
index 000000000..cdb4bef66
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_vectors.S
@@ -0,0 +1,394 @@
+/************************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_vectors.S
+ * arch/arm/src/chip/lpc17_vectors.S
+ *
+ * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <arch/irq.h>
+
+/************************************************************************************************
+ * Preprocessor Definitions
+ ************************************************************************************************/
+
+/* 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)
+#define HEAP_BASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE)
+
+/* The Cortex-M3 return from interrupt is unusual. We provide the following special
+ * address to the BX instruction. The particular value also forces a return to
+ * thread mode and covers state from the main stack point, the MSP (vs. the MSP).
+ */
+
+#define EXC_RETURN 0xfffffff9
+
+/************************************************************************************************
+ * Global Symbols
+ ************************************************************************************************/
+
+ .globl __start
+
+ .syntax unified
+ .thumb
+ .file "lpc17_vectors.S"
+
+/************************************************************************************************
+ * 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 lpc17_common
+ .endm
+
+/************************************************************************************************
+ * Vectors
+ ************************************************************************************************/
+
+ .section .vectors, "ax"
+ .code 16
+ .align 2
+ .globl lpc17_vectors
+ .type lpc17_vectors, function
+
+lpc17_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 */
+
+ .word lpc17_wdt /* Vector 16+0: Watchdog timer */
+ .word lpc17_tmr0 /* Vector 16+1: Timer 0 */
+ .word lpc17_tmr1 /* Vector 16+2: Timer 1 */
+ .word lpc17_tmr2 /* Vector 16+3: Timer 2 */
+ .word lpc17_tmr3 /* Vector 16+4: Timer 3 */
+ .word lpc17_uart0 /* Vector 16+5: UART 0 */
+ .word lpc17_uart1 /* Vector 16+6: UART 1 */
+ .word lpc17_uart2 /* Vector 16+7: UART 2 */
+ .word lpc17_uart3 /* Vector 16+8: UART 3 */
+ .word lpc17_pwm1 /* Vector 16+9: PWM */
+ .word lpc17_i2c0 /* Vector 16+10: I2C 0 */
+ .word lpc17_i2c1 /* Vector 16+11: I2C 1 */
+ .word lpc17_i2c2 /* Vector 16+12: I2C 2 */
+ .word lpc17_spif /* Vector 16+13: SPI */
+ .word lpc17_ssp0 /* Vector 16+14: SSP 0 */
+ .word lpc17_ssp1 /* Vector 16+15: SSP 1 */
+ .word lpc17_pll0 /* Vector 16+16: PLL 0 */
+ .word lpc17_rtc /* Vector 16+17: Real time clock */
+ .word lpc17_eint0 /* Vector 16+18: External interrupt 0 */
+ .word lpc17_eint1 /* Vector 16+19: External interrupt 1 */
+ .word lpc17_eint2 /* Vector 16+20: External interrupt 2 */
+ .word lpc17_eint3 /* Vector 16+21: External interrupt 3 */
+ .word lpc17_adc /* Vector 16+22: A/D Converter */
+ .word lpc17_bod /* Vector 16+23: Brown Out detect */
+ .word lpc17_usb /* Vector 16+24: USB */
+ .word lpc17_can /* Vector 16+25: CAN */
+ .word lpc17_gpdma /* Vector 16+26: GPDMA */
+ .word lpc17_i2s /* Vector 16+27: I2S */
+ .word lpc17_eth /* Vector 16+28: Ethernet */
+ .word lpc17_ritint /* Vector 16+29: Repetitive Interrupt Timer */
+ .word lpc17_mcpwm /* Vector 16+30: Motor Control PWM */
+ .word lpc17_qei /* Vector 16+31: Quadrature Encoder */
+ .word lpc17_pll1 /* Vector 16+32: PLL 1 */
+ .word lpc17_usbact /* Vector 16+33: USB Activity Interrupt */
+ .word lpc17_canact /* Vector 16+34: CAN Activity Interrupt */
+ .size lpc17_vectors, .-lpc17_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 */
+
+ HANDLER lpc17_wdt, LPC17_IRQ_WDT /* Vector 16+0: Watchdog timer */
+ HANDLER lpc17_tmr0, LPC17_IRQ_TMR0 /* Vector 16+1: Timer 0 */
+ HANDLER lpc17_tmr1, LPC17_IRQ_TMR1 /* Vector 16+2: Timer 1 */
+ HANDLER lpc17_tmr2, LPC17_IRQ_TMR2 /* Vector 16+3: Timer 2 */
+ HANDLER lpc17_tmr3, LPC17_IRQ_TMR3 /* Vector 16+4: Timer 3 */
+ HANDLER lpc17_uart0, LPC17_IRQ_UART0 /* Vector 16+5: UART 0 */
+ HANDLER lpc17_uart1, LPC17_IRQ_UART1 /* Vector 16+6: UART 1 */
+ HANDLER lpc17_uart2, LPC17_IRQ_UART2 /* Vector 16+7: UART 2 */
+ HANDLER lpc17_uart3, LPC17_IRQ_UART3 /* Vector 16+8: UART 3 */
+ HANDLER lpc17_pwm1, LPC17_IRQ_PWM1 /* Vector 16+9: PWM 1 */
+ HANDLER lpc17_i2c0, LPC17_IRQ_I2C0 /* Vector 16+10: I2C 0 */
+ HANDLER lpc17_i2c1, LPC17_IRQ_I2C1 /* Vector 16+11: I2C 1 */
+ HANDLER lpc17_i2c2, LPC17_IRQ_I2C2 /* Vector 16+12: I2C 2 */
+ HANDLER lpc17_spif, LPC17_IRQ_SPIF /* Vector 16+13: SPI */
+ HANDLER lpc17_ssp0, LPC17_IRQ_SSP0 /* Vector 16+14: SSP 0 */
+ HANDLER lpc17_ssp1, LPC17_IRQ_SSP1 /* Vector 16+15: SSP 1 */
+ HANDLER lpc17_pll0, LPC17_IRQ_PLL0 /* Vector 16+16: PLL 0 */
+ HANDLER lpc17_rtc, LPC17_IRQ_RTC /* Vector 16+17: Real time clock */
+ HANDLER lpc17_eint0, LPC17_IRQ_EINT0 /* Vector 16+18: External interrupt 0 */
+ HANDLER lpc17_eint1, LPC17_IRQ_EINT1 /* Vector 16+19: External interrupt 1 */
+ HANDLER lpc17_eint2, LPC17_IRQ_EINT2 /* Vector 16+20: External interrupt 2 */
+ HANDLER lpc17_eint3, LPC17_IRQ_EINT3 /* Vector 16+21: External interrupt 3 */
+ HANDLER lpc17_adc, LPC17_IRQ_ADC /* Vector 16+22: A/D Converter */
+ HANDLER lpc17_bod, LPC17_IRQ_BOD /* Vector 16+23: Brown Out detect */
+ HANDLER lpc17_usb, LPC17_IRQ_USB /* Vector 16+24: USB */
+ HANDLER lpc17_can, LPC17_IRQ_CAN /* Vector 16+25: CAN */
+ HANDLER lpc17_gpdma, LPC17_IRQ_GPDMA /* Vector 16+26: GPDMA */
+ HANDLER lpc17_i2s, LPC17_IRQ_I2S /* Vector 16+27: I2S */
+ HANDLER lpc17_eth, LPC17_IRQ_ETH /* Vector 16+28: Ethernet */
+ HANDLER lpc17_ritint, LPC17_IRQ_RITINT /* Vector 16+29: Repetitive Interrupt Timer */
+ HANDLER lpc17_mcpwm, LPC17_IRQ_MCPWM /* Vector 16+30: Motor Control PWM */
+ HANDLER lpc17_qei, LPC17_IRQ_QEI /* Vector 16+31: Quadrature Encoder */
+ HANDLER lpc17_pll1, LPC17_IRQ_PLL1 /* Vector 16+32: PLL 1 */
+ HANDLER lpc17_usbact, LPC17_IRQ_USBACT /* Vector 16+33: USB Activity Interrupt */
+ HANDLER lpc17_canact, LPC17_IRQ_CANACT /* Vector 16+34: CAN Activity Interrupt */
+
+/* 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
+ */
+
+lpc17_common:
+
+ /* Complete the context save */
+
+#ifdef CONFIG_NUTTX_KERNEL
+ /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
+ * (handler mode) if the state is on the MSP. It can only be on the PSP if
+ * EXC_RETURN is 0xfffffffd (unprivileged thread)
+ */
+
+ adds r2, r14, #3 /* If R14=0xfffffffd, then r2 == 0 */
+ ite ne /* Next two instructions are condition */
+ mrsne r1, msp /* R1=The main stack pointer */
+ mrseq r1, psp /* R1=The process stack pointer */
+#else
+ mrs r1, msp /* R1=The main stack pointer */
+#endif
+
+ mov r2, r1 /* R2=Copy of the main/process stack pointer */
+ add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
+ mrs r3, primask /* R3=Current PRIMASK setting */
+#ifdef CONFIG_NUTTX_KERNEL
+ stmdb r1!, {r2-r11,r14} /* Save the remaining registers plus the SP value */
+#else
+ stmdb r1!, {r2-r11} /* Save the remaining registers plus the SP value */
+#endif
+
+ /* 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 re-use the main stack for interrupt level processing.
+ */
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ ldr sp, =g_intstackbase
+ str r1, [sp, #-4]! /* Save the MSP on the interrupt stack */
+ bl up_doirq /* R0=IRQ, R1=register save (msp) */
+ ldr r1, [sp, #+4]! /* Recover R1=main stack pointer */
+#else
+ mov sp, r1 /* We are using the main stack pointer */
+ bl up_doirq /* R0=IRQ, R1=register save (msp) */
+ mov r1, sp /* 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 1f /* 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, are 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_NUTTX_KERNEL
+ 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 2f /* Re-join common logic */
+
+ /* We are returning with no context switch. We simply need to "unwind"
+ * the same stack frame that we created
+ */
+1:
+#ifdef CONFIG_NUTTX_KERNEL
+ ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
+#else
+ ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */
+#endif
+2:
+#ifdef CONFIG_NUTTX_KERNEL
+ /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
+ * (handler mode) if the state is on the MSP. It can only be on the PSP if
+ * EXC_RETURN is 0xfffffffd (unprivileged thread)
+ */
+
+ adds r0, r14, #3 /* If R14=0xfffffffd, then r0 == 0 */
+ ite ne /* Next two instructions are condition */
+ msrne msp, r1 /* R1=The main stack pointer */
+ msreq psp, r1 /* R1=The process stack pointer */
+#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 /* Load the special value */
+#endif
+
+ /* Restore the interrupt state */
+
+ msr primask, r3 /* Restore interrupts */
+
+ /* 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: up_interruptstack/g_intstackbase
+ *
+ * Description:
+ * Shouldn't happen
+ *
+ ************************************************************************************************/
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ .bss
+ .global g_intstackbase
+ .align 4
+up_interruptstack:
+ .skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
+g_intstackbase:
+ .size up_interruptstack, .-up_interruptstack
+#endif
+
+/************************************************************************************************
+ * .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_heapbase below.
+ */
+
+ .globl g_heapbase
+ .type g_heapbase, object
+g_heapbase:
+ .word HEAP_BASE
+ .size g_heapbase, .-g_heapbase
+
+ .end
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_wdt.h b/nuttx/arch/arm/src/lpc17xx/lpc17_wdt.h
new file mode 100644
index 000000000..bd7790a6e
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_wdt.h
@@ -0,0 +1,108 @@
+/************************************************************************************
+ * arch/arm/src/lpc17xx/lpc17_wdt.h
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "lpc17_memorymap.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Register offsets *****************************************************************/
+
+#define LPC17_WDT_WDMOD_OFFSET 0x0000 /* Watchdog mode register */
+#define LPC17_WDT_WDTC_OFFSET 0x0004 /* Watchdog timer constant register */
+#define LPC17_WDT_WDFEED_OFFSET 0x0008 /* Watchdog feed sequence register */
+#define LPC17_WDT_WDTV_OFFSET 0x000c /* Watchdog timer value register */
+#define LPC17_WDT_WDCLKSEL_OFFSET 0x0010 /* Watchdog clock source selection register */
+
+/* Register addresses ***************************************************************/
+
+#define LPC17_WDT_WDMOD (LPC17_WDT_BASE+LPC17_WDT_WDMOD_OFFSET)
+#define LPC17_WDT_WDTC (LPC17_WDT_BASE+LPC17_WDT_WDTC_OFFSET)
+#define LPC17_WDT_WDFEED (LPC17_WDT_BASE+LPC17_WDT_WDFEED_OFFSET)
+#define LPC17_WDT_WDTV (LPC17_WDT_BASE+LPC17_WDT_WDTV_OFFSET)
+#define LPC17_WDT_WDCLKSEL (LPC17_WDT_BASE+LPC17_WDT_WDCLKSEL_OFFSET)
+
+/* Register bit definitions *********************************************************/
+
+/* Watchdog mode register */
+
+#define WDT_WDMOD_WDEN (1 << 0) /* Bit 0: Watchdog enable */
+#define WDT_WDMOD_WDRESET (1 << 1) /* Bit 1: Watchdog reset enable */
+#define WDT_WDMOD_WDTOF (1 << 2) /* Bit 2: Watchdog time-out */
+#define WDT_WDMOD_WDINT (1 << 3) /* Bit 3: Watchdog interrupt */
+ /* Bits 14-31: Reserved */
+
+/* Watchdog timer constant register (Bits 0-31: Watchdog time-out interval) */
+
+/* Watchdog feed sequence register */
+
+#define WDT_WDFEED_MASK (0xff) /* Bits 0-7: Feed value should be 0xaa followed by 0x55 */
+ /* Bits 14-31: Reserved */
+/* Watchdog timer value register (Bits 0-31: Counter timer value) */
+
+/* Watchdog clock source selection register */
+
+#define WDT_WDCLKSEL_WDSEL_SHIFT (0) /* Bits 0-1: Clock source for the Watchdog timer */
+#define WDT_WDCLKSEL_WDSEL_MASK (3 << WDT_WDCLKSEL_WDSEL_SHIFT)
+# define WDT_WDCLKSEL_WDSEL_INTRC (0 << WDT_WDCLKSEL_WDSEL_SHIFT) /* Internal RC osc */
+# define WDT_WDCLKSEL_WDSEL_APB (1 << WDT_WDCLKSEL_WDSEL_SHIFT) /* APB peripheral clock (watchdog pclk) */
+# define WDT_WDCLKSEL_WDSEL_RTC (2 << WDT_WDCLKSEL_WDSEL_SHIFT) /* RTC oscillator (rtc_clk) */
+ /* Bits 2-30: Reserved */
+#define WDT_WDCLKSEL_WDLOCK (1 << 31) /* Bit 31: Lock WDT register bits if set */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_WDT_H */
diff --git a/nuttx/arch/arm/src/lpc214x/Kconfig b/nuttx/arch/arm/src/lpc214x/Kconfig
new file mode 100644
index 000000000..a26483ed9
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc214x/Kconfig
@@ -0,0 +1,6 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+comment "LPC214x Configuration Options"
diff --git a/nuttx/arch/arm/src/lpc214x/Make.defs b/nuttx/arch/arm/src/lpc214x/Make.defs
new file mode 100644
index 000000000..41dc0911c
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc214x/Make.defs
@@ -0,0 +1,57 @@
+##############################################################################
+# lpc214x/Make.defs
+#
+# Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (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_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
+ up_createstack.c up_dataabort.c up_mdelay.c up_udelay.c \
+ up_exit.c up_idle.c up_initialize.c up_initialstate.c \
+ up_interruptcontext.c up_prefetchabort.c up_releasepending.c \
+ up_releasestack.c up_reprioritizertr.c up_syscall.c up_unblocktask.c \
+ up_undefinedinsn.c up_usestack.c up_lowputs.c
+
+ifneq ($(CONFIG_DISABLE_SIGNALS),y)
+CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c
+endif
+
+CHIP_ASRCS = lpc214x_lowputc.S
+CHIP_CSRCS = lpc214x_decodeirq.c lpc214x_irq.c lpc214x_timerisr.c \
+ lpc214x_serial.c
+
+ifeq ($(CONFIG_USBDEV),y)
+CHIP_CSRCS += lpc214x_usbdev.c
+endif
+
diff --git a/nuttx/arch/arm/src/lpc214x/README.txt b/nuttx/arch/arm/src/lpc214x/README.txt
new file mode 100644
index 000000000..9cfc99593
--- /dev/null
+++ b/nuttx/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/nuttx/arch/arm/src/lpc214x/chip.h b/nuttx/arch/arm/src/lpc214x/chip.h
new file mode 100644
index 000000000..d469aae8b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * 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
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Global Function Prototypes
+ ****************************************************************************************************/
+
+#endif /* __LPC214X_CHIP_H */
diff --git a/nuttx/arch/arm/src/lpc214x/lpc214x_apb.h b/nuttx/arch/arm/src/lpc214x/lpc214x_apb.h
new file mode 100644
index 000000000..2d41ab106
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc214x/lpc214x_decodeirq.c b/nuttx/arch/arm/src/lpc214x/lpc214x_decodeirq.c
new file mode 100644
index 000000000..652fe4d61
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc214x/lpc214x_decodeirq.c
@@ -0,0 +1,177 @@
+/********************************************************************************
+ * arch/arm/src/lpc214x/lpc214x_decodeirq.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <assert.h>
+#include <debug.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+#include "lpc214x_vic.h"
+
+/********************************************************************************
+ * 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
+ lib_lowprintf("Unexpected IRQ\n");
+ current_regs = regs;
+ PANIC(OSERR_ERREXCEPTION);
+#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/nuttx/arch/arm/src/lpc214x/lpc214x_head.S b/nuttx/arch/arm/src/lpc214x/lpc214x_head.S
new file mode 100644
index 000000000..678481154
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <arch/board/board.h>
+
+#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"
+
+/*****************************************************************************
+ * 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 up_ledinit
+#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_heapbase
+ * 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_heapbase and is
+ * exported from here only because of its coupling to LCO
+ * above.
+ */
+
+ .data
+ .align 4
+ .globl g_heapbase
+ .type g_heapbase, object
+g_heapbase:
+ .long _ebss+CONFIG_IDLETHREAD_STACKSIZE
+ .size g_heapbase, .-g_heapbase
+
+ .end
+
diff --git a/nuttx/arch/arm/src/lpc214x/lpc214x_i2c.h b/nuttx/arch/arm/src/lpc214x/lpc214x_i2c.h
new file mode 100644
index 000000000..a66399968
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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"
+
+/************************************************************************************
+ * 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 interrrupt 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/nuttx/arch/arm/src/lpc214x/lpc214x_irq.c b/nuttx/arch/arm/src/lpc214x/lpc214x_irq.c
new file mode 100644
index 000000000..cb0f6e12f
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc214x/lpc214x_irq.c
@@ -0,0 +1,224 @@
+/****************************************************************************
+ * arch/arm/src/lpc214x/lpc214x_irq.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+#include <nuttx/irq.h>
+
+#include "arm.h"
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+#include "lpc214x_vic.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/****************************************************************************
+ * 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
+ irqrestore(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 = irqsave();
+
+ /* 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);
+ irqrestore(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 = irqsave();
+
+ /* 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);
+ irqrestore(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/nuttx/arch/arm/src/lpc214x/lpc214x_lowputc.S b/nuttx/arch/arm/src/lpc214x/lpc214x_lowputc.S
new file mode 100644
index 000000000..b53e7aa78
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "lpc214x_pinsel.h"
+#include "lpc214x_uart.h"
+
+/**************************************************************************
+ * Private 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
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * 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/nuttx/arch/arm/src/lpc214x/lpc214x_pinsel.h b/nuttx/arch/arm/src/lpc214x/lpc214x_pinsel.h
new file mode 100644
index 000000000..b34eb86b6
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc214x/lpc214x_pll.h b/nuttx/arch/arm/src/lpc214x/lpc214x_pll.h
new file mode 100644
index 000000000..bea923e43
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <chip.h>
+
+/****************************************************************************************************
+ * 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
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Global Function Prototypes
+ ****************************************************************************************************/
+
+#endif /* _ARCH_ARM_SRC_LPC214X_PLL_H */
diff --git a/nuttx/arch/arm/src/lpc214x/lpc214x_power.h b/nuttx/arch/arm/src/lpc214x/lpc214x_power.h
new file mode 100644
index 000000000..7eb253160
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc214x/lpc214x_serial.c b/nuttx/arch/arm/src/lpc214x/lpc214x_serial.c
new file mode 100644
index 000000000..691adfa75
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc214x/lpc214x_serial.c
@@ -0,0 +1,842 @@
+/****************************************************************************
+ * arch/arm/src/lpc214x/lpc214x_serial.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <arch/serial.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+#include "lpc214x_pinsel.h"
+#include "lpc214x_uart.h"
+
+#ifdef USE_SERIALDRIVER
+
+/****************************************************************************
+ * 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 Variables
+ ****************************************************************************/
+
+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,
+ .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_LPC214X_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 interrrupt 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(OSERR_INTERNAL);
+ }
+ 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)
+ {
+ 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;
+
+ case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
+ {
+ irqstate_t flags = irqsave();
+ up_enablebreaks(priv, true);
+ irqrestore(flags);
+ }
+ break;
+
+ case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
+ {
+ irqstate_t flags;
+ flags = irqsave();
+ up_enablebreaks(priv, false);
+ irqrestore(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/nuttx/arch/arm/src/lpc214x/lpc214x_spi.h b/nuttx/arch/arm/src/lpc214x/lpc214x_spi.h
new file mode 100644
index 000000000..ce6a03db9
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc214x/lpc214x_spi.h
@@ -0,0 +1,166 @@
+/************************************************************************************
+ * arch/arm/src/lpc214x/lpc214x_spi.h
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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"
+
+/************************************************************************************
+ * 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
+ ************************************************************************************/
+
+#endif /* _ARCH_ARM_SRC_LPC214X_SPI_H */
diff --git a/nuttx/arch/arm/src/lpc214x/lpc214x_timer.h b/nuttx/arch/arm/src/lpc214x/lpc214x_timer.h
new file mode 100644
index 000000000..6c239f10c
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc214x/lpc214x_timerisr.c b/nuttx/arch/arm/src/lpc214x/lpc214x_timerisr.c
new file mode 100644
index 000000000..99d1d118f
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc214x/lpc214x_timerisr.c
@@ -0,0 +1,170 @@
+/****************************************************************************
+ * arch/arm/src/lpc214x/lpc214x_timerisr.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "clock_internal.h"
+#include "up_internal.h"
+
+#include "lpc214x_timer.h"
+#include "lpc214x_vic.h"
+
+/****************************************************************************
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize
+ * the timer interrupt.
+ *
+ ****************************************************************************/
+
+void up_timerinit(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
+ * See arch/board.h and sched/os_internal.h
+ */
+
+ 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/nuttx/arch/arm/src/lpc214x/lpc214x_uart.h b/nuttx/arch/arm/src/lpc214x/lpc214x_uart.h
new file mode 100644
index 000000000..fd634a816
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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 <arch/board/board.h> /* For clock settings */
+
+/************************************************************************************
+ * 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * Global Function Prototypes
+ ************************************************************************************/
+
+#endif /* __LPC214X_UART_H */
diff --git a/nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c b/nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c
new file mode 100644
index 000000000..78a5fe1c3
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c
@@ -0,0 +1,3375 @@
+/*******************************************************************************
+ * arch/arm/src/lpc214x/lpc214x_usbdev.c
+ *
+ * Copyright (C) 2008-2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/usb/usb.h>
+#include <nuttx/usb/usbdev.h>
+#include <nuttx/usb/usbdev_trace.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "lpc214x_usbdev.h"
+#include "lpc214x_pll.h"
+#include "lpc214x_power.h"
+
+/*******************************************************************************
+ * 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 desciptors 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 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: 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 = irqsave();
+ 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 */
+
+ irqrestore(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 = irqsave();
+ privreq = lpc214x_rqdequeue(privep);
+ irqrestore(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;
+ ret = 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
+
+#if 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);
+ }
+#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);
+ }
+
+ /* 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 tranfer 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 = irqsave();
+ 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);
+
+ irqrestore(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 *)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);
+
+ 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 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);
+ 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 = irqsave();
+
+ /* 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;
+ }
+ }
+
+ irqrestore(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;
+ FAR struct lpc214x_usbdev_s *priv;
+ irqstate_t flags;
+
+#ifdef CONFIG_DEBUG
+ if (!ep || !req)
+ {
+ usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_INVALIDPARMS), 0);
+ return -EINVAL;
+ }
+#endif
+ usbtrace(TRACE_EPCANCEL, privep->epphy);
+ priv = privep->dev;
+
+ flags = irqsave();
+ lpc214x_cancelrequests(privep);
+ irqrestore(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 = irqsave();
+ 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);
+ }
+ irqrestore(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 = irqsave();
+ 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));
+ irqrestore(flags);
+
+ /* And return the pointer to the standard endpoint structure */
+
+ return &priv->eplist[epndx].ep;
+ }
+ }
+ /* Shouldn't get here */
+ }
+ irqrestore(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 = irqsave();
+ priv->epavail |= (1 << privep->epphy);
+ irqrestore(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 = irqsave();
+ if (DEVSTATUS_CONNECT(g_usbdev.devstatus))
+ {
+ arg |= USBDEV_DEVSTATUS_CONNECT;
+ }
+
+ lpc214x_usbcmd(CMD_USB_DEV_SETSTATUS, arg);
+ irqrestore(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 = irqsave();
+ 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);
+ irqrestore(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/nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.h b/nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.h
new file mode 100644
index 000000000..814622ef5
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/*******************************************************************************
+ * 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/nuttx/arch/arm/src/lpc214x/lpc214x_vic.h b/nuttx/arch/arm/src/lpc214x/lpc214x_vic.h
new file mode 100644
index 000000000..520c6037a
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc2378/Kconfig b/nuttx/arch/arm/src/lpc2378/Kconfig
new file mode 100644
index 000000000..89a515d6a
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc2378/Kconfig
@@ -0,0 +1,6 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+comment "LPC2378 Configuration Options"
diff --git a/nuttx/arch/arm/src/lpc2378/Make.defs b/nuttx/arch/arm/src/lpc2378/Make.defs
new file mode 100644
index 000000000..9126fa2a1
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc2378/Make.defs
@@ -0,0 +1,63 @@
+##############################################################################
+# 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 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (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_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
+ up_createstack.c up_dataabort.c up_mdelay.c up_udelay.c \
+ up_exit.c up_idle.c up_initialize.c up_initialstate.c \
+ up_interruptcontext.c up_prefetchabort.c up_releasepending.c \
+ up_releasestack.c up_reprioritizertr.c up_syscall.c up_unblocktask.c \
+ up_undefinedinsn.c up_usestack.c up_lowputs.c
+
+ifneq ($(CONFIG_DISABLE_SIGNALS),y)
+CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c
+endif
+
+CHIP_ASRCS = lpc23xx_lowputc.S
+CHIP_CSRCS = lpc23xx_pllsetup.c lpc23xx_decodeirq.c lpc23xx_irq.c lpc23xx_timerisr.c \
+ lpc23xx_serial.c lpc23xx_io.c
+
+
+ifeq ($(CONFIG_USBDEV),y)
+#CHIP_CSRCS += lpc23xx_usbdev.c
+endif
+
diff --git a/nuttx/arch/arm/src/lpc2378/chip.h b/nuttx/arch/arm/src/lpc2378/chip.h
new file mode 100644
index 000000000..6113f21e8
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc2378/chip.h
@@ -0,0 +1,959 @@
+/****************************************************************************************************
+ * 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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <sys/types.h>
+
+/****************************************************************************************************
+ * 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 registger 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) Controller */
+//~ 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 0x4034
+/* 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 Indentification 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 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
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Global Function Prototypes
+ ****************************************************************************************************/
+
+#endif /* _ARCH_ARM_SRC_LPC2378_CHIP_H */
diff --git a/nuttx/arch/arm/src/lpc2378/internal.h b/nuttx/arch/arm/src/lpc2378/internal.h
new file mode 100644
index 000000000..5a0e63b62
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc2378/internal.h
@@ -0,0 +1,70 @@
+/****************************************************************************************************
+ * 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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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
+
+/****************************************************************************************************
+ * Global Function Prototypes
+ ****************************************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_ARCH_LEDS
+extern void up_statledoff(void);
+extern void up_statledon(void);
+#endif
+
+#endif
+
+#endif /* _ARCH_ARM_SRC_LPC2378_INTERNAL_H */
diff --git a/nuttx/arch/arm/src/lpc2378/lpc23xx_decodeirq.c b/nuttx/arch/arm/src/lpc2378/lpc23xx_decodeirq.c
new file mode 100644
index 000000000..a55ed339d
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc2378/lpc23xx_decodeirq.c
@@ -0,0 +1,176 @@
+/********************************************************************************
+ * 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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "os_internal.h"
+#include "internal.h"
+#include "lpc23xx_vic.h"
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Types
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Funstions
+ ********************************************************************************/
+
+/********************************************************************************
+ * 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
+ lib_lowprintf("Unexpected IRQ\n");
+ current_regs = regs;
+ PANIC(OSERR_ERREXCEPTION);
+#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;
+
+ /* Mask and acknowledge the interrupt */
+
+ up_maskack_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);
+
+ /* Mask and acknowledge the interrupt */
+
+ up_maskack_irq(irq);
+
+ /* Valid Interrupt */
+
+ if (vector != NULL)
+ (vector) (regs);
+}
+#endif
diff --git a/nuttx/arch/arm/src/lpc2378/lpc23xx_gpio.h b/nuttx/arch/arm/src/lpc2378/lpc23xx_gpio.h
new file mode 100644
index 000000000..f18bd685a
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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"
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc2378/lpc23xx_head.S b/nuttx/arch/arm/src/lpc2378/lpc23xx_head.S
new file mode 100755
index 000000000..a4cab8f05
--- /dev/null
+++ b/nuttx/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 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <arch/board/board.h>
+
+#include "arm.h"
+#include "internal.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_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 up_ledinit
+#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_heapbase
+ * 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_heapbase and is
+ * exported from here only because of its coupling to LCO
+ * above.
+ */
+
+ .data
+ .align 4
+ .globl g_heapbase
+ .type g_heapbase, object
+g_heapbase:
+ .long _ebss+CONFIG_IDLETHREAD_STACKSIZE
+ .size g_heapbase, .-g_heapbase
+
+ .end
+
diff --git a/nuttx/arch/arm/src/lpc2378/lpc23xx_io.c b/nuttx/arch/arm/src/lpc2378/lpc23xx_io.c
new file mode 100644
index 000000000..6f0474f09
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc2378/lpc23xx_io.c
@@ -0,0 +1,101 @@
+/***********************************************************************
+ * 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 <sys/types.h>
+#include "lpc23xx_scb.h"
+#include "lpc23xx_pinsel.h"
+#include "lpc23xx_uart.h"
+#include "lpc23xx_gpio.h"
+
+/***********************************************************************
+ * 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);
+
+/*
+ regval = scb_getreg(SCB_PCONP_OFFSET) & ~(PCSDC | PCUART1 | PCI2C0 | PCSSP1 | PCEMC | );
+ scb_getreg(regval, SCB_PCONP_OFFSET );
+*/
+
+ /* 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/nuttx/arch/arm/src/lpc2378/lpc23xx_irq.c b/nuttx/arch/arm/src/lpc2378/lpc23xx_irq.c
new file mode 100644
index 000000000..96e94c454
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc2378/lpc23xx_irq.c
@@ -0,0 +1,302 @@
+/****************************************************************************
+ * 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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <errno.h>
+#include <debug.h>
+#include <nuttx/irq.h>
+
+#include "arm.h"
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.h"
+
+#include "internal.h"
+#include "lpc23xx_vic.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/****************************************************************************
+ * 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
+ irqrestore(SVC_MODE | PSR_F_BIT);
+#endif
+}
+
+/***********************************************************************
+ * Name: up_enable_irq_protect
+ * VIC registers can be accessed in User or privileged mode
+ ***********************************************************************/
+
+static void up_enable_irq_protect(void)
+{
+ // ~ uint32_t reg32 = vic_getreg(VIC_PROTECTION_OFFSET);
+ // ~ reg32 &= ~(0xFFFFFFFF);
+ vic_putreg(0x01, VIC_PROTECTION_OFFSET);
+}
+
+/***********************************************************************
+ * Name: up_disable_irq_protect
+ * VIC registers can only be accessed in privileged mode
+ ***********************************************************************/
+
+static void up_disable_irq_protect(void)
+{
+ vic_putreg(0, VIC_PROTECTION_OFFSET);
+}
+
+/***********************************************************************
+ * 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 = irqsave();
+
+ /* 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);
+ irqrestore(flags);
+ }
+}
+
+/****************************************************************************
+ * Name: up_maskack_irq
+ *
+ * Description:
+ * Mask the IRQ and acknowledge it
+ *
+ ****************************************************************************/
+
+void up_maskack_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
+ ****************************************************************************/
+
+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;
+}
+
+/****************************************************************************
+ * 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 = irqsave();
+
+ /* Save the vector address */
+
+ vic_putreg((uint32_t) handler, VIC_VECTADDR0_OFFSET + offset);
+
+ /* Set the interrupt priority */
+
+ up_prioritize_irq(irq, vector);
+
+ /* Enable the vectored interrupt */
+
+ uint32_t val = vic_getreg(VIC_INTENABLE_OFFSET);
+ vic_putreg(val | (1 << irq), VIC_INTENABLE_OFFSET);
+
+ irqrestore(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/nuttx/arch/arm/src/lpc2378/lpc23xx_lowputc.S b/nuttx/arch/arm/src/lpc2378/lpc23xx_lowputc.S
new file mode 100755
index 000000000..cc332a961
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include "up_internal.h"
+#include "up_arch.h"
+#include "lpc23xx_pinsel.h"
+#include "lpc23xx_scb.h"
+#include "lpc23xx_uart.h"
+
+/**************************************************************************
+ * Private 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
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * 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/nuttx/arch/arm/src/lpc2378/lpc23xx_pinsel.h b/nuttx/arch/arm/src/lpc2378/lpc23xx_pinsel.h
new file mode 100644
index 000000000..10a97c7f1
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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"
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc2378/lpc23xx_pllsetup.c b/nuttx/arch/arm/src/lpc2378/lpc23xx_pllsetup.c
new file mode 100644
index 000000000..b11658f99
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc2378/lpc23xx_pllsetup.c
@@ -0,0 +1,242 @@
+/****************************************************************************
+ * 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 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_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.
+ */
+
+/***********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <nuttx/config.h>
+#include <arch/board/board.h>
+#include <sys/types.h>
+
+#include "arm.h"
+#include "up_arch.h"
+#include "internal.h"
+#include "lpc23xx_pinsel.h"
+#include "lpc23xx_scb.h"
+
+extern void IO_Init(void);
+
+/***********************************************************************
+ * 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_PLL_CLKSRC
+# if ( (CONFIG_PLL_CLKSRC < 0) || (CONFIG_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_MAM_SETUP
+# ifndef CONFIG_MAMCR_VALUE /* Can be selected from config file */
+# define CONFIG_MAMCR_VALUE (MAMCR_PART)
+# endif
+
+# ifndef CONFIG_MAMTIM_VALUE /* Can be selected from config file */
+# define CONFIG_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_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_MAMTIM_VALUE;
+ SCB_MAMCR = CONFIG_MAMCR_VALUE;
+
+ /* Enable FastIO on P0:P1 */
+ SCB_SCS |= 0x01;
+
+ IO_Init();
+
+ return;
+}
diff --git a/nuttx/arch/arm/src/lpc2378/lpc23xx_scb.h b/nuttx/arch/arm/src/lpc2378/lpc23xx_scb.h
new file mode 100644
index 000000000..d876ef6ec
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc2378/lpc23xx_scb.h
@@ -0,0 +1,131 @@
+/****************************************************************************************************
+ * 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 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <chip.h>
+#include "lpc23xx_vic.h"
+
+/****************************************************************************************************
+ * 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
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Global Function Prototypes
+ ****************************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LPC2378_LPC23XX_SCB_H */
diff --git a/nuttx/arch/arm/src/lpc2378/lpc23xx_serial.c b/nuttx/arch/arm/src/lpc2378/lpc23xx_serial.c
new file mode 100644
index 000000000..4f20cc7fd
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * This file is part of the NuttX RTOS and based on the lpc2148 port:
+ *
+ * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <arch/serial.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.h"
+
+#include "internal.h"
+#include "lpc23xx_scb.h"
+#include "lpc23xx_pinsel.h"
+#include "lpc23xx_uart.h"
+#include "lpc23xx_vic.h"
+
+#ifdef USE_SERIALDRIVER
+
+/****************************************************************************
+ * 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 Variables
+ ****************************************************************************/
+
+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,
+ .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_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_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_LPC214X_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 interrrupt 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);
+
+ /* Set the uart interrupt priority (the default value is one) */
+ if (priv->uartbase == UART0_BASE_ADDR)
+ {
+ up_prioritize_irq(priv->irq, PRIORITY_LOWEST);
+ }
+ else if (priv->uartbase == UART2_BASE_ADDR)
+ {
+ up_prioritize_irq(priv->irq, 10);
+ }
+
+ }
+ 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(OSERR_INTERNAL);
+ }
+ 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)
+ {
+ 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;
+
+ case TIOCSBRK: /* BSD compatibility: Turn break on,
+ * unconditionally */
+ {
+ irqstate_t flags = irqsave();
+ up_enablebreaks(priv, true);
+ irqrestore(flags);
+ }
+ break;
+
+ case TIOCCBRK: /* BSD compatibility: Turn break off,
+ * unconditionally */
+ {
+ irqstate_t flags;
+ flags = irqsave();
+ up_enablebreaks(priv, false);
+ irqrestore(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/nuttx/arch/arm/src/lpc2378/lpc23xx_timer.h b/nuttx/arch/arm/src/lpc2378/lpc23xx_timer.h
new file mode 100644
index 000000000..4de1b3fff
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc2378/lpc23xx_timerisr.c b/nuttx/arch/arm/src/lpc2378/lpc23xx_timerisr.c
new file mode 100644
index 000000000..d9e63d6d6
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc2378/lpc23xx_timerisr.c
@@ -0,0 +1,202 @@
+/****************************************************************************
+ * 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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <sys/types.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "clock_internal.h"
+#include "internal.h"
+#include "up_arch.h"
+
+#include "lpc23xx_scb.h"
+#include "lpc23xx_vic.h"
+#include "lpc23xx_timer.h"
+
+/****************************************************************************
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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;
+ up_statledoff();
+ }
+ else
+ up_statledon();
+
+ return 0;
+}
+
+/****************************************************************************
+ * Function: up_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize
+ * the system timer interrupt.
+ *
+ ****************************************************************************/
+
+void up_timerinit(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
+ * sched/os_internal.h
+ */
+
+ 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, PRIORITY_HIGHEST, (vic_vector_t) up_timerisr);
+#else
+ (void)irq_attach(IRQ_SYSTIMER, (xcpt_t) up_timerisr);
+ up_prioritize_irq(IRQ_SYSTIMER, PRIORITY_HIGHEST);
+#endif
+
+ /* And enable the system timer interrupt */
+
+ up_enable_irq(IRQ_SYSTIMER);
+}
diff --git a/nuttx/arch/arm/src/lpc2378/lpc23xx_uart.h b/nuttx/arch/arm/src/lpc2378/lpc23xx_uart.h
new file mode 100644
index 000000000..2c8999bfa
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <arch/board/board.h> /* For clock settings */
+
+/************************************************************************************
+ * 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * Global Function Prototypes
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LPC2378_LPC23XX_UART_H */
diff --git a/nuttx/arch/arm/src/lpc2378/lpc23xx_vic.h b/nuttx/arch/arm/src/lpc2378/lpc23xx_vic.h
new file mode 100644
index 000000000..c8b9871a1
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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
+ ************************************************************************************/
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc31xx/Kconfig b/nuttx/arch/arm/src/lpc31xx/Kconfig
new file mode 100644
index 000000000..39b19b95d
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/Kconfig
@@ -0,0 +1,204 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+comment "LPC31xx Configuration Options"
+
+choice
+ prompt "LPC31 Chip Selection"
+ default ARCH_CHIP_LPC3131
+ depends on ARCH_CHIP_LPC31XX
+
+config ARCH_CHIP_LPC3130
+ bool "LPC3130"
+
+config ARCH_CHIP_LPC3131
+ bool "LPC3131"
+
+config ARCH_CHIP_LPC3152
+ bool "LPC3152"
+
+config ARCH_CHIP_LPC3154
+ bool "LPC3154"
+
+endchoice
+
+choice
+ prompt "Toolchain Selection"
+ default LPC31_CODESOURCERYW
+ depends on ARCH_CHIP_LPC31XX
+
+config LPC31_CODESOURCERYW
+ bool "CodeSourcery for Windows"
+
+config LPC31_CODESOURCERYL
+ bool "CodeSourcery for Linux"
+
+config LPC31_DEVKITARM
+ bool "DevkitARM (Windows)"
+
+config LPC31_BUILDROOT
+ bool "NuttX buildroot (Cygwin or Linux)"
+
+endchoice
+
+menu "LPC31xx Memory Mapping"
+
+config LPC31_EXTNAND
+ bool "Map external NAND"
+ default n
+ ---help---
+ Map external NAND into the memory map.
+
+config LPC31_EXTSDRAM
+ bool "Map external SDRAM"
+ default n
+ ---help---
+ Map external SDRAM into the memory map.
+
+config LPC31_EXTSDRAMHEAP
+ bool "Add external SDRAM to the heap"
+ default y
+ depends on LPC31_EXTSDRAM
+ ---help---
+ Add external SDRAM into the heap.
+
+config LPC31_EXTSDRAMSIZE
+ int "External SDRAM size"
+ depends on LPC31_EXTSDRAM
+ ---help---
+ Size of the external SDRAM.
+
+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).
+
+config LPC31_EXTSRAM0
+ bool "Map external SRAM0"
+ default n
+ ---help---
+ Map external SRAM0 into the memory map.
+
+config LPC31_EXTSRAM0HEAP
+ bool "Add external SRAM0 to the heap"
+ default y
+ depends on LPC31_EXTSRAM0
+ ---help---
+ Add external SRAM0 into the heap.
+
+config LPC31_EXTSRAM0SIZE
+ int "External SRAM size"
+ depends on LPC31_EXTSRAM0
+ ---help---
+ Size of the external SRAM.
+
+config LPC31_EXTSRAM1
+ bool "Map external SRAM0"
+ default n
+ ---help---
+ Map external SRAM1 into the memory map.
+
+config LPC31_EXTSRAM1HEAP
+ bool "Add external SRAM1 to the heap"
+ default y
+ depends on LPC31_EXTSRAM1
+ ---help---
+ Add external SRAM1 into the heap.
+
+config LPC31_EXTSRAM1SIZE
+ int "External SRAM1 size"
+ depends on LPC31_EXTSRAM1
+ ---help---
+ Size of the external SRAM1.
+
+endmenu
+
+menu "LPC31xx Peripheral Support"
+
+config LPC31_UART
+ bool "UART"
+ default n
+ select ARCH_HAVE_UART
+
+config LPC31_SPI
+ bool "SPI"
+ default n
+
+config LPC31_USB
+ bool "USB"
+ default n
+
+config LPC31_MCI
+ bool "MCI"
+ default n
+
+endmenu
+
+menu "LPC31xx UART Configuration"
+ depends on LPC31_UART
+
+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
+
+endmenu
+
+menu "USB device driver options"
+
+config LPC31_USBDEV_EP0_MAXSIZE
+ int "EP0 Max packet size"
+ depends on USBDEV
+ default 64
+ ---help---
+ Endpoint 0 maximum packet size. Default: 64
+
+config LPC31_USBDEV_FRAME_INTERRUPT
+ bool "USB frame interrupt"
+ depends on USBDEV
+ 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"
+ depends on USBDEV
+ default n
+ ---help---
+ Enable lpc31xx-specific DMA support
+
+config LPC31_USBDEV_REGDEBUG
+ bool "Register level debug"
+ depends on USBDEV && DEBUG
+ default n
+ ---help---
+ Output detailed register-level USB device debug information. Requires also DEBUG.
+
+endmenu
+
+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
+
diff --git a/nuttx/arch/arm/src/lpc31xx/Make.defs b/nuttx/arch/arm/src/lpc31xx/Make.defs
new file mode 100644
index 000000000..83dadc8c0
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/Make.defs
@@ -0,0 +1,67 @@
+############################################################################
+# arch/arm/lpc31xx/Make.defs
+#
+# Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# 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 \
+ up_vectors.S up_vectoraddrexcptn.S up_vectortab.S
+CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.c up_createstack.c \
+ up_dataabort.c up_mdelay.c up_udelay.c up_exit.c up_idle.c \
+ up_initialize.c up_initialstate.c up_interruptcontext.c \
+ up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c \
+ up_prefetchabort.c up_releasepending.c up_releasestack.c \
+ up_reprioritizertr.c up_schedulesigaction.c \
+ up_sigdeliver.c up_syscall.c up_unblocktask.c \
+ up_undefinedinsn.c up_usestack.c
+
+ifeq ($(CONFIG_PAGING),y)
+CMN_CSRCS += up_pginitialize.c up_checkmapping.c up_allocpage.c up_va2pte.c
+endif
+
+CGU_ASRCS =
+CGU_CSRCS = lpc31_bcrndx.c lpc31_clkdomain.c lpc31_clkexten.c \
+ lpc31_clkfreq.c lpc31_clkinit.c lpc31_defclk.c \
+ lpc31_esrndx.c lpc31_fdcndx.c lpc31_fdivinit.c \
+ lpc31_freqin.c lpc31_pllconfig.c lpc31_resetclks.c \
+ lpc31_setfreqin.c lpc31_setfdiv.c lpc31_softreset.c
+
+CHIP_ASRCS = $(CGU_ASRCS)
+CHIP_CSRCS = lpc31_allocateheap.c lpc31_boot.c lpc31_decodeirq.c \
+ lpc31_irq.c lpc31_lowputc.c lpc31_serial.c lpc31_i2c.c \
+ lpc31_spi.c lpc31_timerisr.c $(CGU_CSRCS)
+
+ifeq ($(CONFIG_USBDEV),y)
+CHIP_CSRCS += lpc31_usbdev.c
+endif
diff --git a/nuttx/arch/arm/src/lpc31xx/chip.h b/nuttx/arch/arm/src/lpc31xx/chip.h
new file mode 100644
index 000000000..4ffcf2fbf
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/chip.h
@@ -0,0 +1,85 @@
+/************************************************************************************
+ * arch/arm/src/lpc31xx/chip.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LPC31XX_CHIP_H */
diff --git a/nuttx/arch/arm/src/lpc31xx/lpc31_adc.h b/nuttx/arch/arm/src/lpc31xx/lpc31_adc.h
new file mode 100644
index 000000000..c5edeef78
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_allocateheap.c b/nuttx/arch/arm/src/lpc31xx/lpc31_allocateheap.c
new file mode 100644
index 000000000..df3c897e1
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_allocateheap.c
@@ -0,0 +1,206 @@
+/************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_allocateheap.c
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "arm.h"
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+#include "lpc31_memorymap.h"
+
+#ifdef CONFIG_PAGING
+# include <nuttx/page.h>
+# 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_EXTSDRAM) && defined(CONFIG_LPC31_EXTSDRAMHEAP)
+# /* SRAM+EXTSRAM0+EXTSRAM1+EXTSDRAM */
+# define LPC31_NEXT_REGIONS 4
+# else
+# /* SRAM+EXTSRAM0+EXTSRAM1 */
+# define LPC31_NEXT_REGIONS 3
+# endif
+# elif defined(CONFIG_LPC31_EXTSDRAM) && defined(CONFIG_LPC31_EXTSDRAMHEAP)
+# /* 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_EXTSDRAM) && defined(CONFIG_LPC31_EXTSDRAMHEAP)
+# /* SRAM+EXTSRAM1+EXTSDRAM */
+# define LPC31_NEXT_REGIONS 3
+# else
+# /* SRAM+EXTSRAM1 */
+# define LPC31_NEXT_REGIONS 2
+# endif
+#elif defined(CONFIG_LPC31_EXTSDRAM) && defined(CONFIG_LPC31_EXTSDRAMHEAP)
+# /* 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_EXTSDRAM) && defined(CONFIG_LPC31_EXTSDRAMHEAP)
+# error "External SRAM1 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:
+ * The heap may be statically allocated by defining CONFIG_HEAP_BASE
+ * and CONFIG_HEAP_SIZE. If these are not defined, then this function
+ * will be called to dynamically set aside the heap region to the end
+ * of SRAM.
+ *
+ * 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)
+{
+ up_ledon(LED_HEAPALLOCATE);
+ *heap_start = (FAR void*)g_heapbase;
+ *heap_size = LPC31_HEAP_VEND - g_heapbase;
+}
+
+/************************************************************************
+ * 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)
+ mm_addregion((FAR void*)LPC31_EXTSRAM0_VSECTION, CONFIG_LPC31_EXTSRAM0SIZE);
+#endif
+
+#if defined(CONFIG_LPC31_EXTSRAM1) && defined(CONFIG_LPC31_EXTSRAM1HEAP)
+ mm_addregion((FAR void*)LPC31_EXTSRAM1_VSECTION, CONFIG_LPC31_EXTSRAM1SIZE);
+#endif
+
+#if defined(CONFIG_LPC31_EXTSDRAM) && defined(CONFIG_LPC31_EXTSDRAMHEAP)
+ mm_addregion((FAR void*)LPC31_EXTSDRAM_VSECTION, CONFIG_LPC31_EXTSDRAMSIZE);
+#endif
+}
+#endif
diff --git a/nuttx/arch/arm/src/lpc31xx/lpc31_analogdie.h b/nuttx/arch/arm/src/lpc31xx/lpc31_analogdie.h
new file mode 100644
index 000000000..9daf5c34f
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_bcrndx.c b/nuttx/arch/arm/src/lpc31xx/lpc31_bcrndx.c
new file mode 100644
index 000000000..f2bcf7276
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+#include <stdint.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_boot.c b/nuttx/arch/arm/src/lpc31xx/lpc31_boot.c
new file mode 100644
index 000000000..7abe15d4d
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <stdint.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "arm.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "lpc31_syscreg.h"
+#include "lpc31_cgudrvr.h"
+#include "lpc31_internal.h"
+
+#ifdef CONFIG_PAGING
+# include <nuttx/page.h>
+# 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 Variables
+ ************************************************************************************/
+
+extern uint32_t _vector_start; /* Beginning of vector block */
+extern uint32_t _vector_end; /* End+1 of vector block */
+
+/************************************************************************************
+ * Private Variables
+ ************************************************************************************/
+
+/* 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_EXTSDRAM) && CONFIG_LPC31_EXTSDRAMSIZE > 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/nuttx/arch/arm/src/lpc31xx/lpc31_cgu.h b/nuttx/arch/arm/src/lpc31xx/lpc31_cgu.h
new file mode 100644
index 000000000..0d1d7b7fb
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_cgudrvr.h b/nuttx/arch/arm/src/lpc31xx/lpc31_cgudrvr.h
new file mode 100644
index 000000000..a408f56b2
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_cgudrvr.h
@@ -0,0 +1,819 @@
+/************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_cgudrvr.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#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 initilization 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.
+ *
+ ****************************************************************************/
+
+EXTERN bool lpc31_defclk(enum lpc31_clockid_e clkid);
+
+/****************************************************************************
+ * Name: lpc31_resetclks
+ *
+ * Description:
+ * Put all clocks into a known, initial state
+ *
+ ****************************************************************************/
+
+EXTERN void lpc31_resetclks(void);
+
+/************************************************************************
+ * Name: lpc31_clkinit
+ *
+ * Description:
+ * Initialize all clock domains based on board-specific clock
+ * configuration data
+ *
+ ************************************************************************/
+
+EXTERN 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.
+ *
+ ************************************************************************/
+
+EXTERN 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
+ *
+ ************************************************************************/
+
+EXTERN 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.
+ *
+ ****************************************************************************/
+
+EXTERN 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.
+ *
+ ************************************************************************/
+
+EXTERN void lpc31_hp0pllconfig(void);
+
+/************************************************************************
+ * Name: lpc31_hp1pllconfig
+ *
+ * Description:
+ * Configure the HP1 PLL according to the board.h default selections.
+ *
+ ************************************************************************/
+
+EXTERN void lpc31_hp1pllconfig(void);
+
+/************************************************************************
+ * Name: lpc31_softreset
+ *
+ * Description:
+ * Perform a soft reset on the specified module.
+ *
+ ************************************************************************/
+
+EXTERN 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.
+ *
+ ************************************************************************/
+
+EXTERN 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
+ *
+ ************************************************************************/
+
+EXTERN 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.
+ *
+ ************************************************************************/
+
+EXTERN 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).
+ *
+ ************************************************************************/
+
+EXTERN 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
+ *
+ ************************************************************************/
+
+EXTERN 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.
+ *
+ ************************************************************************/
+
+EXTERN uint32_t lpc31_clkfreq(enum lpc31_clockid_e clkid,
+ enum lpc31_domainid_e dmnid);
+
+/************************************************************************
+ * Name: lpc31_enableexten
+ *
+ * Description:
+ * Enable external enabling for the the specified possible clocks.
+ *
+ ************************************************************************/
+
+EXTERN void lpc31_enableexten(enum lpc31_clockid_e clkid);
+
+/************************************************************************
+ * Name: lpc31_disableexten
+ *
+ * Description:
+ * Disable external enabling for the the specified possible clocks.
+ *
+ ************************************************************************/
+
+EXTERN 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/nuttx/arch/arm/src/lpc31xx/lpc31_clkdomain.c b/nuttx/arch/arm/src/lpc31xx/lpc31_clkdomain.c
new file mode 100644
index 000000000..e07f86e52
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+#include <stdint.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_clkexten.c b/nuttx/arch/arm/src/lpc31xx/lpc31_clkexten.c
new file mode 100644
index 000000000..20bd0c776
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+
+#include <arch/board/board.h>
+
+#include "lpc31_cgudrvr.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lpc31_enableexten
+ *
+ * Description:
+ * Enable external enabling for the 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 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/nuttx/arch/arm/src/lpc31xx/lpc31_clkfreq.c b/nuttx/arch/arm/src/lpc31xx/lpc31_clkfreq.c
new file mode 100644
index 000000000..e78b95086
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_clkfreq.c
@@ -0,0 +1,177 @@
+/************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_clkfreq.c
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+#include <stdint.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_clkinit.c b/nuttx/arch/arm/src/lpc31xx/lpc31_clkinit.c
new file mode 100644
index 000000000..b0e032281
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+
+#include <arch/board/board.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_decodeirq.c b/nuttx/arch/arm/src/lpc31xx/lpc31_decodeirq.c
new file mode 100644
index 000000000..41e1d3e13
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_decodeirq.c
@@ -0,0 +1,137 @@
+/********************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_decodeirq.c
+ * arch/arm/src/chip/lpc31_decodeirq.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <assert.h>
+#include <debug.h>
+
+#include "chip.h"
+#include "up_arch.h"
+
+#include "os_internal.h"
+#include "up_internal.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
+ lib_lowprintf("Unexpected IRQ\n");
+ current_regs = regs;
+ PANIC(OSERR_ERREXCEPTION);
+#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)
+ {
+ uint32_t* savestate;
+
+ /* Mask and acknowledge the interrupt */
+
+ up_maskack_irq(irq);
+
+ /* 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;
+
+ /* Unmask the last interrupt (global interrupts are still
+ * disabled).
+ */
+
+ up_enable_irq(irq);
+ }
+ }
+#endif
+}
diff --git a/nuttx/arch/arm/src/lpc31xx/lpc31_defclk.c b/nuttx/arch/arm/src/lpc31xx/lpc31_defclk.c
new file mode 100644
index 000000000..1f0ec194b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <arch/board/board.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_dma.h b/nuttx/arch/arm/src/lpc31xx/lpc31_dma.h
new file mode 100644
index 000000000..8bfac39d3
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_esrndx.c b/nuttx/arch/arm/src/lpc31xx/lpc31_esrndx.c
new file mode 100644
index 000000000..e29fe937d
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+#include <stdint.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_evntrtr.h b/nuttx/arch/arm/src/lpc31xx/lpc31_evntrtr.h
new file mode 100644
index 000000000..6ebc46e3b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_fdcndx.c b/nuttx/arch/arm/src/lpc31xx/lpc31_fdcndx.c
new file mode 100644
index 000000000..7d678b370
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+#include <stdint.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_fdivinit.c b/nuttx/arch/arm/src/lpc31xx/lpc31_fdivinit.c
new file mode 100644
index 000000000..f8ecb00f3
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+
+#include <arch/board/board.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_freqin.c b/nuttx/arch/arm/src/lpc31xx/lpc31_freqin.c
new file mode 100644
index 000000000..3540592ac
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+
+#include <arch/board/board.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_i2c.c b/nuttx/arch/arm/src/lpc31xx/lpc31_i2c.c
new file mode 100644
index 000000000..3d65c302d
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_i2c.c
@@ -0,0 +1,608 @@
+/*******************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_i2c.c
+ *
+ * Author: David Hewson
+ *
+ * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/i2c.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "wdog.h"
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "lpc31_i2c.h"
+#include "lpc31_evntrtr.h"
+#include "lpc31_syscreg.h"
+
+/*******************************************************************************
+ * Definitions
+ *******************************************************************************/
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define I2C_TIMEOUT ((20 * CLK_TCK) / 1000) /* 20 mS */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+struct lpc31_i2cdev_s
+{
+ struct i2c_dev_s dev; /* Generic I2C device */
+ struct i2c_msg_s msg; /* a single message for legacy read/write */
+ 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 */
+
+ 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 Functions
+ ****************************************************************************/
+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_reset (struct lpc31_i2cdev_s *priv);
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * I2C device operations
+ ****************************************************************************/
+
+static uint32_t i2c_setfrequency(FAR struct i2c_dev_s *dev, uint32_t frequency);
+static int i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits);
+static int i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer, int buflen);
+static int i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen);
+static int i2c_transfer(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, int count);
+
+struct i2c_ops_s lpc31_i2c_ops = {
+ .setfrequency = i2c_setfrequency,
+ .setaddress = i2c_setaddress,
+ .write = i2c_write,
+ .read = i2c_read,
+#ifdef CONFIG_I2C_TRANSFER
+ .transfer = i2c_transfer
+#endif
+};
+
+/*******************************************************************************
+ * Name: up_i2cinitialize
+ *
+ * Description:
+ * Initialise an I2C device
+ *
+ *******************************************************************************/
+
+struct i2c_dev_s *up_i2cinitialize(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_reset (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: up_i2cuninitalize
+ *
+ * Description:
+ * Uninitialise an I2C device
+ *
+ *******************************************************************************/
+
+void up_i2cuninitalize (struct lpc31_i2cdev_s *priv)
+{
+ /* Disable All Interrupts, soft reset the device */
+
+ i2c_reset (priv);
+
+ /* Detach Interrupt Handler */
+
+ irq_detach (priv->irqid);
+
+ /* Reset I2C blocks */
+
+ lpc31_softreset (priv->rstid);
+
+ /* Disable I2C system clocks */
+
+ lpc31_disableclock (priv->clkid);
+}
+
+/*******************************************************************************
+ * Name: lpc31_i2c_setfrequency
+ *
+ * Description:
+ * Set the frequence for the next transfer
+ *
+ *******************************************************************************/
+
+static uint32_t i2c_setfrequency(FAR struct i2c_dev_s *dev, uint32_t frequency)
+{
+ struct lpc31_i2cdev_s *priv = (struct lpc31_i2cdev_s *) dev;
+
+ 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);
+ }
+
+ /* FIXME: This function should return the actual selected frequency */
+ return frequency;
+}
+
+/*******************************************************************************
+ * Name: lpc31_i2c_setaddress
+ *
+ * Description:
+ * Set the I2C slave address for a subsequent read/write
+ *
+ *******************************************************************************/
+static int i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits)
+{
+ struct lpc31_i2cdev_s *priv = (struct lpc31_i2cdev_s *) dev;
+
+ DEBUGASSERT(dev != NULL);
+ DEBUGASSERT(nbits == 7 || nbits == 10);
+
+ priv->msg.addr = addr;
+ priv->msg.flags = (nbits == 7) ? 0 : I2C_M_TEN;
+
+ return OK;
+}
+
+/*******************************************************************************
+ * Name: lpc31_i2c_write
+ *
+ * Description:
+ * Send a block of data on I2C using the previously selected I2C
+ * frequency and slave address.
+ *
+ *******************************************************************************/
+static int i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer, int buflen)
+{
+ struct lpc31_i2cdev_s *priv = (struct lpc31_i2cdev_s *) dev;
+ int ret;
+
+ DEBUGASSERT (dev != NULL);
+
+ priv->msg.flags &= ~I2C_M_READ;
+ priv->msg.buffer = (uint8_t*)buffer;
+ priv->msg.length = buflen;
+
+ ret = i2c_transfer (dev, &priv->msg, 1);
+
+ return ret == 1 ? OK : -ETIMEDOUT;
+}
+
+/*******************************************************************************
+ * Name: lpc31_i2c_read
+ *
+ * Description:
+ * Receive a block of data on I2C using the previously selected I2C
+ * frequency and slave address.
+ *
+ *******************************************************************************/
+static int i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
+{
+ struct lpc31_i2cdev_s *priv = (struct lpc31_i2cdev_s *) dev;
+ int ret;
+
+ DEBUGASSERT (dev != NULL);
+
+ priv->msg.flags |= I2C_M_READ;
+ priv->msg.buffer = buffer;
+ priv->msg.length = buflen;
+
+ ret = i2c_transfer (dev, &priv->msg, 1);
+
+ return ret == 1 ? OK : -ETIMEDOUT;
+}
+
+/*******************************************************************************
+ * Name: i2c_transfer
+ *
+ * Description:
+ * Perform a sequence of I2C transfers
+ *
+ *******************************************************************************/
+
+static int i2c_transfer (FAR struct i2c_dev_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;
+
+ sem_wait (&priv->mutex);
+ flags = irqsave();
+
+ priv->state = I2C_STATE_START;
+ priv->msgs = msgs;
+ priv->nmsg = count;
+
+ 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);
+
+ while (priv->state != I2C_STATE_DONE)
+ {
+ sem_wait (&priv->wait);
+ }
+
+ wd_cancel (priv->timeout);
+
+ ret = count - priv->nmsg;
+
+ irqrestore (flags);
+ sem_post (&priv->mutex);
+
+ return ret;
+}
+
+/*******************************************************************************
+ * 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_reset (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_reset (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 = irqsave();
+
+ 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_reset (priv);
+
+ /* Mark the transfer as finished */
+ priv->state = I2C_STATE_DONE;
+ sem_post (&priv->wait);
+ }
+
+ irqrestore (flags);
+}
+
+/*******************************************************************************
+ * Name: i2c_reset
+ *
+ * Description:
+ * Perform a soft reset of the I2C controller
+ *
+ *******************************************************************************/
+static void i2c_reset (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)
+ ;
+}
diff --git a/nuttx/arch/arm/src/lpc31xx/lpc31_i2c.h b/nuttx/arch/arm/src/lpc31xx/lpc31_i2c.h
new file mode 100644
index 000000000..e7574c702
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_i2c.h
@@ -0,0 +1,207 @@
+/************************************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_i2c.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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 Types
+ ************************************************************************************************/
+
+/************************************************************************************************
+ * Public Data
+ ************************************************************************************************/
+
+/************************************************************************************************
+ * Public Functions
+ ************************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_I2C_H */
diff --git a/nuttx/arch/arm/src/lpc31xx/lpc31_i2s.h b/nuttx/arch/arm/src/lpc31xx/lpc31_i2s.h
new file mode 100644
index 000000000..5ad4413f0
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_intc.h b/nuttx/arch/arm/src/lpc31xx/lpc31_intc.h
new file mode 100644
index 000000000..e6dabded8
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_internal.h b/nuttx/arch/arm/src/lpc31xx/lpc31_internal.h
new file mode 100644
index 000000000..f68384b7e
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_internal.h
@@ -0,0 +1,300 @@
+/************************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_internal.h
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_INTERNAL_H
+#define __ARCH_ARM_SRC_LPC31XX_LPC31_INTERNAL_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+#include "chip.h"
+#include "lpc31_ioconfig.h"
+
+/************************************************************************************
+ * 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.
+ *
+ ************************************************************************************/
+
+EXTERN void lpc31_lowsetup(void);
+
+/************************************************************************************
+ * Name: lpc31_clockconfig
+ *
+ * Description:
+ * Called to change to new clock based on settings in board.h
+ *
+ ************************************************************************************/
+
+EXTERN void lpc31_clockconfig(void);
+
+/************************************************************************************
+ * 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.h). All other methods
+ * (including up_spiinitialize()) 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 up_spiinitialize() in your low level application
+ * initialization logic
+ * 5. The handle returned by up_spiinitialize() 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;
+EXTERN void lpc31_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t lpc31_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+#ifdef CONFIG_SPI_CMDDATA
+EXTERN 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.
+ *
+ ************************************************************************************/
+
+struct usbdev_s;
+EXTERN int lpc31_usbpullup(FAR struct usbdev_s *dev, bool enable);
+
+/************************************************************************************
+ * 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.
+ *
+ ************************************************************************************/
+
+struct usbdev_s;
+EXTERN void lpc31_usbsuspend(FAR struct usbdev_s *dev, bool resume);
+
+/****************************************************************************
+ * 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 */
+EXTERN 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
+ *
+ ****************************************************************************/
+
+EXTERN 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
+ *
+ ****************************************************************************/
+
+EXTERN 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_INTERNAL_H */
diff --git a/nuttx/arch/arm/src/lpc31xx/lpc31_ioconfig.h b/nuttx/arch/arm/src/lpc31xx/lpc31_ioconfig.h
new file mode 100644
index 000000000..2cf5e0c90
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_irq.c b/nuttx/arch/arm/src/lpc31xx/lpc31_irq.c
new file mode 100644
index 000000000..4418ebc08
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_irq.c
@@ -0,0 +1,218 @@
+/****************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_irq.c
+ * arch/arm/src/chip/lpc31_irq.c
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "arm.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+#include "lpc31_intc.h"
+#include "lpc31_cgudrvr.h"
+#include "lpc31_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/****************************************************************************
+ * 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
+ irqrestore(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_maskack_irq
+ *
+ * Description:
+ * Mask the IRQ and acknowledge it
+ *
+ ****************************************************************************/
+
+void up_maskack_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) AND disable interrupts
+ * (ENABLE=0 && WE_ENABLE=1). Configuration settings will be preserved because
+ * WE_TARGET is zero.
+ */
+
+ putreg32(INTC_REQUEST_CLRSWINT|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/nuttx/arch/arm/src/lpc31xx/lpc31_lcd.h b/nuttx/arch/arm/src/lpc31xx/lpc31_lcd.h
new file mode 100644
index 000000000..34aa6fc6e
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_lowputc.c b/nuttx/arch/arm/src/lpc31xx/lpc31_lowputc.c
new file mode 100644
index 000000000..72eb91748
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "lpc31_cgudrvr.h"
+#include "lpc31_uart.h"
+
+/****************************************************************************
+ * 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_LPC31_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 Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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 interrrupt 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/nuttx/arch/arm/src/lpc31xx/lpc31_mci.h b/nuttx/arch/arm/src/lpc31xx/lpc31_mci.h
new file mode 100644
index 000000000..8314db414
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_memorymap.h b/nuttx/arch/arm/src/lpc31xx/lpc31_memorymap.h
new file mode 100644
index 000000000..b5155df89
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_memorymap.h
@@ -0,0 +1,415 @@
+/************************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_memorymap.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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 OTG (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 definitiions below specifiy 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_EXTSDRAM) && CONFIG_LPC31_EXTSDRAMSIZE > 0
+# define LPC31_EXTSDRAM0_NSECTIONS _NSECTIONS(CONFIG_LPC31_EXTSDRAMSIZE)
+#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 <arch/board/board_memorymap.h>
+
+/* 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
+#elif defined(CONFIG_BOOT_RUNFROMSDRAM)
+# define NUTTX_START_VADDR LPC31_EXTSDRAM0_VSECTION
+#elif defined(CONFIG_BOOT_RUNFROMEXTSRAM)
+# define NUTTX_START_VADDR LPC31_EXTSRAM0_VADDR
+#else /* CONFIG_BOOT_RUNFROMISRAM, CONFIG_PAGING */
+# define NUTTX_START_VADDR LPC31_INTSRAM0_VADDR
+#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
+ * CONFIG_PGTABLE_VADDR and CONFIG_PGTABLE_PADDR in the configuration or 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/nuttx/arch/arm/src/lpc31xx/lpc31_mpmc.h b/nuttx/arch/arm/src/lpc31xx/lpc31_mpmc.h
new file mode 100644
index 000000000..5c2b8761a
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_nand.h b/nuttx/arch/arm/src/lpc31xx/lpc31_nand.h
new file mode 100644
index 000000000..52f22bdc2
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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 <<NAND_CONFIG_TL_SHIFT)
+# define NAND_CONFIG_TL_528 (0 <<NAND_CONFIG_TL_SHIFT)
+# define NAND_CONFIG_TL_516 (1 <<NAND_CONFIG_TL_SHIFT)
+# define NAND_CONFIG_TL_512 (2 <<NAND_CONFIG_TL_SHIFT)
+#define NAND_CONFIG_DC (1 << 8) /* Bit 8: Deactivate CE enable */
+#define NAND_CONFIG_M (1 << 7) /* Bit 7: 512 mode */
+#define NAND_CONFIG_LC_SHIFT (5) /* Bits 5-6: Latency Configuration */
+#define NAND_CONFIG_LC_MASK (3 << NAND_CONFIG_LC_SHIFT)
+# define NAND_CONFIG_LC_0WAITSTATES (0 << NAND_CONFIG_LC_SHIFT)
+# define NAND_CONFIG_LC_1WAITSTATES (1 << NAND_CONFIG_LC_SHIFT)
+# define NAND_CONFIG_LC_2WAITSTATES (2 << NAND_CONFIG_LC_SHIFT)
+#define NAND_CONFIG_ES (1 << 4) /* Bit 4: Endianess setting */
+#define NAND_CONFIG_DE (1 << 3) /* Bit 3: DMA external enable */
+#define NAND_CONFIG_AO (1 << 2) /* Bit 2: AES on (LPC3154 only) */
+#define NAND_CONFIG_WD (1 << 1) /* Bit 1: Wide device */
+#define NAND_CONFIG_EC (1 << 0) /* Bit 0: ECC on */
+
+/* NandIOConfig register description (NandIOConfig, address 0x1700 0810) */
+
+#define NAND_IOCONFIG_NI (1 << 24) /* Bit 24: Nand IO drive default */
+#define NAND_IOCONFIG_DN_SHIFT (8) /* Bits 8-23: Data to NAND default */
+#define NAND_IOCONFIG_DN_MASK (0xffff << NAND_IOCONFIG_DN_SHIFT)
+#define NAND_IOCONFIG_CD_SHIFT (6) /* Bits 6-7: CLE default */
+#define NAND_IOCONFIG_CD_MASK (3 << NAND_IOCONFIG_CD_SHIFT)
+#define NAND_IOCONFIG_AD_SHIFT (4) /* Bits 4-5: ALE default */
+#define NAND_IOCONFIG_AD_MASK (3 << NAND_IOCONFIG_AD_SHIFT)
+#define NAND_IOCONFIG_WD_SHIFT (2) /* Bits 2-3: WE_n default */
+#define NAND_IOCONFIG_WD_MASK (3 << NAND_IOCONFIG_WD_SHIFT)
+#define NAND_IOCONFIG_RD_SHIFT (0) /* Bits 0-1: RE_n default */
+#define NAND_IOCONFIG_RD_MASK (3 << NAND_IOCONFIG_RD_SHIFT)
+
+/* NandTiming1 register description (NandTiming1, address 0x17000814) */
+
+#define NAND_TIMING1_TSRD_SHIFT (20) /* Bits 20-21: Single data input delay */
+#define NAND_TIMING1_TSRD_MASK (3 << NAND_TIMING1_TSRD_SHIFT
+#define NAND_TIMING1_TALS_SHIFT (16) /* Bits 16-18: Address setup time */
+#define NAND_TIMING1_TALS_MASK (7 << NAND_TIMING1_TALS_SHIFT
+#define NAND_TIMING1_TALH_SHIFT (12) /* Bits 12-14: Address hold time */
+#define NAND_TIMING1_TALH_MASK (7 << NAND_TIMING1_TALH_SHIFT
+#define NAND_TIMING1_TCLS_SHIFT (4) /* Bits 4-6: Command setup time */
+#define NAND_TIMING1_TCLS_MASK (7 << NAND_TIMING1_TCLS_SHIFT
+#define NAND_TIMING1_TCLH_SHIFT (0) /* Bits 0-2: Command hold time */
+#define NAND_TIMING1_TCLH_MASK (7 << NAND_TIMING1_TCLH_SHIFT
+
+/* NandTiming2 register description (NandTiming2, address 0x17000818) */
+
+#define NAND_TIMING2_TDRD_SHIFT (28) /* Bits 28-30: Data input delay */
+#define NAND_TIMING2_TDRD_MASK (7 << NAND_TIMING2_TDRD_SHIFT)
+#define NAND_TIMING2_TEBIDEL_SHIFT (24) /* Bits 24-26: EBI delay time */
+#define NAND_TIMING2_TEBIDEL_MASK (7 << NAND_TIMING2_TEBIDEL_SHIFT)
+#define NAND_TIMING2_TCH_SHIFT (22) /* Bits 20-22: Chip select hold time */
+#define NAND_TIMING2_TCH_MASK (7 << NAND_TIMING2_TCH_SHIFT)
+#define NAND_TIMING2_TCS_SHIFT (16) /* Bits 16-18: Chip select setup time */
+#define NAND_TIMING2_TCS_MASK (7 << NAND_TIMING2_TCS_SHIFT)
+#define NAND_TIMING2_TREH_SHIFT (12) /* Bits 12-14: Read enable high hold */
+#define NAND_TIMING2_TREH_MASK (7 << NAND_TIMING2_TREH_SHIFT)
+#define NAND_TIMING2_TRP_SHIFT (8) /* Bits 8-10: Read enable pulse width */
+#define NAND_TIMING2_TRP_MASK (7 << NAND_TIMING2_TRP_SHIFT)
+#define NAND_TIMING2_TWH_SHIFT (4) /* Bits 4-6: Write enable high hold */
+#define NAND_TIMING2_TWH_MASK (7 << NAND_TIMING2_TWH_SHIFT)
+#define NAND_TIMING2_TWP_SHIFT (0) /* Bits 0-2: Write enable pulse width */
+#define NAND_TIMING2_TWP_MASK (7 << NAND_TIMING2_TWP_SHIFT)
+
+/* NandSetCmd register description (NandSetCmd, address 0x17000820) */
+
+#define NAND_SETCMD_CV_SHIFT (0) /* Bits 0-15: Command value */
+#define NAND_SETCMD_CV_MASK (0xffff << NAND_SETCMD_CV_SHIFT)
+
+/* NandSetAddr register description (NandSetAddr, address 0x17000824) */
+
+#define NAND_SETADDR_AV_SHIFT (0) /* Bits 0-15: Address value */
+#define NAND_SETADDR_AV_MASK (0xffff << NAND_SETADDR_AV_SHIFT)
+
+/* NandWriteData register description (NandWriteData, address 0x17000828) */
+
+#define NAND_WRITEDATA_WV_SHIFT (0) /* Bits 0-15: Write value */
+#define NAND_WRITEDATA_WV_MASK (0xffff << NAND_SETADDR_AV_SHIFT)
+
+/* NandSetCE register description (NandSetCE, address 0x1700082c) */
+
+#define NAND_SETCE_WP (1 << 4) /* Bit 4: WP_n pin value */
+#define NAND_SETCE_CEV_MASK (0x0f)
+#define NAND_SETCE_CE1N (1 << 3) /* Bit 3: Chip select CE1_n value */
+#define NAND_SETCE_CE2N (1 << 2) /* Bit 2: Chip select CE2_n value */
+#define NAND_SETCE_CE3N (1 << 1) /* Bit 1: Chip select CE3_n value */
+#define NAND_SETCE_CE4N (1 << 0) /* Bit 0: Chip select CE4_n value */
+
+/* NandReadData register description (NandReadData, address 0x17000830) */
+
+#define NAND_READDATA_RV_SHIFT (0) /* Bits 0-15: Read value */
+#define NAND_READDATA_RV_MASK (0xffff << NAND_READDATA_RV_SHIFT)
+
+/* NandCheckSTS register description (NandCheckSTS, address 0x17000834) */
+
+#define NAND_CHECKSTS_R3R (1 << 8) /* Bit 8: mNAND_RYBN3 rising edge */
+#define NAND_CHECKSTS_R2R (1 << 7) /* Bit 7: mNAND_RYBN2 rising edge */
+#define NAND_CHECKSTS_R1R (1 << 6) /* Bit 6: mNAND_RYBN1 rising edge */
+#define NAND_CHECKSTS_R0R (1 << 5) /* Bit 5: mNAND_RYBN0 rising edge */
+#define NAND_CHECKSTS_R3 (1 << 4) /* Bit 4: mNAND_RYBN3 value */
+#define NAND_CHECKSTS_R2 (1 << 3) /* Bit 3: mNAND_RYBN2 value */
+#define NAND_CHECKSTS_R1 (1 << 2) /* Bit 2: mNAND_RYBN1 value */
+#define NAND_CHECKSTS_R0 (1 << 1) /* Bit 1: mNAND_RYBN0 value */
+#define NAND_CHECKSTS_VB (1 << 0) /* Bit 0: APB busy */
+
+/* NandControlFlow register description (NandControlFlow, address 0x17000838) */
+
+#define NAND_CONTROLFLOW_W1 (1 << 5) /* Bit 5: Starts write SRAM1 to NAND */
+#define NAND_CONTROLFLOW_W0 (1 << 4) /* Bit 4: Starts write SRAM0 to NAND */
+#define NAND_CONTROLFLOW_R1 (1 << 1) /* Bit 1: Starts read from NAND to SRAM1 */
+#define NAND_CONTROLFLOW_R0 (1 << 0) /* Bit 0: Starts read from NAND to SRAM0 */
+
+/* NandGPIO1 register description (NandGPIO1, address 0x17000840) */
+
+#define NAND_GPIO1_GPIOCONF (1 << 26) /* Bit 26: GPIO mode */
+#define NAND_GPIO1_WPN (1 << 25) /* Bit 25: Value on WP_n */
+#define NAND_GPIO1_CLE (1 << 24) /* Bit 24: Value on CLE */
+#define NAND_GPIO1_ALE (1 << 23) /* Bit 23: Value on ALE */
+#define NAND_GPIO1_REN (1 << 22) /* Bit 22: Value on RE_n */
+#define NAND_GPIO1_WEN (1 << 21) /* Bit 21: Value on WE_n */
+#define NAND_GPIO1_CE4N (1 << 20) /* Bit 20: Value on NAND_NCS_3 */
+#define NAND_GPIO1_CE3N (1 << 19) /* Bit 19: Value on NAND_NCS_2 */
+#define NAND_GPIO1_CE2N (1 << 18) /* Bit 18: Value on NAND_NCS_1 */
+#define NAND_GPIO1_CE1N (1 << 17) /* Bit 17: Value on NAND_NCS_0 */
+#define NAND_GPIO1_IODRIVE (1 << 16) /* Bit 16: Program value on NAND IO drive */
+#define NAND_GPIO1_IODATA_SHIFT (0) /* Bit 0-15: Program value on data to NAND IO */
+#define NAND_GPIO1_IODATA_MASK (0xffff << NAND_GPIO1_IODATA_SHIFT)
+
+/* NandGPIO2 register description (NandGPIO2, address 0x17000844) */
+
+#define NAND_GPIO2_RnB3 (1 << 19) /* Bit 19: Read value from mNAND_RYBN3 */
+#define NAND_GPIO2_RnB2 (1 << 18) /* Bit 18: Read value from mNAND_RYBN2 */
+#define NAND_GPIO2_RnB1 (1 << 17) /* Bit 17: Read value from mNAND_RYBN1 */
+#define NAND_GPIO2_RnB0 (1 << 16) /* Bit 16: Read value from mNAND_RYBN0 */
+#define NAND_GPIO2_READDATA_SHIFT (0) /* Bit 0-15: Read data from NAND IO */
+#define NAND_GPIO2_READDATA_MASK (0xffff << NAND_GPIO2_READDATA_SHIFT)
+
+/* NandIRQStatus2 register description (NandIRQStatus2, address 0x1700 0848) */
+
+#define NAND_IRQSTATUS2_PGWHILEAPB (1 << 4) /* Bit 4: Page access while APB access */
+#define NAND_IRQSTATUS2_APBWHILEPG (1 << 3) /* Bit 3: APB access while page access */
+#define NAND_IRQSTATUS2_FLASHBUSY (1 << 2) /* Bit 2: Flash access while busy */
+#define NAND_IRQSTATUS2_RAM1BUSY (1 << 1) /* Bit 1: RAM1 access while busy */
+#define NAND_IRQSTATUS2_RAM0BUSY (1 << 0) /* Bit 0: RAM0 access while busy */
+
+/* NandIRQMask2 register description (NandIRQMask2, address 0x1700 084C) */
+
+#define NAND_IRQMASK2_PGWHILEAPB (1 << 4) /* Bit 4: Page access while APB access */
+#define NAND_IRQMASK2_APBWHILEPG (1 << 3) /* Bit 3: APB access while page access */
+#define NAND_IRQMASK2_FLASHBUSY (1 << 2) /* Bit 2: Flash access while busy */
+#define NAND_IRQMASK2_RAM1BUSY (1 << 1) /* Bit 1: RAM1 access while busy */
+#define NAND_IRQMASK2_RAM0BUSY (1 << 0) /* Bit 0: RAM0 access while busy */
+
+/* NandIRQStatusRaw2 register description (NandIRQStatusRaw2, address 0x1700 0850) */
+
+#define NAND_IRQSTATUSRAW2_PGWHILEAPB (1 << 4) /* Bit 4: Page access while APB access */
+#define NAND_IRQSTATUSRAW2_APBWHILEPG (1 << 3) /* Bit 3: APB access while page access */
+#define NAND_IRQSTATUSRAW2_FLASHBUSY (1 << 2) /* Bit 2: Flash access while busy */
+#define NAND_IRQSTATUSRAW2_RAM1BUSY (1 << 1) /* Bit 1: RAM1 access while busy */
+#define NAND_IRQSTATUSRAW2_RAM0BUSY (1 << 0) /* Bit 0: RAM0 access while busy */
+
+/* First-fourth words of 128-bit AES key (32-bit values, no bit fields -- LPC3154 only) */
+/* First-fourth words of 128-bit initial AES value (32-bit values, no bit fields -- LPC3154 only) */
+
+/* Register to display AES state (LPC3154 only) */
+
+#define NAND_AESSTATE_SHIFT (0) /* Bits 0-1: AES state */
+#define NAND_AESSTATE_MASK (3 << NAND_AESSTATE_SHIFT)
+# define NAND_AESSTATE_BUSY (0 << NAND_AESSTATE_SHIFT) /* AES state machine busy */
+# define NAND_AESSTATE_KEYSETUP (1 << NAND_AESSTATE_SHIFT) /* AES key setup needed */
+# define NAND_AESSTATE_IDLE (3 << NAND_AESSTATE_SHIFT) /* AES module is IDLE */
+
+/* NandECCErrStatus register description (NandECCErrStatus, address 0x1700 0878) */
+
+#define NAND_ECCERRSTATUS_NERR1_SHIFT (4) /* Bits 4-7: Number of errors in RAM1 */
+#define NAND_ECCERRSTATUS_NERR1_MASK (0x0f << NAND_ECCERRSTATUS_NERR1_SHIFT)
+#define NAND_ECCERRSTATUS_NERR0_SHIFT (0) /* Bits 0-3: Number of errors in RAM0 */
+#define NAND_ECCERRSTATUS_NERR0_MASK (0x0f << NAND_ECCERRSTATUS_NERR0_SHIFT)
+
+/* Enable AES engine from AHB */
+
+#define NAND_AESFROMAHB_MODE (1 << 7) /* Bit 7: Set AES from AHB mode */
+#define NAND_AESFROMAHB_DECRYPTRAM1 (1 << 1) /* Bit 1: Decrypt RAM1 */
+#define NAND_AESFROMAHB_DECRYPTRAM0 (1 << 0) /* Bit 0: Decrypt RAM0 */
+
+/************************************************************************************************
+ * Public Types
+ ************************************************************************************************/
+
+/************************************************************************************************
+ * Public Data
+ ************************************************************************************************/
+
+/************************************************************************************************
+ * Public Functions
+ ************************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_NAND_H */
diff --git a/nuttx/arch/arm/src/lpc31xx/lpc31_otp.h b/nuttx/arch/arm/src/lpc31xx/lpc31_otp.h
new file mode 100644
index 000000000..349fe2154
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_otp.h
@@ -0,0 +1,139 @@
+/************************************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_otp.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_pcm.h b/nuttx/arch/arm/src/lpc31xx/lpc31_pcm.h
new file mode 100644
index 000000000..0be577aef
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_pllconfig.c b/nuttx/arch/arm/src/lpc31xx/lpc31_pllconfig.c
new file mode 100644
index 000000000..fc6d4dc3b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+
+#include <stdint.h>
+
+#include <arch/board/board.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_pwm.h b/nuttx/arch/arm/src/lpc31xx/lpc31_pwm.h
new file mode 100644
index 000000000..042cd79d9
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_resetclks.c b/nuttx/arch/arm/src/lpc31xx/lpc31_resetclks.c
new file mode 100644
index 000000000..fe3287940
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_resetclks.c
@@ -0,0 +1,151 @@
+/****************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_resetclks.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+
+#include <arch/board/board.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_rng.h b/nuttx/arch/arm/src/lpc31xx/lpc31_rng.h
new file mode 100644
index 000000000..e0539f96a
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_serial.c b/nuttx/arch/arm/src/lpc31xx/lpc31_serial.c
new file mode 100644
index 000000000..c5438e1c8
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_serial.c
@@ -0,0 +1,856 @@
+/****************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_serial.c
+ *
+ * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <arch/serial.h>
+
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+#include "lpc31_cgudrvr.h"
+#include "lpc31_uart.h"
+
+#ifdef USE_SERIALDRIVER
+
+/****************************************************************************
+ * 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 Variables
+ ****************************************************************************/
+
+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,
+ .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_LPC31_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 interrrupt 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)
+{
+ struct inode *inode = filep->f_inode;
+ struct uart_dev_s *dev = inode->i_private;
+ int ret = OK;
+
+ switch (cmd)
+ {
+ 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;
+
+ case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
+ {
+ irqstate_t flags = irqsave();
+ up_enablebreaks();
+ irqrestore(flags);
+ }
+ break;
+
+ case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
+ {
+ irqstate_t flags;
+ flags = irqsave();
+ up_disablebreaks();
+ irqrestore(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/nuttx/arch/arm/src/lpc31xx/lpc31_setfdiv.c b/nuttx/arch/arm/src/lpc31xx/lpc31_setfdiv.c
new file mode 100644
index 000000000..196118b18
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <arch/board/board.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_setfreqin.c b/nuttx/arch/arm/src/lpc31xx/lpc31_setfreqin.c
new file mode 100644
index 000000000..bbac38240
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+
+#include <stdint.h>
+
+#include <arch/board/board.h>
+
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_softreset.c b/nuttx/arch/arm/src/lpc31xx/lpc31_softreset.c
new file mode 100644
index 000000000..fcade115a
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+#include <stdint.h>
+
+#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 the soft reset bit */
+
+ putreg32(CGU_SOFTRESET, address);
+}
diff --git a/nuttx/arch/arm/src/lpc31xx/lpc31_spi.c b/nuttx/arch/arm/src/lpc31xx/lpc31_spi.c
new file mode 100644
index 000000000..6f04af303
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_spi.c
@@ -0,0 +1,969 @@
+/************************************************************************************
+ * arm/arm/src/lpc31xx/lpc31_spi.c
+ *
+ * Copyright (C) 2009-2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: David Hewson, deriving in part from other SPI drivers originally by
+ * Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/spi.h>
+
+#include <arch/board/board.h>
+
+#include "lpc31_spi.h"
+#include "lpc31_ioconfig.h"
+
+/************************************************************************************
+ * 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,
+ .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,
+};
+
+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: up_spiinitialize
+ *
+ * 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 *up_spiinitialize(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/nuttx/arch/arm/src/lpc31xx/lpc31_spi.h b/nuttx/arch/arm/src/lpc31xx/lpc31_spi.h
new file mode 100644
index 000000000..6d63fe65d
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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 interrrupt bit */
+
+/************************************************************************************************
+ * Public Types
+ ************************************************************************************************/
+
+/************************************************************************************************
+ * Public Data
+ ************************************************************************************************/
+
+/************************************************************************************************
+ * Public Functions
+ ************************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_SPI_H */
diff --git a/nuttx/arch/arm/src/lpc31xx/lpc31_syscreg.h b/nuttx/arch/arm/src/lpc31xx/lpc31_syscreg.h
new file mode 100644
index 000000000..c14c7267c
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_timer.h b/nuttx/arch/arm/src/lpc31xx/lpc31_timer.h
new file mode 100644
index 000000000..b3d580ab6
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_timerisr.c b/nuttx/arch/arm/src/lpc31xx/lpc31_timerisr.c
new file mode 100644
index 000000000..ab9912c19
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <time.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "clock_internal.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "lpc31_timer.h"
+#include "lpc31_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize
+ * the timer interrupt.
+ *
+ ****************************************************************************/
+
+void up_timerinit(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/nuttx/arch/arm/src/lpc31xx/lpc31_uart.h b/nuttx/arch/arm/src/lpc31xx/lpc31_uart.h
new file mode 100644
index 000000000..d612e0308
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc31xx/lpc31_usbdev.c b/nuttx/arch/arm/src/lpc31xx/lpc31_usbdev.c
new file mode 100644
index 000000000..255f28da1
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_usbdev.c
@@ -0,0 +1,2668 @@
+/*******************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_usbdev.c
+ *
+ * Authors: David Hewson
+ * Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Part of the NuttX OS and based, in part, on the LPC2148 USB driver:
+ *
+ * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/usb/usb.h>
+#include <nuttx/usb/usbdev.h>
+#include <nuttx/usb/usbdev_trace.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "lpc31_usbotg.h"
+#include "lpc31_evntrtr.h"
+#include "lpc31_syscreg.h"
+
+/*******************************************************************************
+ * Definitions
+ *******************************************************************************/
+
+/* Configuration ***************************************************************/
+
+#ifndef CONFIG_LPC31_USBDEV_EP0_MAXSIZE
+# define CONFIG_LPC31_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_SUSPENDCHG 0x0018
+#define LPC31_TRACEINTID_SYNCHFRAME 0x0019
+
+/* 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 */
+ 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;
+ }
+
+ if (disr & USBDEV_USBSTS_SLI)
+ {
+ // FIXME: what do we need to do here...
+ usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_SUSPENDCHG),0);
+ }
+
+ 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 = irqsave();
+
+ /* 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);
+
+ irqrestore(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 *)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);
+ 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 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
+ 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 = irqsave();
+
+ /* 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);
+ }
+ }
+
+ irqrestore(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;
+ FAR struct lpc31_usbdev_s *priv;
+ irqstate_t flags;
+
+#ifdef CONFIG_DEBUG
+ if (!ep || !req)
+ {
+ usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_INVALIDPARMS), 0);
+ return -EINVAL;
+ }
+#endif
+
+ usbtrace(TRACE_EPCANCEL, privep->epphy);
+ priv = privep->dev;
+
+ flags = irqsave();
+
+ /* 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);
+ irqrestore(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 = irqsave();
+ 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);
+ }
+
+ irqrestore(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 = irqsave();
+ 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));
+ irqrestore(flags);
+
+ /* And return the pointer to the standard endpoint structure */
+
+ return &priv->eplist[epndx].ep;
+ }
+ }
+ /* Shouldn't get here */
+ }
+ irqrestore(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 = irqsave();
+ priv->epavail |= (1 << privep->epphy);
+ irqrestore(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 = irqsave();
+ lpc31_setbits(USBDEV_PRTSC1_FPR, LPC31_USBDEV_PORTSC1);
+ irqrestore(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 = irqsave();
+ if (enable)
+ lpc31_setbits (USBDEV_USBCMD_RS, LPC31_USBDEV_USBCMD);
+ else
+ lpc31_clrbits (USBDEV_USBCMD_RS, LPC31_USBDEV_USBCMD);
+ irqrestore(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_CMDEVICE,
+ 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 = irqsave();
+ 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);
+
+
+ irqrestore(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/nuttx/arch/arm/src/lpc31xx/lpc31_usbotg.h b/nuttx/arch/arm/src/lpc31xx/lpc31_usbotg.h
new file mode 100644
index 000000000..b98706dfb
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc31xx/lpc31_usbotg.h
@@ -0,0 +1,654 @@
+/************************************************************************************************
+ * arch/arm/src/lpc31xx/lpc31_usbotg.h
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include "lpc31_memorymap.h"
+
+/************************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************************/
+
+/* 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_CAPLENGTH_OFFSET 0x100 /* Capability register length */
+#define LPC31_USBHOST_HCIVERSION_OFFSET 0x102 /* Host interface version number */
+#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_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) */
+#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_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_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_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_CMIDLE (0 << USBDEV_USBMODE_CM_SHIFT) /* Idle */
+# define USBDEV_USBMODE_CMDEVICE (2 << USBDEV_USBMODE_CM_SHIFT) /* Device controller */
+# define USBDEV_USBMODE_CMHOST (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_CMIDLE (0 << USBHOST_USBMODE_CM_SHIFT) /* Idle */
+# define USBHOST_USBMODE_CMDEVICE (2 << USBHOST_USBMODE_CM_SHIFT) /* Device controller */
+# define USBHOST_USBMODE_CMHOST (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/nuttx/arch/arm/src/lpc31xx/lpc31_wdt.h b/nuttx/arch/arm/src/lpc31xx/lpc31_wdt.h
new file mode 100644
index 000000000..2840b67e4
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc43xx/Kconfig b/nuttx/arch/arm/src/lpc43xx/Kconfig
new file mode 100644
index 000000000..4653b2ee3
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/Kconfig
@@ -0,0 +1,318 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+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_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"
+
+endchoice
+
+config ARCH_FAMILY_LPC4310
+ bool
+ default y if ARCH_CHIP_LPC4310FBD144 || ARCH_CHIP_LPC4310FET100
+
+config ARCH_FAMILY_LPC4320
+ bool
+ default y if ARCH_CHIP_LPC4320FBD144 || ARCH_CHIP_LPC4320FET100
+
+config ARCH_FAMILY_LPC4330
+ bool
+ default y if ARCH_CHIP_LPC4330FBD144 || ARCH_CHIP_LPC4330FET100 || ARCH_CHIP_LPC4330FET180 || ARCH_CHIP_LPC4330FET256
+
+config ARCH_FAMILY_LPC4350
+ bool
+ default y if ARCH_CHIP_LPC4350FBD208 || ARCH_CHIP_LPC4350FET180 || ARCH_CHIP_LPC4350FET256
+
+config ARCH_FAMILY_LPC4353
+ bool
+ default y if ARCH_CHIP_LPC4353FBD208 || ARCH_CHIP_LPC4353FET180 || ARCH_CHIP_LPC4353FET256
+
+config ARCH_FAMILY_LPC4357
+ bool
+ default y if ARCH_CHIP_LPC4357FET180 || ARCH_CHIP_LPC4357FBD208 || ARCH_CHIP_LPC4357FET256
+
+choice
+ prompt "Toolchain Selection"
+ default LPC43_CODEREDW
+ depends on ARCH_CHIP_LPC43XX
+
+config LPC43_CODEREDW
+ bool "CodeRed for Windows"
+
+config LPC43_CODESOURCERYW
+ bool "CodeSourcery for Windows"
+
+config LPC43_CODESOURCERYL
+ bool "CodeSourcery for Linux"
+
+config LPC43_ATOLLIC_LITE
+ bool "Atollic Lite for Windows"
+
+config LPC43_ATOLLIC_PRO
+ bool "Atollic Pro for Windows"
+
+config LPC43_DEVKITARM
+ bool "DevkitARM (Windows)"
+
+config LPC43_BUILDROOT
+ bool "NuttX buildroot (Cygwin or Linux)"
+
+endchoice
+
+choice
+ prompt "LPC43XX Boot Configuration"
+ default 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 BOOT_SRAM.
+
+config BOOT_SRAM
+ bool "Running from SRAM"
+
+config BOOT_SPIFI
+ bool "Running from QuadFLASH"
+
+config BOOT_FLASHA
+ bool "Running in internal FLASHA"
+
+config BOOT_FLASHB
+ bool "Running in internal FLASHA"
+
+config BOOT_CS0FLASH
+ bool "Running in external FLASH CS0"
+
+config BOOT_CS1FLASH
+ bool "Running in external FLASH CS1"
+
+config BOOT_CS2FLASH
+ bool "Running in external FLASH CS2"
+
+config BOOT_CS3FLASH
+ bool "Running in external FLASH CS3"
+
+endchoice
+
+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_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"
+ select ARCH_HAVE_USART0
+ default n
+
+config LPC43_UART1
+ bool "UART1"
+ select ARCH_HAVE_UART1
+ default n
+
+config LPC43_USART2
+ bool "USART2"
+ select ARCH_HAVE_USART2
+ default n
+
+config LPC43_USART3
+ bool "USART3"
+ select ARCH_HAVE_USART3
+ default n
+
+config LPC43_USB0
+ bool "USB0"
+ default n
+
+config LPC43_USB1
+ bool "USB1"
+ default n
+
+config LPC43_USB1_ULPI
+ bool "USB1 with ULPI"
+ default n
+ depends on LPC43_USB1
+
+config LPC43_WWDT
+ bool "Windowing Watchdog Timer (WWDT)"
+ default n
+
+endmenu
+
+config SERIAL_TERMIOS
+ bool "Serial driver TERMIOS supported"
+ depends on LPC43_USART0 || LPC43_UART1 || LPC43_USART2 || LPC43_USART3
+ 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..
diff --git a/nuttx/arch/arm/src/lpc43xx/Make.defs b/nuttx/arch/arm/src/lpc43xx/Make.defs
new file mode 100644
index 000000000..cc8de3b32
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/Make.defs
@@ -0,0 +1,126 @@
+############################################################################
+# arch/arm/src/lpc43xx/Make.defs
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (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_CSRCS += 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_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_unblocktask.c
+CMN_CSRCS += up_usestack.c up_doirq.c up_hardfault.c up_svcall.c
+
+ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
+CMN_ASRCS += up_exception.S
+CMN_CSRCS += up_vectors.c
+endif
+
+ifeq ($(CONFIG_DEBUG_STACK),y)
+CMN_CSRCS += up_checkstack.c
+endif
+
+ifeq ($(CONFIG_ARCH_FPU),y)
+CMN_ASRCS += up_fpu.S
+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_timerisr.c lpc43_uart.c
+
+ifneq ($(CONFIG_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_SPI),y)
+CHIP_CSRCS += lpc43_spi.c
+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_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_acc.c
+else
+ifeq ($(CONFIG_LPC43_ADC1),y)
+CHIP_CSRCS += lpc43_adc.c
+endif
+endif
+
+ifeq ($(CONFIG_LPC43_DAC),y)
+CHIP_CSRCS += lpc43_acc.c
+else
+ifeq ($(CONFIG_LPC43_DAC),y)
+CHIP_CSRCS += lpc43_adc.c
+endif
+endif
+
+ifeq ($(CONFIG_LPC43_USB0),y)
+ifeq ($(CONFIG_USBDEV),y)
+CHIP_CSRCS += lpc31_usb0dev.c
+endif
+endif
+
diff --git a/nuttx/arch/arm/src/lpc43xx/chip.h b/nuttx/arch/arm/src/lpc43xx/chip.h
new file mode 100644
index 000000000..35150d08c
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/chip.h
@@ -0,0 +1,173 @@
+/************************************************************************************
+ * arch/arm/src/lpc43xx/chip.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/* Include the chip capabilities file */
+
+#include <arch/lpc43xx/chip.h>
+
+/* 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_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"
+#else
+# error "Unsupported LPC43xx chip"
+#endif
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* 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 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 */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_H */
diff --git a/nuttx/arch/arm/src/lpc43xx/chip/lpc4310203050_memorymap.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc4310203050_memorymap.h
new file mode 100644
index 000000000..882444c05
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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_PERIPH_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/nuttx/arch/arm/src/lpc43xx/chip/lpc4310203050_pinconfig.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc4310203050_pinconfig.h
new file mode 100644
index 000000000..c1c710e0c
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/chip/lpc4310203050_pinconfig.h
@@ -0,0 +1,982 @@
+/****************************************************************************************************
+ * arch/arm/src/lpc43xx/chip/lpc4310203050_pinconfig.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/****************************************************************************************************
+ * 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_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_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)
+
+#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_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/nuttx/arch/arm/src/lpc43xx/chip/lpc435357_memorymap.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc435357_memorymap.h
new file mode 100644
index 000000000..2cc96fb8e
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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_PERIPH_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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_adc.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_adc.h
new file mode 100644
index 000000000..bd2c31c08
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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_CHN_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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_aes.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_aes.h
new file mode 100644
index 000000000..74e53d616
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_atimer.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_atimer.h
new file mode 100644
index 000000000..1a5ef8602
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_can.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_can.h
new file mode 100644
index 000000000..cebeaccd8
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_ccu.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_ccu.h
new file mode 100644
index 000000000..ff7b4c9ab
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_ccu.h
@@ -0,0 +1,356 @@
+/****************************************************************************************************
+ * arch/arm/src/lpc43xx/chip/lpc43_ccu.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/****************************************************************************************************
+ * 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_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_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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_cgu.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_cgu.h
new file mode 100644
index 000000000..61fa3be0b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/****************************************************************************************************
+ * 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) */
+/* NOTE: Clocks 4-19 are identical */
+
+#define BASE_APB1_CLK_PD (1 << 0) /* Bit 0: Output stage power down */
+ /* Bits 1-10: Reserved */
+#define BASE_APB1_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */
+ /* Bits 12-23: Reserved */
+#define BASE_APB1_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */
+#define BASE_APB1_CLK_CLKSEL_MASK (31 << BASE_APB1_CLK_CLKSEL_SHIFT)
+# define BASE_APB1_CLKSEL_32KHZOSC (0 << BASE_APB1_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */
+# define BASE_APB1_CLKSEL_IRC (1 << BASE_APB1_CLK_CLKSEL_SHIFT) /* IRC (default) */
+# define BASE_APB1_CLKSEL_ENET_RXCLK (2 << BASE_APB1_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */
+# define BASE_APB1_CLKSEL_ENET_TXCLK (3 << BASE_APB1_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */
+# define BASE_APB1_CLKSEL_GPCLKIN (4 << BASE_APB1_CLK_CLKSEL_SHIFT) /* GP_CLKIN */
+# define BASE_APB1_CLKSEL_XTAL (6 << BASE_APB1_CLK_CLKSEL_SHIFT) /* Crystal oscillator */
+# define BASE_APB1_CLKSEL_PLL0AUDIO (8 << BASE_APB1_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */
+# define BASE_APB1_CLKSEL_PLL1 (9 << BASE_APB1_CLK_CLKSEL_SHIFT) /* PLL1 */
+# define BASE_APB1_CLKSEL_IDIVA (12 << BASE_APB1_CLK_CLKSEL_SHIFT) /* IDIVA */
+# define BASE_APB1_CLKSEL_IDIVB (13 << BASE_APB1_CLK_CLKSEL_SHIFT) /* IDIVB */
+# define BASE_APB1_CLKSEL_IDIVC (14 << BASE_APB1_CLK_CLKSEL_SHIFT) /* IDIVC */
+# define BASE_APB1_CLKSEL_IDIVD (15 << BASE_APB1_CLK_CLKSEL_SHIFT) /* IDIVD */
+# define BASE_APB1_CLKSEL_IDIVE (16 << BASE_APB1_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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_creg.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_creg.h
new file mode 100644
index 000000000..61a62e694
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_dac.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_dac.h
new file mode 100644
index 000000000..e06ecf442
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_eeprom.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_eeprom.h
new file mode 100644
index 000000000..19391d479
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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)
+# 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_emc.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_emc.h
new file mode 100644
index 000000000..4fb3ae38b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/****************************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h
new file mode 100644
index 000000000..e7d16fe26
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h
@@ -0,0 +1,666 @@
+/****************************************************************************************************
+ * arch/arm/src/lpc43xx/chip/lpc43_ethernet.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/****************************************************************************************************
+ * 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 */
+ /* Bits 1-2: Reserved */
+#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 */
+#define ETH_MACFFLT_SAIF (1 << 8) /* Bit 8: Source address inverse filtering */
+#define ETH_MACFFLT_SAF (1 << 9) /* Bit 9: Source address filter */
+ /* Bits 10-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_168 (4 << ETH_MACMIIA_CR_SHIFT) /* 150-168 MHz CLK_M4_ETHERNET/102 */
+# define ETH_MACMIIA_CR_150_168 (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_TSTIM)
+
+/* 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_LC (1 << 9) /* Bit 9: Late collision */
+#define ETH_TDES0_NC (1 << 10) /* Bit 10: No carrier */
+#define ETH_TDES0_LC (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_DE (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_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)
+ /* 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_PDELREQFUS (7 << ETH_RDES4_MT_SHIFT) /* Pdelay_Resp_Follow_Up (in
+ * peer-to-peer transparent clock) */
+# define ETH_RDES4_MT_PDELREQFUS (8 << ETH_RDES4_MT_SHIFT) /* Announce */
+# define ETH_RDES4_MT_PDELREQFUS (9 << ETH_RDES4_MT_SHIFT) /* Management */
+# define ETH_RDES4_MT_PDELREQFUS (10 << ETH_RDES4_MT_SHIFT) /* Signaling */
+# define ETH_RDES4_MT_PDELREQFUS (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 /* LPC43_NETHERNET > 0 */
+#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_ETHERNET_H */
+
diff --git a/nuttx/arch/arm/src/lpc43xx/chip/lpc43_evntmntr.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_evntmntr.h
new file mode 100644
index 000000000..a12112ece
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/****************************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_evntrtr.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_evntrtr.h
new file mode 100644
index 000000000..644e6758e
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_flash.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_flash.h
new file mode 100644
index 000000000..4f99484da
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_gima.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_gima.h
new file mode 100644
index 000000000..993242ebe
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/****************************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_gpdma.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_gpdma.h
new file mode 100644
index 000000000..f885c1387
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_gpdma.h
@@ -0,0 +1,466 @@
+/****************************************************************************************************
+ * arch/arm/src/lpc43xx/chip/lpc43_gpdma.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/****************************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_gpio.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_gpio.h
new file mode 100644
index 000000000..6d3bb5d80
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_gpio.h
@@ -0,0 +1,439 @@
+/****************************************************************************************************
+ * arch/arm/src/lpc43xx/chip/lpc43_gpio.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_i2c.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_i2c.h
new file mode 100644
index 000000000..000fbed51
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_i2s.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_i2s.h
new file mode 100644
index 000000000..71fc875e9
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_lcd.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_lcd.h
new file mode 100644
index 000000000..5762bed5e
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/****************************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_mcpwm.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_mcpwm.h
new file mode 100644
index 000000000..6344c24c9
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_otp.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_otp.h
new file mode 100644
index 000000000..67b5af319
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_pmc.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_pmc.h
new file mode 100644
index 000000000..511c515a2
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_qei.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_qei.h
new file mode 100644
index 000000000..9994c4e9e
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_rgu.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_rgu.h
new file mode 100644
index 000000000..acf2fdc5d
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/****************************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_rit.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_rit.h
new file mode 100644
index 000000000..915836e80
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_rit.h
@@ -0,0 +1,89 @@
+/************************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_rit.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_rtc.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_rtc.h
new file mode 100644
index 000000000..971349354
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_sct.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_sct.h
new file mode 100644
index 000000000..d93db2834
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/****************************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_scu.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_scu.h
new file mode 100644
index 000000000..d9dfe1ce9
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/****************************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_sdmmc.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_sdmmc.h
new file mode 100644
index 000000000..1236d82f3
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_sgpio.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_sgpio.h
new file mode 100644
index 000000000..bd3d2df39
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/****************************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_spi.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_spi.h
new file mode 100644
index 000000000..5f6e26d6b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_spifi.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_spifi.h
new file mode 100644
index 000000000..a0bec7592
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_spifi.h
@@ -0,0 +1,275 @@
+/****************************************************************************
+ * arch/arm/src/lpc43/chip/lpc43_spifi.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* 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
+ ****************************************************************************/
+
+EXTERN int32_t spifi_init(struct spifi_dev_s *dev, uint32_t cshigh,
+ uint32_t options, uint32_t mhz);
+EXTERN int32_t spifi_program(struct spifi_dev_s *dev, const uint8_t *source,
+ struct spifi_operands_s *opers);
+EXTERN 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_ssp.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_ssp.h
new file mode 100644
index 000000000..2bf934097
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_timer.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_timer.h
new file mode 100644
index 000000000..7627b135d
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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_TMR0_BASE+LPC43_TMR_IR_OFFSET)
+#define LPC43_TMR0_TCR (LPC43_TMR0_BASE+LPC43_TMR_TCR_OFFSET)
+#define LPC43_TMR0_TC (LPC43_TMR0_BASE+LPC43_TMR_TC_OFFSET)
+#define LPC43_TMR0_PR (LPC43_TMR0_BASE+LPC43_TMR_PR_OFFSET)
+#define LPC43_TMR0_PC (LPC43_TMR0_BASE+LPC43_TMR_PC_OFFSET)
+#define LPC43_TMR0_MCR (LPC43_TMR0_BASE+LPC43_TMR_MCR_OFFSET)
+#define LPC43_TMR0_MR0 (LPC43_TMR0_BASE+LPC43_TMR_MR0_OFFSET)
+#define LPC43_TMR0_MR1 (LPC43_TMR0_BASE+LPC43_TMR_MR1_OFFSET)
+#define LPC43_TMR0_MR2 (LPC43_TMR0_BASE+LPC43_TMR_MR2_OFFSET)
+#define LPC43_TMR0_MR3 (LPC43_TMR0_BASE+LPC43_TMR_MR3_OFFSET)
+#define LPC43_TMR0_CCR (LPC43_TMR0_BASE+LPC43_TMR_CCR_OFFSET)
+#define LPC43_TMR0_CR0 (LPC43_TMR0_BASE+LPC43_TMR_CR0_OFFSET)
+#define LPC43_TMR0_CR1 (LPC43_TMR0_BASE+LPC43_TMR_CR1_OFFSET)
+#define LPC43_TMR0_CR2 (LPC43_TMR0_BASE+LPC43_TMR_CR2_OFFSET)
+#define LPC43_TMR0_CR3 (LPC43_TMR0_BASE+LPC43_TMR_CR3_OFFSET)
+#define LPC43_TMR0_EMR (LPC43_TMR0_BASE+LPC43_TMR_EMR_OFFSET)
+#define LPC43_TMR0_CTCR (LPC43_TMR0_BASE+LPC43_TMR_CTCR_OFFSET)
+
+#define LPC43_TMR1_IR (LPC43_TMR1_BASE+LPC43_TMR_IR_OFFSET)
+#define LPC43_TMR1_TCR (LPC43_TMR1_BASE+LPC43_TMR_TCR_OFFSET)
+#define LPC43_TMR1_TC (LPC43_TMR1_BASE+LPC43_TMR_TC_OFFSET)
+#define LPC43_TMR1_PR (LPC43_TMR1_BASE+LPC43_TMR_PR_OFFSET)
+#define LPC43_TMR1_PC (LPC43_TMR1_BASE+LPC43_TMR_PC_OFFSET)
+#define LPC43_TMR1_MCR (LPC43_TMR1_BASE+LPC43_TMR_MCR_OFFSET)
+#define LPC43_TMR1_MR0 (LPC43_TMR1_BASE+LPC43_TMR_MR0_OFFSET)
+#define LPC43_TMR1_MR1 (LPC43_TMR1_BASE+LPC43_TMR_MR1_OFFSET)
+#define LPC43_TMR1_MR2 (LPC43_TMR1_BASE+LPC43_TMR_MR2_OFFSET)
+#define LPC43_TMR1_MR3 (LPC43_TMR1_BASE+LPC43_TMR_MR3_OFFSET)
+#define LPC43_TMR1_CCR (LPC43_TMR1_BASE+LPC43_TMR_CCR_OFFSET)
+#define LPC43_TMR1_CR0 (LPC43_TMR1_BASE+LPC43_TMR_CR0_OFFSET)
+#define LPC43_TMR1_CR1 (LPC43_TMR1_BASE+LPC43_TMR_CR1_OFFSET)
+#define LPC43_TMR1_CR2 (LPC43_TMR1_BASE+LPC43_TMR_CR2_OFFSET)
+#define LPC43_TMR1_CR3 (LPC43_TMR1_BASE+LPC43_TMR_CR3_OFFSET)
+#define LPC43_TMR1_EMR (LPC43_TMR1_BASE+LPC43_TMR_EMR_OFFSET)
+#define LPC43_TMR1_CTCR (LPC43_TMR1_BASE+LPC43_TMR_CTCR_OFFSET)
+
+#define LPC43_TMR2_IR (LPC43_TMR2_BASE+LPC43_TMR_IR_OFFSET)
+#define LPC43_TMR2_TCR (LPC43_TMR2_BASE+LPC43_TMR_TCR_OFFSET)
+#define LPC43_TMR2_TC (LPC43_TMR2_BASE+LPC43_TMR_TC_OFFSET)
+#define LPC43_TMR2_PR (LPC43_TMR2_BASE+LPC43_TMR_PR_OFFSET)
+#define LPC43_TMR2_PC (LPC43_TMR2_BASE+LPC43_TMR_PC_OFFSET)
+#define LPC43_TMR2_MCR (LPC43_TMR2_BASE+LPC43_TMR_MCR_OFFSET)
+#define LPC43_TMR2_MR0 (LPC43_TMR2_BASE+LPC43_TMR_MR0_OFFSET)
+#define LPC43_TMR2_MR1 (LPC43_TMR2_BASE+LPC43_TMR_MR1_OFFSET)
+#define LPC43_TMR2_MR2 (LPC43_TMR2_BASE+LPC43_TMR_MR2_OFFSET)
+#define LPC43_TMR2_MR3 (LPC43_TMR2_BASE+LPC43_TMR_MR3_OFFSET)
+#define LPC43_TMR2_CCR (LPC43_TMR2_BASE+LPC43_TMR_CCR_OFFSET)
+#define LPC43_TMR2_CR0 (LPC43_TMR2_BASE+LPC43_TMR_CR0_OFFSET)
+#define LPC43_TMR2_CR1 (LPC43_TMR2_BASE+LPC43_TMR_CR1_OFFSET)
+#define LPC43_TMR2_CR2 (LPC43_TMR2_BASE+LPC43_TMR_CR2_OFFSET)
+#define LPC43_TMR2_CR3 (LPC43_TMR2_BASE+LPC43_TMR_CR3_OFFSET)
+#define LPC43_TMR2_EMR (LPC43_TMR2_BASE+LPC43_TMR_EMR_OFFSET)
+#define LPC43_TMR2_CTCR (LPC43_TMR2_BASE+LPC43_TMR_CTCR_OFFSET)
+
+#define LPC43_TMR3_IR (LPC43_TMR3_BASE+LPC43_TMR_IR_OFFSET)
+#define LPC43_TMR3_TCR (LPC43_TMR3_BASE+LPC43_TMR_TCR_OFFSET)
+#define LPC43_TMR3_TC (LPC43_TMR3_BASE+LPC43_TMR_TC_OFFSET)
+#define LPC43_TMR3_PR (LPC43_TMR3_BASE+LPC43_TMR_PR_OFFSET)
+#define LPC43_TMR3_PC (LPC43_TMR3_BASE+LPC43_TMR_PC_OFFSET)
+#define LPC43_TMR3_MCR (LPC43_TMR3_BASE+LPC43_TMR_MCR_OFFSET)
+#define LPC43_TMR3_MR0 (LPC43_TMR3_BASE+LPC43_TMR_MR0_OFFSET)
+#define LPC43_TMR3_MR1 (LPC43_TMR3_BASE+LPC43_TMR_MR1_OFFSET)
+#define LPC43_TMR3_MR2 (LPC43_TMR3_BASE+LPC43_TMR_MR2_OFFSET)
+#define LPC43_TMR3_MR3 (LPC43_TMR3_BASE+LPC43_TMR_MR3_OFFSET)
+#define LPC43_TMR3_CCR (LPC43_TMR3_BASE+LPC43_TMR_CCR_OFFSET)
+#define LPC43_TMR3_CR0 (LPC43_TMR3_BASE+LPC43_TMR_CR0_OFFSET)
+#define LPC43_TMR3_CR1 (LPC43_TMR3_BASE+LPC43_TMR_CR1_OFFSET)
+#define LPC43_TMR3_CR2 (LPC43_TMR3_BASE+LPC43_TMR_CR2_OFFSET)
+#define LPC43_TMR3_CR3 (LPC43_TMR3_BASE+LPC43_TMR_CR3_OFFSET)
+#define LPC43_TMR3_EMR (LPC43_TMR3_BASE+LPC43_TMR_EMR_OFFSET)
+#define LPC43_TMR3_CTCR (LPC43_TMR3_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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_uart.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_uart.h
new file mode 100644
index 000000000..a0ea29718
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/********************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_usb0.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_usb0.h
new file mode 100644
index 000000000..6d18dd41c
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_usb0.h
@@ -0,0 +1,716 @@
+/************************************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_usb0.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************************/
+
+/* Register Offsets *****************************************************************************/
+ /* 0x000 - 0x0ff: Reserved */
+/* Device/host capability 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_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_USBMODE_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_USBMODE_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_CAPLENGTH (LPC43_USBOTG_BASE+LPC43_USBOTG_CAPLENGTH_OFFSET)
+#define LPC43_USBHOST_HCIVERSION (LPC43_USBOTG_BASE+LPC43_USBHOST_HCIVERSION_OFFSET)
+#define LPC43_USBHOST_HCSPARAMS (LPC43_USBOTG_BASE+LPC43_USBHOST_HCSPARAMS_OFFSET)
+#define LPC43_USBHOST_HCCPARAMS (LPC43_USBOTG_BASE+LPC43_USBHOST_HCCPARAMS_OFFSET)
+#define LPC43_USBDEV_DCIVERSION (LPC43_USBOTG_BASE+LPC43_USBDEV_DCIVERSION_OFFSET)
+#define LPC43_USBDEV_DCCPARAMS (LPC43_USBOTG_BASE+LPC43_USBDEV_DCCPARAMS_OFFSET)
+
+/* Device/host operational registers */
+
+#define LPC43_USBOTG_USBCMD (LPC43_USBOTG_BASE+LPC43_USBOTG_USBCMD_OFFSET)
+#define LPC43_USBOTG_USBSTS (LPC43_USBOTG_BASE+LPC43_USBOTG_USBSTS_OFFSET)
+#define LPC43_USBOTG_USBINTR (LPC43_USBOTG_BASE+LPC43_USBOTG_USBINTR_OFFSET)
+#define LPC43_USBOTG_FRINDEX (LPC43_USBOTG_BASE+LPC43_USBOTG_FRINDEX_OFFSET)
+#define LPC43_USBHOST_PERIODICLIST (LPC43_USBOTG_BASE+LPC43_USBHOST_PERIODICLIST_OFFSET)
+#define LPC43_USBDEV_DEVICEADDR (LPC43_USBOTG_BASE+LPC43_USBDEV_DEVICEADDR_OFFSET)
+#define LPC43_USBHOST_ASYNCLISTADDR (LPC43_USBOTG_BASE+LPC43_USBHOST_ASYNCLISTADDR_OFFSET)
+#define LPC43_USBDEV_ENDPOINTLIST (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPOINTLIST_OFFSET)
+#define LPC43_USBHOST_TTCTRL (LPC43_USBOTG_BASE+LPC43_USBHOST_TTCTRL_OFFSET)
+#define LPC43_USBOTG_BURSTSIZE (LPC43_USBOTG_BASE+LPC43_USBOTG_BURSTSIZE_OFFSET)
+#define LPC43_USBHOST_TXFILLTUNING (LPC43_USBOTG_BASE+LPC43_USBHOST_TXFILLTUNING_OFFSET)
+#define LPC43_USBOTG_BINTERVAL (LPC43_USBOTG_BASE+LPC43_USBOTG_BINTERVAL_OFFSET)
+#define LPC43_USBDEV_ENDPTNAK (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPTNAK_OFFSET)
+#define LPC43_USBDEV_ENDPTNAKEN (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPTNAKEN_OFFSET)
+#define LPC43_USBOTG_PORTSC1 (LPC43_USBOTG_BASE+LPC43_USBOTG_PORTSC1_OFFSET)
+#define LPC43_USBOTG_OTGSC (LPC43_USBOTG_BASE+LPC43_USBOTG_OTGSC_OFFSET)
+#define LPC43_USBOTG_USBMODE (LPC43_USBOTG_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_USBMODE
+#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_USBMODE
+#define LPC43_USBHOST_USBMODE LPC43_USBOTG_USBMODE
+
+/* Device endpoint registers */
+
+#define LPC43_USBDEV_ENDPTSETUPSTAT (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPTSETUPSTAT_OFFSET)
+#define LPC43_USBDEV_ENDPTPRIME (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPTPRIME_OFFSET)
+#define LPC43_USBDEV_ENDPTFLUSH (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPTFLUSH_OFFSET)
+#define LPC43_USBDEV_ENDPTSTATUS (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPTSTATUS_OFFSET)
+#define LPC43_USBDEV_ENDPTCOMPLETE (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPTCOMPLETE_OFFSET)
+
+#define LPC43_USBDEV_ENDPTCTRL(n) (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPTCTRL_OFFSET(n))
+#define LPC43_USBDEV_ENDPTCTRL0 (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPTCTRL0_OFFSET)
+#define LPC43_USBDEV_ENDPTCTRL1 (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPTCTRL1_OFFSET)
+#define LPC43_USBDEV_ENDPTCTRL2 (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPTCTRL2_OFFSET)
+#define LPC43_USBDEV_ENDPTCTRL3 (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPTCTRL3_OFFSET)
+#define LPC43_USBDEV_ENDPTCTRL4 (LPC43_USBOTG_BASE+LPC43_USBDEV_ENDPTCTRL4_OFFSET)
+#define LPC43_USBDEV_ENDPTCTRL5 (LPC43_USBOTG_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_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_CMIDLE (0 << USBHOST_USBMODE_CM_SHIFT) /* Idle */
+# define USBHOST_USBMODE_CMDEVICE (2 << USBHOST_USBMODE_CM_SHIFT) /* Device controller */
+# define USBHOST_USBMODE_CMHOST (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/nuttx/arch/arm/src/lpc43xx/chip/lpc43_wwdt.h b/nuttx/arch/arm/src/lpc43xx/chip/lpc43_wwdt.h
new file mode 100644
index 000000000..df9d172c7
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/lpc43_adc.c b/nuttx/arch/arm/src/lpc43xx/lpc43_adc.c
new file mode 100644
index 000000000..d9165ba75
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_adc.c
@@ -0,0 +1,283 @@
+/************************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_adc.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Ported from from the LPC17 version:
+ *
+ * Copyright (C) 2011 Li Zhuoyi. All rights reserved.
+ * Author: Li Zhuoyi <lzyy.cn@gmail.com>
+ * 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 <nuttx/config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+#include <nuttx/arch.h>
+#include <nuttx/analog/adc.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lpc43_syscon.h"
+#include "lpc43_pinconn.h"
+#include "lpc43_adc.h"
+
+#if defined(CONFIG_LPC43_ADC)
+
+#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 = LPC43_IRQ_ADC,
+};
+
+static struct adc_dev_s g_adcdev =
+{
+ .ad_ops = &g_adcops,
+ .ad_priv= &g_adcpriv,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* Reset the ADC device. Called early to initialize the hardware. This
+ * is called, before ao_setup() and on error conditions.
+ */
+
+static void adc_reset(FAR struct adc_dev_s *dev)
+{
+ irqstate_t flags;
+ uint32_t regval;
+ FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
+
+ flags = irqsave();
+
+ regval = getreg32(LPC43_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCADC;
+ putreg32(regval, LPC43_SYSCON_PCONP);
+
+ putreg32(ADC_CR_PDN,LPC43_ADC_CR);
+
+ regval = getreg32(LPC43_SYSCON_PCLKSEL0);
+ regval &= ~SYSCON_PCLKSEL0_ADC_MASK;
+ regval |= (SYSCON_PCLKSEL_CCLK8 << SYSCON_PCLKSEL0_ADC_SHIFT);
+ putreg32(regval, LPC43_SYSCON_PCLKSEL0);
+
+ uint32_t clkdiv=LPC43_CCLK/8/65/priv->sps;
+ clkdiv<<=8;
+ clkdiv&=0xff00;
+ putreg32(ADC_CR_PDN|ADC_CR_BURST|clkdiv|priv->mask,LPC43_ADC_CR);
+
+ if(priv->mask&0x01)
+ lpc43_configgpio(GPIO_AD0p0);
+ else if(priv->mask&0x02)
+ lpc43_configgpio(GPIO_AD0p1);
+ else if(priv->mask&0x04)
+ lpc43_configgpio(GPIO_AD0p2);
+ else if(priv->mask&0x08)
+ lpc43_configgpio(GPIO_AD0p3);
+ else if(priv->mask&0x10)
+ lpc43_configgpio(GPIO_AD0p4);
+ else if(priv->mask&0x20)
+ lpc43_configgpio(GPIO_AD0p5);
+ else if(priv->mask&0x40)
+ lpc43_configgpio(GPIO_AD0p6);
+ else if(priv->mask&0x80)
+ lpc43_configgpio(GPIO_AD0p7);
+
+ irqrestore(flags);
+}
+
+/* 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)
+{
+ int i;
+ 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)
+ {
+ for (i = 0; i < 8; i++)
+ {
+ priv->buf[i]=0;
+ priv->count[i]=0;
+ }
+ up_enable_irq(priv->irq);
+ }
+ return ret;
+}
+
+/* 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;
+ up_disable_irq(priv->irq);
+ irq_detach(priv->irq);
+}
+
+/* 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(ADC_INTEN_GLOBAL, LPC43_ADC_INTEN);
+ else
+ putreg32(0x00, LPC43_ADC_INTEN);
+}
+
+/* All ioctl calls will be routed through this method */
+
+static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg)
+{
+ dbg("Fix me:Not Implemented\n");
+ return 0;
+}
+
+static int adc_interrupt(int irq, void *context)
+{
+ uint32_t regval;
+ FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv;
+ unsigned char ch;
+ int32_t value;
+
+ regval = getreg32(LPC43_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;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_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)
+{
+ return &g_adcdev;
+}
+#endif
+
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_adc.h b/nuttx/arch/arm/src/lpc43xx/lpc43_adc.h
new file mode 100644
index 000000000..ae8cef6c1
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_adc.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_adc.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <nuttx/analog/adc.h>
+#include "chip/lpc43_adc.h"
+
+#ifdef CONFIG_LPC43_ADC
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/lpc43_allocateheap.c b/nuttx/arch/arm/src/lpc43xx/lpc43_allocateheap.c
new file mode 100644
index 000000000..7912f6c6e
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_allocateheap.c
@@ -0,0 +1,290 @@
+/****************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_allocateheap.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/mm.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "lpc43_emacram.h"
+#include "lpc43_usbram.h"
+
+/****************************************************************************
+ * Private 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_DRAM_START = The start of the data RAM region which may be
+ * either local SRAM bank 0 (Configuration A) or 1 (Configuration B).
+ * CONFIG_DRAM_START = The size of the data RAM region.
+ * CONFIG_DRAM_END = The sum of the above
+ */
+
+/* Check for Configuration A. */
+
+#ifndef CONFIG_BOOT_SRAM
+
+/* Configuration A */
+/* CONFIG_DRAM_START should be set to the base of AHB SRAM, local 0. */
+
+# if CONFIG_DRAM_START != LPC43_LOCSRAM_BANK0_BASE
+# error "CONFIG_DRAM_START must be set to the base address of AHB SRAM Bank 0"
+# endif
+
+/* The configured RAM size should be equal to the size of local SRAM Bank 0 */
+
+# if CONFIG_DRAM_SIZE != LPC43_LOCSRAM_BANK0_SIZE
+# error "CONFIG_DRAM_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_DRAM_START should be set to the base of local SRAM, bank 1. */
+
+# if CONFIG_DRAM_START != LPC43_LOCSRAM_BANK1_BASE
+# error "CONFIG_DRAM_START must be set to the base address of AHB SRAM Bank 0"
+# endif
+
+/* The configured RAM size should be equal to the size of local SRAM Bank 1 */
+
+# if CONFIG_DRAM_SIZE != LPC43_LOCSRAM_BANK1_SIZE
+# error "CONFIG_DRAM_SIZE must be set to size of AHB SRAM Bank 0"
+# 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_heapbase is the beginning of this heap region (not necessarily aligned).
+ */
+
+const uint32_t g_heapbase = (uint32_t)&_ebss + CONFIG_IDLETHREAD_STACKSIZE;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_allocate_heap
+ *
+ * Description:
+ * The heap may be statically allocated by
+ * defining CONFIG_HEAP_BASE and CONFIG_HEAP_SIZE. If these
+ * are not defined, then this function will be called to
+ * dynamically set aside the heap region.
+ *
+ ****************************************************************************/
+
+void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
+{
+ /* Start with the first SRAM region */
+
+ up_ledon(LED_HEAPALLOCATE);
+ *heap_start = (FAR void*)g_heapbase;
+ *heap_size = CONFIG_DRAM_END - g_heapbase;
+}
+
+/************************************************************************
+ * 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) */
+
+ mm_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) */
+
+ mm_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) */
+
+ mm_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) */
+
+ mm_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/nuttx/arch/arm/src/lpc43xx/lpc43_cgu.c b/nuttx/arch/arm/src/lpc43xx/lpc43_cgu.c
new file mode 100644
index 000000000..61c4112ae
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_cgu.c
@@ -0,0 +1,482 @@
+/****************************************************************************
+ * arch/arm/src/lpc43/lpc43_cgu.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <nuttx/arch.h>
+#include <errno.h>
+
+#include "up_arch.h"
+#include "lpc43_cgu.h"
+#include <arch/board/board.h>
+
+/****************************************************************************
+ * 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_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
+}
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_cgu.h b/nuttx/arch/arm/src/lpc43xx/lpc43_cgu.h
new file mode 100644
index 000000000..94254c648
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_cgu.h
@@ -0,0 +1,91 @@
+/************************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_cgu.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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_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.
+ *
+ ************************************************************************************/
+
+EXTERN void lpc43_clockconfig(void);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_LPC43XX_CGU_H */
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_clrpend.c b/nuttx/arch/arm/src/lpc43xx/lpc43_clrpend.c
new file mode 100644
index 000000000..ca7189103
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <arch/irq.h>
+
+#include "nvic.h"
+#include "up_arch.h"
+
+#include "lpc43_irq.h"
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/lpc43_config.h b/nuttx/arch/arm/src/lpc43xx/lpc43_config.h
new file mode 100644
index 000000000..fb5773682
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_config.h
@@ -0,0 +1,153 @@
+/************************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_config.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * 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
+#endif
+
+#ifndef CONFIG_LPC43_UART1
+# undef CONFIG_UART1_SERIAL_CONSOLE
+#endif
+
+#ifndef CONFIG_LPC43_USART2
+# undef CONFIG_USART2_SERIAL_CONSOLE
+# undef CONFIG_USART2_RS485MODE
+#endif
+
+#ifndef CONFIG_LPC43_USART3
+# undef CONFIG_USART3_SERIAL_CONSOLE
+# undef CONFIG_USART3_RS485MODE
+#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 (USART0,2,3 only) */
+
+#undef HAVE_RS485
+#if defined(CONFIG_USART0_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/nuttx/arch/arm/src/lpc43xx/lpc43_dac.c b/nuttx/arch/arm/src/lpc43xx/lpc43_dac.c
new file mode 100644
index 000000000..5fcceaa1e
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_dac.c
@@ -0,0 +1,204 @@
+/************************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_dac.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Ported from from the LPC17 version:
+ *
+ * Copyright (C) 2011 Li Zhuoyi. All rights reserved.
+ * Author: Li Zhuoyi <lzyy.cn@gmail.com>
+ * 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 <nuttx/config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+#include <nuttx/arch.h>
+#include <nuttx/analog/dac.h>
+
+#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 = irqsave();
+
+ 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);
+
+ irqrestore(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/nuttx/arch/arm/src/lpc43xx/lpc43_dac.h b/nuttx/arch/arm/src/lpc43xx/lpc43_dac.h
new file mode 100644
index 000000000..310e29f51
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_dac.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_dac.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <nuttx/analog/dac.h>
+#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
+ *
+ ****************************************************************************/
+
+EXTERN 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/nuttx/arch/arm/src/lpc43xx/lpc43_debug.c b/nuttx/arch/arm/src/lpc43xx/lpc43_debug.c
new file mode 100644
index 000000000..51cf94706
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <errno.h>
+
+#include <arch/board/board.h>
+
+#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/nuttx/arch/arm/src/lpc43xx/lpc43_emacram.h b/nuttx/arch/arm/src/lpc43xx/lpc43_emacram.h
new file mode 100644
index 000000000..2c472b616
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include "chip.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_EMACRAM_H */
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_emc.h b/nuttx/arch/arm/src/lpc43xx/lpc43_emc.h
new file mode 100644
index 000000000..3c2bd2496
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc43xx/lpc43_gpdma.c b/nuttx/arch/arm/src/lpc43xx/lpc43_gpdma.c
new file mode 100644
index 000000000..4cfc0327f
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+
+#include "lpc43_syscon.h"
+#include "lpc43_gpdma.h"
+
+#ifdef CONFIG_LPC43_GPDMA
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/lpc43_gpdma.h b/nuttx/arch/arm/src/lpc43xx/lpc43_gpdma.h
new file mode 100644
index 000000000..68469d9b6
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_gpdma.h
@@ -0,0 +1,236 @@
+/****************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_gpdma.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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
+ *
+ ****************************************************************************/
+
+EXTERN 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.
+ *
+ ****************************************************************************/
+
+EXTERN 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
+ *
+ ****************************************************************************/
+
+EXTERN void lpc43_dmafree(DMA_HANDLE handle);
+
+/****************************************************************************
+ * Name: lpc43_dmasetup
+ *
+ * Description:
+ * Configure DMA for one transfer.
+ *
+ ****************************************************************************/
+
+EXTERN 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
+ *
+ ****************************************************************************/
+
+EXTERN 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
+ *
+ ****************************************************************************/
+
+EXTERN void lpc43_dmastop(DMA_HANDLE handle);
+
+/****************************************************************************
+ * Name: lpc43_dmasample
+ *
+ * Description:
+ * Sample DMA register contents
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_DMA
+EXTERN 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
+EXTERN 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/nuttx/arch/arm/src/lpc43xx/lpc43_gpio.c b/nuttx/arch/arm/src/lpc43xx/lpc43_gpio.c
new file mode 100644
index 000000000..2b2c88f31
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_gpio.c
@@ -0,0 +1,251 @@
+/****************************************************************************
+ * arch/arm/src/lpc43/lpc43_gpio.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <arch/board/board.h>
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#include <errno.h>
+#include <debug.h>
+
+#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 = irqsave();
+ 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;
+ }
+
+ irqrestore(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/nuttx/arch/arm/src/lpc43xx/lpc43_gpio.h b/nuttx/arch/arm/src/lpc43xx/lpc43_gpio.h
new file mode 100644
index 000000000..8f8460966
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_gpio.h
@@ -0,0 +1,324 @@
+/********************************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_gpio.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <nuttx/irq.h>
+
+/* 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.
+ *
+ ********************************************************************************************/
+
+EXTERN int lpc43_gpio_config(uint16_t gpiocfg);
+
+/********************************************************************************************
+ * Name: lpc43_gpio_write
+ *
+ * Description:
+ * Write one or zero to the selected GPIO pin
+ *
+ * Returned Value:
+ * None
+ *
+ ********************************************************************************************/
+
+EXTERN 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
+ *
+ ********************************************************************************************/
+
+EXTERN 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
+EXTERN 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/nuttx/arch/arm/src/lpc43xx/lpc43_gpioint.c b/nuttx/arch/arm/src/lpc43xx/lpc43_gpioint.c
new file mode 100644
index 000000000..d33d2dfa9
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_gpioint.c
@@ -0,0 +1,317 @@
+/****************************************************************************
+ * arch/arm/src/lpc43/lpc43_gpioint.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <arch/board/board.h>
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#include <errno.h>
+
+#include "chip.h"
+#include "chip/lpc43_scu.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 = irqsave();
+ 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(regbal, grpbase + LPC43_GRP1INT_CTRL_OFFSET);
+
+ irqrestore(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;
+ int ret = OK;
+
+ 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);
+ int ret = OK;
+
+ /* Select the group register base address */
+
+ flags = irqsave();
+ 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);
+
+ irqrestore(flags);
+ return OK;
+}
+
+#endif /* CONFIG_GPIO_IRQ */
+
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_gpioint.h b/nuttx/arch/arm/src/lpc43xx/lpc43_gpioint.h
new file mode 100644
index 000000000..ef83d147f
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_gpioint.h
@@ -0,0 +1,140 @@
+/************************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_gpioint.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+#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.
+ *
+ ****************************************************************************/
+
+EXTERN 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.
+ *
+ ****************************************************************************/
+
+EXTERN 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.
+ *
+ ****************************************************************************/
+
+EXTERN int lpc43_gpioint_grpconfig(uint16_t gpiocfg);
+
+#endif /* CONFIG_GPIO_IRQ */
+#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_GPIOINT_H */
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_i2c.c b/nuttx/arch/arm/src/lpc43xx/lpc43_i2c.c
new file mode 100644
index 000000000..64a044f13
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_i2c.c
@@ -0,0 +1,567 @@
+/*******************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_i2c.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Ported from from the LPC17 version:
+ *
+ * Copyright (C) 2011 Li Zhuoyi. All rights reserved.
+ * Author: Li Zhuoyi <lzyy.cn@gmail.com>
+ * 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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/i2c.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "wdog.h"
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+#include "os_internal.h"
+
+#include "lpc43_syscon.h"
+#include "lpc43_pinconn.h"
+#include "lpc43_i2c.h"
+
+#if defined(CONFIG_LPC43_I2C0) || defined(CONFIG_LPC43_I2C1)
+
+#ifndef GPIO_I2C1_SCL
+ #define GPIO_I2C1_SCL GPIO_I2C1_SCL_1
+ #define GPIO_I2C1_SDA GPIO_I2C1_SDA_1
+#endif
+#ifndef CONFIG_I2C0_FREQ
+ #define CONFIG_I2C0_FREQ 100000
+#endif
+#ifndef CONFIG_I2C1_FREQ
+ #define CONFIG_I2C1_FREQ 100000
+#endif
+#ifndef CONFIG_I2C2_FREQ
+ #define CONFIG_I2C2_FREQ 100000
+#endif
+
+/*******************************************************************************
+ * Definitions
+ *******************************************************************************/
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define I2C_TIMEOUT ((20 * CLK_TCK) / 1000) /* 20 mS */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lpc43_i2cdev_s
+{
+ struct i2c_dev_s dev; /* Generic I2C device */
+ struct i2c_msg_s msg; /* a single message for legacy read/write */
+ 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 */
+
+ 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 i2c_start(struct lpc43_i2cdev_s *priv);
+static void i2c_stop(struct lpc43_i2cdev_s *priv);
+static int i2c_interrupt(int irq, FAR void *context);
+static void i2c_timeout(int argc, uint32_t arg, ...);
+
+/****************************************************************************
+ * I2C device operations
+ ****************************************************************************/
+
+static uint32_t i2c_setfrequency(FAR struct i2c_dev_s *dev,
+ uint32_t frequency);
+static int i2c_setaddress(FAR struct i2c_dev_s *dev, int addr,
+ int nbits);
+static int i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer,
+ int buflen);
+static int i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer,
+ int buflen);
+static int i2c_transfer(FAR struct i2c_dev_s *dev,
+ FAR struct i2c_msg_s *msgs, int count);
+
+struct i2c_ops_s lpc43_i2c_ops =
+{
+ .setfrequency = i2c_setfrequency,
+ .setaddress = i2c_setaddress,
+ .write = i2c_write,
+ .read = i2c_read,
+#ifdef CONFIG_I2C_TRANSFER
+ .transfer = i2c_transfer
+#endif
+};
+
+/*******************************************************************************
+ * Name: lpc43_i2c_setfrequency
+ *
+ * Description:
+ * Set the frequence for the next transfer
+ *
+ *******************************************************************************/
+
+static uint32_t i2c_setfrequency(FAR struct i2c_dev_s *dev, uint32_t frequency)
+{
+ struct lpc43_i2cdev_s *priv = (struct lpc43_i2cdev_s *) dev;
+
+ if (frequency > 100000)
+ {
+ /* asymetric per 400Khz I2C spec */
+
+ putreg32(LPC43_CCLK / (83 + 47) * 47 / frequency, priv->base + LPC43_I2C_SCLH_OFFSET);
+ putreg32(LPC43_CCLK / (83 + 47) * 83 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET);
+ }
+ else
+ {
+ /* 50/50 mark space ratio */
+
+ putreg32(LPC43_CCLK / 100 * 50 / frequency, priv->base + LPC43_I2C_SCLH_OFFSET);
+ putreg32(LPC43_CCLK / 100 * 50 / frequency, priv->base + LPC43_I2C_SCLL_OFFSET);
+ }
+
+ /* FIXME: This function should return the actual selected frequency */
+
+ return frequency;
+}
+
+/*******************************************************************************
+ * Name: lpc43_i2c_setaddress
+ *
+ * Description:
+ * Set the I2C slave address for a subsequent read/write
+ *
+ *******************************************************************************/
+
+static int i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits)
+{
+ struct lpc43_i2cdev_s *priv = (struct lpc43_i2cdev_s *)dev;
+
+ DEBUGASSERT(dev != NULL);
+ DEBUGASSERT(nbits == 7);
+
+ priv->msg.addr = addr << 1;
+ priv->msg.flags = 0 ;
+
+ return OK;
+}
+
+/*******************************************************************************
+ * Name: lpc43_i2c_write
+ *
+ * Description:
+ * Send a block of data on I2C using the previously selected I2C
+ * frequency and slave address.
+ *
+ *******************************************************************************/
+
+static int i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer,
+ int buflen)
+{
+ struct lpc43_i2cdev_s *priv = (struct lpc43_i2cdev_s *)dev;
+ int ret;
+
+ DEBUGASSERT(dev != NULL);
+
+ priv->wrcnt = 0;
+ priv->rdcnt = 0;
+ priv->msg.addr &= ~0x01;
+ priv->msg.buffer = (uint8_t*)buffer;
+ priv->msg.length = buflen;
+
+ ret = i2c_start(priv);
+
+ return ret > 0 ? OK : -ETIMEDOUT;
+}
+
+/*******************************************************************************
+ * Name: lpc43_i2c_read
+ *
+ * Description:
+ * Receive a block of data on I2C using the previously selected I2C
+ * frequency and slave address.
+ *
+ *******************************************************************************/
+
+static int i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
+{
+ struct lpc43_i2cdev_s *priv = (struct lpc43_i2cdev_s *)dev;
+ int ret;
+
+ DEBUGASSERT(dev != NULL);
+
+ priv->wrcnt=0;
+ priv->rdcnt=0;
+ priv->msg.addr |= 0x01;
+ priv->msg.buffer = buffer;
+ priv->msg.length = buflen;
+
+ ret = i2c_start(priv);
+
+ return ret >0 ? OK : -ETIMEDOUT;
+}
+
+/*******************************************************************************
+ * Name: i2c_start
+ *
+ * Description:
+ * Perform a I2C transfer start
+ *
+ *******************************************************************************/
+
+static int i2c_start(struct lpc43_i2cdev_s *priv)
+{
+ int ret = -1;
+
+ sem_wait(&priv->mutex);
+
+ 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, i2c_timeout, 1, (uint32_t)priv);
+ sem_wait(&priv->wait);
+ wd_cancel(priv->timeout);
+ sem_post(&priv->mutex);
+
+ if (priv-> state == 0x18 || priv->state == 0x28)
+ {
+ ret = priv->wrcnt;
+ }
+ else if (priv-> state == 0x50 || priv->state == 0x58)
+ {
+ ret = priv->rdcnt;
+ }
+
+ return ret;
+}
+
+/*******************************************************************************
+ * Name: i2c_stop
+ *
+ * Description:
+ * Perform a I2C transfer stop
+ *
+ *******************************************************************************/
+
+static void 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: i2c_timeout
+ *
+ * Description:
+ * Watchdog timer for timeout of I2C operation
+ *
+ *******************************************************************************/
+
+static void i2c_timeout(int argc, uint32_t arg, ...)
+{
+ struct lpc43_i2cdev_s *priv = (struct lpc43_i2cdev_s *)arg;
+
+ irqstate_t flags = irqsave();
+ priv->state = 0xff;
+ sem_post(&priv->wait);
+ irqrestore(flags);
+}
+
+/*******************************************************************************
+ * Name: i2c_interrupt
+ *
+ * Description:
+ * The I2C Interrupt Handler
+ *
+ *******************************************************************************/
+
+static int i2c_interrupt(int irq, FAR void *context)
+{
+ struct lpc43_i2cdev_s *priv;
+ uint32_t state;
+
+#ifdef CONFIG_LPC43_I2C0
+ if (irq == LPC43_IRQ_I2C0)
+ {
+ priv = &g_i2c0dev;
+ }
+ else
+#endif
+#ifdef CONFIG_LPC43_I2C1
+ if (irq == LPC43_IRQ_I2C1)
+ {
+ priv = &g_i2c1dev;
+ }
+ else
+#endif
+ {
+ PANIC(OSERR_INTERNAL);
+ }
+
+ /* Reference UM10360 19.10.5 */
+
+ state = getreg32(priv->base+LPC43_I2C_STAT_OFFSET);
+ putreg32(I2C_CONCLR_SIC, priv->base + LPC43_I2C_CONCLR_OFFSET);
+
+ priv->state = state;
+ state &= 0xf8;
+ switch (state)
+ {
+ case 0x00: /* Bus Error */
+ case 0x20:
+ case 0x30:
+ case 0x38:
+ case 0x48:
+ i2c_stop(priv);
+ break;
+
+ case 0x08: /* START */
+ case 0x10: /* Repeated START */
+ putreg32(priv->msg.addr, priv->base + LPC43_I2C_DAT_OFFSET);
+ putreg32(I2C_CONCLR_STAC, priv->base + LPC43_I2C_CONCLR_OFFSET);
+ break;
+
+ case 0x18:
+ priv->wrcnt=0;
+ putreg32(priv->msg.buffer[0], priv->base + LPC43_I2C_DAT_OFFSET);
+ break;
+
+ case 0x28:
+ priv->wrcnt++;
+ if (priv->wrcnt < priv->msg.length)
+ {
+ putreg32(priv->msg.buffer[priv->wrcnt],priv->base+LPC43_I2C_DAT_OFFSET);
+ }
+ else
+ {
+ i2c_stop(priv);
+ }
+ break;
+
+ case 0x40:
+ priv->rdcnt = -1;
+ putreg32(I2C_CONSET_AA, priv->base + LPC43_I2C_CONSET_OFFSET);
+ break;
+
+ case 0x50:
+ priv->rdcnt++;
+ if (priv->rdcnt < priv->msg.length)
+ {
+ priv->msg.buffer[priv->rdcnt]=getreg32(priv->base+LPC43_I2C_BUFR_OFFSET);
+ }
+
+ if (priv->rdcnt >= priv->msg.length - 1)
+ {
+ putreg32(I2C_CONCLR_AAC|I2C_CONCLR_SIC,priv->base+LPC43_I2C_CONCLR_OFFSET);
+ }
+ break;
+
+ case 0x58:
+ i2c_stop(priv);
+ break;
+
+ default:
+ i2c_stop(priv);
+ break;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/*******************************************************************************
+ * Name: up_i2cinitialize
+ *
+ * Description:
+ * Initialise an I2C device
+ *
+ *******************************************************************************/
+
+struct i2c_dev_s *up_i2cinitialize(int port)
+{
+ struct lpc43_i2cdev_s *priv;
+
+ if (port>2)
+ {
+ dbg("lpc I2C Only support 0,1,2\n");
+ return NULL;
+ }
+
+ irqstate_t flags;
+ uint32_t regval;
+
+ flags = irqsave();
+
+#ifdef CONFIG_LPC43_I2C0
+ if (port == 0)
+ {
+ priv = &g_i2c0dev;
+ priv->base = LPC43_I2C0_BASE;
+ priv->irqid = LPC43_IRQ_I2C0;
+
+ regval = getreg32(LPC43_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCI2C0;
+ putreg32(regval, LPC43_SYSCON_PCONP);
+
+ regval = getreg32(LPC43_SYSCON_PCLKSEL0);
+ regval &= ~SYSCON_PCLKSEL0_I2C0_MASK;
+ regval |= (SYSCON_PCLKSEL_CCLK << SYSCON_PCLKSEL0_I2C0_SHIFT);
+ putreg32(regval, LPC43_SYSCON_PCLKSEL0);
+
+ lpc43_configgpio(GPIO_I2C0_SCL);
+ lpc43_configgpio(GPIO_I2C0_SDA);
+
+ putreg32(LPC43_CCLK/CONFIG_I2C0_FREQ/2, priv->base + LPC43_I2C_SCLH_OFFSET);
+ putreg32(LPC43_CCLK/CONFIG_I2C0_FREQ/2, priv->base + LPC43_I2C_SCLL_OFFSET);
+ }
+ else
+#endif
+#ifdef CONFIG_LPC43_I2C1
+ if (port == 1)
+ {
+ priv = &g_i2c1dev;
+ priv->base = LPC43_I2C1_BASE;
+ priv->irqid = LPC43_IRQ_I2C1;
+
+ regval = getreg32(LPC43_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCI2C1;
+ putreg32(regval, LPC43_SYSCON_PCONP);
+
+ regval = getreg32(LPC43_SYSCON_PCLKSEL1);
+ regval &= ~SYSCON_PCLKSEL1_I2C1_MASK;
+ regval |= (SYSCON_PCLKSEL_CCLK << SYSCON_PCLKSEL1_I2C1_SHIFT);
+ putreg32(regval, LPC43_SYSCON_PCLKSEL1);
+
+ lpc43_configgpio(GPIO_I2C1_SCL);
+ lpc43_configgpio(GPIO_I2C1_SDA);
+
+ putreg32(LPC43_CCLK/CONFIG_I2C1_FREQ/2, priv->base + LPC43_I2C_SCLH_OFFSET);
+ putreg32(LPC43_CCLK/CONFIG_I2C1_FREQ/2, priv->base + LPC43_I2C_SCLL_OFFSET);
+ }
+ else
+#endif
+ {
+ return NULL;
+ }
+
+ 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, i2c_interrupt);
+
+ /* Enable Interrupt Handler */
+
+ up_enable_irq(priv->irqid);
+
+ /* Install our operations */
+
+ priv->dev.ops = &lpc43_i2c_ops;
+ return &priv->dev;
+}
+
+/*******************************************************************************
+ * Name: up_i2cuninitalize
+ *
+ * Description:
+ * Uninitialise an I2C device
+ *
+ *******************************************************************************/
+
+int up_i2cuninitialize(FAR struct i2c_dev_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
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_idle.c b/nuttx/arch/arm/src/lpc43xx/lpc43_idle.c
new file mode 100644
index 000000000..72541eed8
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_idle.c
@@ -0,0 +1,187 @@
+/****************************************************************************
+ * arch/arm/src/lpc43/lpc43_idle.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <arch/board/board.h>
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/power/pm.h>
+
+#include <arch/irq.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() up_ledon(LED_IDLE)
+# define END_IDLE() up_ledoff(LED_IDLE)
+#else
+# define BEGIN_IDLE()
+# define END_IDLE()
+#endif
+
+/****************************************************************************
+ * 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();
+
+ /* 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(newstate);
+ if (ret < 0)
+ {
+ /* The new state change failed, revert to the preceding state */
+
+ (void)pm_changestate(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;
+ }
+
+ 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 */
+
+ BEGIN_IDLE();
+ asm("WFI");
+ END_IDLE();
+#endif
+}
+
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_irq.c b/nuttx/arch/arm/src/lpc43xx/lpc43_irq.c
new file mode 100644
index 000000000..9cbb8238c
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_irq.c
@@ -0,0 +1,503 @@
+/****************************************************************************
+ * arch/arm/src/lpc43/lpc43_irq.c
+ * arch/arm/src/chip/lpc43_irq.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "chip.h"
+#include "nvic.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+#include "lpc43_irq.h"
+
+/****************************************************************************
+ * 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)
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/* This is the address of the vector table */
+
+extern unsigned _vectors[];
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lpc43_dumpnvic
+ *
+ * Description:
+ * Dump some interesting NVIC registers
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_IRQ) && defined (CONFIG_DEBUG)
+static void lpc43_dumpnvic(const char *msg, int irq)
+{
+ irqstate_t flags;
+
+ flags = irqsave();
+ slldbg("NVIC (%s, irq=%d):\n", msg, irq);
+ slldbg(" INTCTRL: %08x VECTAB: %08x\n",
+ getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB));
+#if 0
+ slldbg(" 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
+ slldbg(" IRQ ENABLE: %08x %08x\n",
+ getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE));
+ slldbg(" SYSH_PRIO: %08x %08x %08x\n",
+ getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY),
+ getreg32(NVIC_SYSH12_15_PRIORITY));
+ slldbg(" 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));
+ slldbg(" %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));
+ slldbg(" %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));
+ slldbg(" %08x %08x %08x\n",
+ getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY),
+ getreg32(NVIC_IRQ56_59_PRIORITY));
+ irqrestore(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 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 lpc43_nmi(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! NMI received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lpc43_busfault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Bus fault recived\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lpc43_usagefault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Usage fault received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lpc43_pendsv(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! PendSV received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lpc43_dbgmonitor(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Debug Monitor receieved\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int lpc43_reserved(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Reserved interrupt\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+#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, uint32_t *regaddr, uint32_t *bit)
+{
+ 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;
+ *bit = 1 << (irq - LPC43_IRQ_EXTINT);
+ }
+ else if (irq < LPC43M4_IRQ_NIRQS)
+ {
+ *regaddr = NVIC_IRQ32_63_ENABLE;
+ *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);
+
+ /* 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
+
+ /* If the MPU is enabled, then attach and enable the Memory Management
+ * Fault handler.
+ */
+
+#ifdef CONFIG_ARMV7M_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_ARMV7M_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 */
+
+#ifdef CONFIG_DEBUG
+ regval = getreg32(NVIC_DEMCR);
+ regval &= ~NVIC_DEMCR_VCHARDERR;
+ putreg32(regval, NVIC_DEMCR);
+#endif
+
+ /* And finally, enable interrupts */
+
+#ifndef CONFIG_SUPPRESS_INTERRUPTS
+ setbasepri(LPC43M4_SYSH_PRIORITY_MAX);
+ irqrestore(0);
+#endif
+}
+
+/****************************************************************************
+ * Name: up_disable_irq
+ *
+ * Description:
+ * Disable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_disable_irq(int irq)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (lpc43_irqinfo(irq, &regaddr, &bit) == 0)
+ {
+ /* Clear the appropriate bit in the register to enable the interrupt */
+
+ regval = getreg32(regaddr);
+ regval &= ~bit;
+ putreg32(regval, regaddr);
+ }
+#ifdef CONFIG_GPIO_IRQ
+ else if (irq >= LPC43_VALID_FIRST0L)
+ {
+ /* Maybe it is a (derived) GPIO IRQ */
+
+ lpc43_gpioint_disable(irq);
+ }
+#endif
+ lpc43_dumpnvic("disable", irq);
+}
+
+/****************************************************************************
+ * Name: up_enable_irq
+ *
+ * Description:
+ * Enable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_enable_irq(int irq)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (lpc43_irqinfo(irq, &regaddr, &bit) == 0)
+ {
+ /* Set the appropriate bit in the register to enable the interrupt */
+
+ regval = getreg32(regaddr);
+ regval |= bit;
+ putreg32(regval, regaddr);
+ }
+#ifdef CONFIG_GPIO_IRQ
+ else if (irq >= LPC43_VALID_FIRST0L)
+ {
+ /* Maybe it is a (derived) GPIO IRQ */
+
+ lpc43_gpioint_enable(irq);
+ }
+#endif
+ lpc43_dumpnvic("enable", irq);
+}
+
+/****************************************************************************
+ * Name: up_maskack_irq
+ *
+ * Description:
+ * Mask the IRQ and acknowledge it
+ *
+ ****************************************************************************/
+
+void up_maskack_irq(int irq)
+{
+ up_disable_irq(irq);
+
+#if 0 /* Does not appear to be necessary in most cases */
+ lpc43_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 >= LPC43_IRQ_MEMFAULT && irq < NR_IRQS &&
+ (unsigned)priority <= LPC43M4_SYSH_PRIORITY_MIN);
+
+ if (irq < LPC43_IRQ_EXTINT)
+ {
+ irq -= 4;
+ regaddr = NVIC_SYSH_PRIORITY(irq);
+ }
+ else
+ {
+ 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/nuttx/arch/arm/src/lpc43xx/lpc43_irq.h b/nuttx/arch/arm/src/lpc43xx/lpc43_irq.h
new file mode 100644
index 000000000..201081169
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_irq.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_irq.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/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
+
+/****************************************************************************
+ * 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.
+ *
+ ****************************************************************************/
+
+EXTERN void lpc43_clrpend(int irq);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_IRQ_H */
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_pinconfig.c b/nuttx/arch/arm/src/lpc43xx/lpc43_pinconfig.c
new file mode 100644
index 000000000..fb5173339
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <arch/board/board.h>
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#include <errno.h>
+
+#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/nuttx/arch/arm/src/lpc43xx/lpc43_pinconfig.h b/nuttx/arch/arm/src/lpc43xx/lpc43_pinconfig.h
new file mode 100644
index 000000000..293f838e9
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_pinconfig.h
@@ -0,0 +1,278 @@
+/********************************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_pinconfig.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/* 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.
+ *
+ ********************************************************************************************/
+
+EXTERN 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
+EXTERN 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/nuttx/arch/arm/src/lpc43xx/lpc43_rgu.c b/nuttx/arch/arm/src/lpc43xx/lpc43_rgu.c
new file mode 100644
index 000000000..d5ab819dc
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <arch/irq.h>
+#include <nuttx/arch.h>
+
+#include "nvic.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lpc43_rgu.h"
+
+/****************************************************************************
+ * 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 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 = irqsave();
+
+ /* 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 interupts */
+
+ putreg32(0xffffffff, NVIC_IRQ0_31_CLRPEND);
+ putreg32(0xffffffff, NVIC_IRQ32_63_CLRPEND);
+ irqrestore(flags);
+}
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_rgu.h b/nuttx/arch/arm/src/lpc43xx/lpc43_rgu.h
new file mode 100644
index 000000000..364b4d066
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_rgu.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_rgu.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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 the boot logic will call this
+ * function on all restarts.
+ *
+ ****************************************************************************/
+
+EXTERN void lpc43_softreset(void);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_RGU_H */
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_serial.c b/nuttx/arch/arm/src/lpc43xx/lpc43_serial.c
new file mode 100644
index 000000000..6e2e19f35
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_serial.c
@@ -0,0 +1,1460 @@
+/****************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_serial.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#ifdef CONFIG_SERIAL_TERMIOS
+# include <termios.h>
+#endif
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+
+#include <arch/serial.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.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 */
+};
+
+/****************************************************************************
+ * 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 Variables
+ ****************************************************************************/
+
+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,
+ .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,
+};
+
+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,
+};
+
+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,
+};
+
+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,
+};
+
+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_USART2
+# 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_LPC43_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(OSERR_INTERNAL);
+ }
+ 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 = irqsave();
+
+ /* 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 control 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;
+ }
+
+ 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);
+ }
+
+ irqrestore(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 = irqsave();
+
+ /* 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;
+ }
+
+ irqrestore(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)
+ {
+ 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;
+
+#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 = irqsave();
+ up_enablebreaks(priv, true);
+ irqrestore(flags);
+ }
+ break;
+
+ case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
+ {
+ irqstate_t flags;
+ flags = irqsave();
+ up_enablebreaks(priv, false);
+ irqrestore(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 = irqsave();
+ 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);
+ }
+ irqrestore(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.
+ *
+ ****************************************************************************/
+
+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
+}
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/lpc43xx/lpc43_serial.h b/nuttx/arch/arm/src/lpc43xx/lpc43_serial.h
new file mode 100644
index 000000000..f29a99023
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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/nuttx/arch/arm/src/lpc43xx/lpc43_spi.c b/nuttx/arch/arm/src/lpc43xx/lpc43_spi.c
new file mode 100644
index 000000000..52910a4a1
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_spi.c
@@ -0,0 +1,604 @@
+/****************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_spi.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+#include <nuttx/arch.h>
+#include <nuttx/spi.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lpc43_syscon.h"
+#include "lpc43_pinconn.h"
+#include "lpc43_spi.h"
+
+#ifdef CONFIG_LPC43_SPI
+
+/****************************************************************************
+ * 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_PCLKSET_DIV SYSCON_PCLKSEL_CCLK
+#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 */
+#ifndef CONFIG_SPI_OWNBUS
+ 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 */
+#endif
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* SPI methods */
+
+#ifndef CONFIG_SPI_OWNBUS
+static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
+#endif
+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 =
+{
+#ifndef CONFIG_SPI_OWNBUS
+ .lock = spi_lock,
+#endif
+ .select = lpc43_spiselect,
+ .setfrequency = spi_setfrequency,
+ .setmode = spi_setmode,
+ .setbits = spi_setbits,
+ .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
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_OWNBUS
+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;
+}
+#endif
+
+/****************************************************************************
+ * 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);
+#ifndef CONFIG_SPI_OWNBUS
+ if (priv->frequency == frequency)
+ {
+ /* We are already at this frequency. Return the actual. */
+
+ return priv->actual;
+ }
+#endif
+
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->frequency = frequency;
+ priv->actual = actual;
+#endif
+
+ 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? */
+
+#ifndef CONFIG_SPI_OWNBUS
+ if (mode != priv->mode)
+ {
+#endif
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->mode = mode;
+ }
+#endif
+}
+
+/****************************************************************************
+ * 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);
+#ifndef CONFIG_SPI_OWNBUS
+ if (nbits != priv->nbits)
+ {
+#endif
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->nbits = nbits;
+ }
+#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(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--;
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lpc43_spiinitialize
+ *
+ * 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
+ *
+ ****************************************************************************/
+
+FAR struct spi_dev_s *lpc43_spiinitialize(int port)
+{
+ FAR struct lpc43_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 = irqsave();
+ lpc43_configgpio(GPIO_SPI_SCK);
+ lpc43_configgpio(GPIO_SPI_MISO);
+ lpc43_configgpio(GPIO_SPI_MOSI);
+
+ /* Configure clocking */
+
+ regval = getreg32(LPC43_SYSCON_PCLKSEL0);
+ regval &= ~SYSCON_PCLKSEL0_SPI_MASK;
+ regval |= (SPI_PCLKSET_DIV << SYSCON_PCLKSEL0_SPI_SHIFT);
+ putreg32(regval, LPC43_SYSCON_PCLKSEL0);
+
+ /* Enable peripheral clocking to SPI and SPI1 */
+
+ regval = getreg32(LPC43_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCSPI;
+ putreg32(regval, LPC43_SYSCON_PCONP);
+ irqrestore(flags);
+
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->frequency = 0;
+ priv->nbits = 8;
+ priv->mode = SPIDEV_MODE0;
+#endif
+
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ sem_init(&priv->exclsem, 0, 1);
+#endif
+ return &priv->spidev;
+}
+
+#endif /* CONFIG_LPC43_SPI */
+
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_spi.h b/nuttx/arch/arm/src/lpc43xx/lpc43_spi.h
new file mode 100644
index 000000000..28c833826
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_spi.h
@@ -0,0 +1,180 @@
+/************************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_spi.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <nuttx/spi.h>
+#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_sspiinitialize.
+ * 5. The handle returned by lpc43_spiinitialize() 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_spiinitialize
+ *
+ * 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
+ *
+ ************************************************************************************/
+
+EXTERN FAR struct spi_dev_s *lpc43_spiinitialize(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.
+ *
+ ************************************************************************************/
+
+EXTERN void lpc43_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
+ bool selected);
+EXTERN uint8_t lpc43_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+
+#ifdef CONFIG_SPI_CMDDATA
+EXTERN 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
+ *
+ ****************************************************************************/
+
+EXTERN 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 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.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
+EXTERN 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/nuttx/arch/arm/src/lpc43xx/lpc43_spifi.c b/nuttx/arch/arm/src/lpc43xx/lpc43_spifi.c
new file mode 100644
index 000000000..ad6ce0ad5
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_spifi.c
@@ -0,0 +1,1268 @@
+/****************************************************************************
+ * arch/arm/src/lpc43/lpc43_spifi.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/fs/ioctl.h>
+#include <nuttx/mtd.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+
+#include "chip.h"
+#include "lpc43_cgu.h"
+#include "lpc43_spifi.h"
+#include "lpc43_pinconfig.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. NOTE: CONFIG_LPC43_SPIFI=y must also
+ * be defined to enable SPIFI setup support:
+ *
+ * CONFIG_SPIFI_RDONLY - 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) \
+ spifi_init(rom, cshigh, options, mhz)
+# define SPIFI_PROGRAM(priv, rom, src, operands) \
+ spifi_program(rom, src, operands)
+# define SPIFI_ERASE(priv, rom, operands) \
+ spifi_erase(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);
+
+ /* 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;
+ }
+
+ 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);
+
+#if 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 = irqsave();
+
+ /* 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();
+ irqrestore(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 *)kmalloc(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/nuttx/arch/arm/src/lpc43xx/lpc43_spifi.h b/nuttx/arch/arm/src/lpc43xx/lpc43_spifi.h
new file mode 100644
index 000000000..f7cc0d775
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_spifi.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+ * arch/arm/src/lpc43/lpc43_spifi.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <nuttx/mtd.h>
+
+#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/nuttx/arch/arm/src/lpc43xx/lpc43_ssp.c b/nuttx/arch/arm/src/lpc43xx/lpc43_ssp.c
new file mode 100644
index 000000000..4a749825a
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_ssp.c
@@ -0,0 +1,930 @@
+/****************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_ssp.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+#include <nuttx/arch.h>
+#include <nuttx/spi.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+
+#include "lpc43_syscon.h"
+#include "lpc43_pinconn.h"
+#include "lpc43_ssp.h"
+
+#if defined(CONFIG_LPC43_SSP0) || defined(CONFIG_LPC43_SSP1)
+
+/****************************************************************************
+ * 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
+
+/* SSP Clocking.
+ *
+ * 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 LPC43_CCLK > 100000000
+# error "CCLK <= 100,000,000 assumed"
+#endif
+
+#define SSP_PCLKSET_DIV SYSCON_PCLKSEL_CCLK
+#define SSP_CLOCK LPC43_CCLK
+
+/****************************************************************************
+ * 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 */
+#ifdef CONFIG_LPC43_SSP_INTERRUPTS
+ uint8_t sspirq; /* SPI IRQ number */
+#endif
+#ifndef CONFIG_SPI_OWNBUS
+ 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 */
+#endif
+};
+
+/****************************************************************************
+ * 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+static int ssp_lock(FAR struct spi_dev_s *dev, bool lock);
+#endif
+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_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 =
+{
+#ifndef CONFIG_SPI_OWNBUS
+ .lock = ssp_lock,
+#endif
+ .select = lpc43_ssp0select, /* Provided externally */
+ .setfrequency = ssp_setfrequency,
+ .setmode = ssp_setmode,
+ .setbits = ssp_setbits,
+ .status = lpc43_ssp0status, /* Provided externally */
+#ifdef CONFIG_SPI_CMDDATA
+ .cmddata = lpc43_ssp0cmddata, /* Provided externally */
+#endif
+ .send = ssp_send,
+ .sndblock = ssp_sndblock,
+ .recvblock = ssp_recvblock,
+#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,
+#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 =
+{
+#ifndef CONFIG_SPI_OWNBUS
+ .lock = ssp_lock,
+#endif
+ .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,
+ .sndblock = ssp_sndblock,
+ .recvblock = ssp_recvblock,
+#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,
+#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
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_OWNBUS
+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;
+}
+#endif
+
+/****************************************************************************
+ * 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;
+
+ /* Check if the requested frequence is the same as the frequency selection */
+
+ DEBUGASSERT(priv && frequency <= SSP_CLOCK / 2);
+#ifndef CONFIG_SPI_OWNBUS
+ if (priv->frequency == frequency)
+ {
+ /* We are already at this frequency. Return the actual. */
+
+ return priv->actual;
+ }
+#endif
+
+ /* frequency = SSP_CLOCK / divisor, or divisor = SSP_CLOCK / frequency */
+
+ divisor = SSP_CLOCK / 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 = SSP_CLOCK / divisor;
+
+ /* Save the frequency setting */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->frequency = frequency;
+ priv->actual = actual;
+#endif
+
+ 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? */
+
+#ifndef CONFIG_SPI_OWNBUS
+ if (mode != priv->mode)
+ {
+#endif
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->mode = mode;
+ }
+#endif
+}
+
+/****************************************************************************
+ * 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);
+#ifndef CONFIG_SPI_OWNBUS
+ if (nbits != priv->nbits)
+ {
+#endif
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->nbits = nbits;
+ }
+#endif
+}
+
+/****************************************************************************
+ * 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_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 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;
+ } 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, LPC43_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, LPC43_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, LPC43_SSP_SR_OFFSET);
+ if ((sr & SSP_SR_RNE) != 0)
+ {
+ /* Yes.. Read and discard */
+
+ (void)ssp_getreg(priv, LPC43_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, LPC43_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 lpc43_sspdev_s *priv = (FAR struct lpc43_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, LPC43_SSP_SR_OFFSET) & SSP_SR_TNF) &&
+ (rxpending < LPC43_SSP_FIFOSZ) && nwords)
+ {
+ ssp_putreg(priv, LPC43_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, LPC43_SSP_SR_OFFSET) & SSP_SR_RNE)
+ {
+ data = (uint8_t)ssp_getreg(priv, LPC43_SSP_DR_OFFSET);
+ if (priv->nbits > 8)
+ {
+ *u.p16++ = (uint16_t)data;
+ }
+ else
+ {
+ *u.p8++ = (uint8_t)data;
+ }
+ rxpending--;
+ }
+ }
+}
+
+/****************************************************************************
+ * 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;
+
+ /* 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 = irqsave();
+ lpc43_configgpio(GPIO_SSP0_SCK);
+ lpc43_configgpio(GPIO_SSP0_MISO);
+ lpc43_configgpio(GPIO_SSP0_MOSI);
+
+ /* Configure clocking */
+
+ regval = getreg32(LPC43_SYSCON_PCLKSEL1);
+ regval &= ~SYSCON_PCLKSEL1_SSP0_MASK;
+ regval |= (SSP_PCLKSET_DIV << SYSCON_PCLKSEL1_SSP0_SHIFT);
+ putreg32(regval, LPC43_SYSCON_PCLKSEL1);
+
+ /* Enable peripheral clocking to SSP0 */
+
+ regval = getreg32(LPC43_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCSSP0;
+ putreg32(regval, LPC43_SYSCON_PCONP);
+ irqrestore(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;
+
+ /* 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 = irqsave();
+ lpc43_configgpio(GPIO_SSP1_SCK);
+ lpc43_configgpio(GPIO_SSP1_MISO);
+ lpc43_configgpio(GPIO_SSP1_MOSI);
+
+ /* Configure clocking */
+
+ regval = getreg32(LPC43_SYSCON_PCLKSEL0);
+ regval &= ~SYSCON_PCLKSEL0_SSP1_MASK;
+ regval |= (SSP_PCLKSET_DIV << SYSCON_PCLKSEL0_SSP1_SHIFT);
+ putreg32(regval, LPC43_SYSCON_PCLKSEL0);
+
+ /* Enable peripheral clocking to SSP0 and SSP1 */
+
+ regval = getreg32(LPC43_SYSCON_PCONP);
+ regval |= SYSCON_PCONP_PCSSP1;
+ putreg32(regval, LPC43_SYSCON_PCONP);
+ irqrestore(flags);
+
+ return &g_ssp1dev;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lpc43_sspinitialize
+ *
+ * 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_sspinitialize(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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->frequency = 0;
+ priv->nbits = 8;
+ priv->mode = SPIDEV_MODE0;
+#endif
+
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ sem_init(&priv->exclsem, 0, 1);
+#endif
+
+ /* 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/nuttx/arch/arm/src/lpc43xx/lpc43_ssp.h b/nuttx/arch/arm/src/lpc43xx/lpc43_ssp.h
new file mode 100644
index 000000000..cec08e5d0
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_ssp.h
@@ -0,0 +1,197 @@
+/************************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_ssp.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <nuttx/spi.h>
+#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_sspinitialize.
+ * 5. The handle returned by lpc43_sspinitialize() 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_sspinitialize
+ *
+ * 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_sspinitialize(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
+EXTERN void lpc43_ssp0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t lpc43_ssp0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+#ifdef CONFIG_SPI_CMDDATA
+EXTERN int lpc43_ssp0cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+#endif
+#endif
+
+#ifdef CONFIG_LPC43_SSP1
+EXTERN void lpc43_ssp1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t lpc43_ssp1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+#ifdef CONFIG_SPI_CMDDATA
+EXTERN 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)
+EXTERN 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 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.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_LPC43_SSP0
+EXTERN int lpc43_ssp0register(FAR struct spi_dev_s *dev,
+ spi_mediachange_t callback, void *arg);
+#endif
+
+#ifdef CONFIG_LPC43_SSP1
+EXTERN int lpc43_ssp1register(FAR struct spi_dev_s *dev,
+ spi_mediachange_t callback, 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/nuttx/arch/arm/src/lpc43xx/lpc43_start.c b/nuttx/arch/arm/src/lpc43xx/lpc43_start.c
new file mode 100644
index 000000000..88976e03d
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_start.c
@@ -0,0 +1,349 @@
+/****************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_start.c
+ * arch/arm/src/chip/lpc43_start.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/init.h>
+#include <arch/board/board.h>
+
+#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"
+
+/****************************************************************************
+ * Preprocessor 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 the 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_BOOT_CS0FLASH) || defined(CONFIG_BOOT_CS1FLASH) || \
+ defined(CONFIG_BOOT_CS2FLASH) || defined(CONFIG_BOOT_CS3FLASH)
+static inline void lpc43_enabuffering(void)
+{
+ uint32_t regval;
+
+#ifdef CONFIG_BOOT_CS0FLASH
+ regval = getreg32(LPC43_EMC_STATCONFIG0);
+ regval |= EMC_STATCONFIG_BENA
+ putreg32(regval, LPC43_EMC_STATCONFIG0);
+#endif
+
+#ifdef CONFIG_BOOT_CS1FLASH
+ regval = getreg32(LPC43_EMC_STATCONFIG1);
+ regval |= EMC_STATCONFIG_BENA
+ putreg32(regval, LPC43_EMC_STATCONFIG1);
+#endif
+
+#ifdef CONFIG_BOOT_CS2FLASH
+ regval = getreg32(LPC43_EMC_STATCONFIG2);
+ regval |= EMC_STATCONFIG_BENA
+ putreg32(regval, LPC43_EMC_STATCONFIG2);
+#endif
+
+#ifdef CONFIG_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
+#ifdef CONFIG_ARMV7M_CMNVECTOR
+
+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 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 intialized 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');
+
+ /* Initialize onboard resources */
+
+ lpc43_boardinitialize();
+ showprogress('F');
+
+ /* Then start NuttX */
+
+ showprogress('\r');
+ showprogress('\n');
+ os_start();
+
+ /* Shouldn't get here */
+
+ for(;;);
+}
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_timerisr.c b/nuttx/arch/arm/src/lpc43xx/lpc43_timerisr.c
new file mode 100644
index 000000000..83a64e34f
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <time.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "nvic.h"
+#include "clock_internal.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+
+/****************************************************************************
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize
+ * the timer interrupt.
+ *
+ ****************************************************************************/
+
+void up_timerinit(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/nuttx/arch/arm/src/lpc43xx/lpc43_uart.c b/nuttx/arch/arm/src/lpc43xx/lpc43_uart.c
new file mode 100644
index 000000000..4491830f9
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_uart.c
@@ -0,0 +1,600 @@
+/**************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_uart.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#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_uart.h"
+
+/**************************************************************************
+ * Private 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
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * 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. Power: In the PCONP register, set bits PCUSART0/1/2/3.
+ * On reset, USART0 and UART 1 are enabled (PCUSART0 = 1 and PCUART1 = 1)
+ * and USART2/3 are disabled (PCUART1 = 0 and PCUSART3 = 0).
+ * 2. Peripheral clock: In the PCLKSEL0 register, select PCLK_USART0 and
+ * PCLK_UART1; in the PCLKSEL1 register, select PCLK_USART2 and PCLK_USART3.
+ * 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 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 = irqsave();
+
+ 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);
+
+ /* 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
+
+ irqrestore(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 = irqsave();
+
+ 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);
+
+ /* 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
+
+ irqrestore(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 = irqsave();
+
+ 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);
+
+ /* 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
+
+ irqrestore(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 = irqsave();
+
+ 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);
+
+ /* 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
+
+ irqrestore(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/nuttx/arch/arm/src/lpc43xx/lpc43_uart.h b/nuttx/arch/arm/src/lpc43xx/lpc43_uart.h
new file mode 100644
index 000000000..90216ff64
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_uart.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_uart.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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.
+ *
+ ****************************************************************************/
+
+EXTERN 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
+EXTERN void lpc43_usart0_reset(void);
+#endif
+#ifdef CONFIG_LPC43_UART1
+EXTERN void lpc43_uart1_reset(void);
+#endif
+#ifdef CONFIG_LPC43_USART2
+EXTERN void lpc43_usart2_reset(void);
+#endif
+#ifdef CONFIG_LPC43_USART3
+EXTERN 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
+EXTERN void lpc43_usart0_setup(void);
+#endif
+
+#ifdef CONFIG_LPC43_UART1
+EXTERN void lpc43_uart1_setup(void);
+#endif
+
+#ifdef CONFIG_LPC43_USART2
+EXTERN void lpc43_usart2_setup(void);
+#endif
+
+#ifdef CONFIG_LPC43_USART3
+EXTERN 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.
+ *
+ ****************************************************************************/
+
+EXTERN 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/nuttx/arch/arm/src/lpc43xx/lpc43_usb0dev.c b/nuttx/arch/arm/src/lpc43xx/lpc43_usb0dev.c
new file mode 100644
index 000000000..a40d6492d
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_usb0dev.c
@@ -0,0 +1,2671 @@
+/*******************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_usbdev.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Part of the NuttX OS and based, in part, on the LPC31xx USB driver:
+ *
+ * Authors: David Hewson
+ * Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Which, in turn, was based on the LPC2148 USB driver:
+ *
+ * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/usb/usb.h>
+#include <nuttx/usb/usbdev.h>
+#include <nuttx/usb/usbdev_trace.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "lpc43_usb0dev.h"
+
+/*******************************************************************************
+ * 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_SUSPENDCHG 0x0018
+#define LPC43_TRACEINTID_SYNCHFRAME 0x0019
+
+/* 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 (4) /* ep0-3 */
+#define LPC43_NPHYSENDPOINTS (8) /* 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 (0xff) /* All endpoints */
+#define LPC43_EPOUTSET (0x55) /* Even phy endpoint numbers are OUT EPs */
+#define LPC43_EPINSET (0xaa) /* Odd endpoint numbers are IN EPs */
+#define LPC43_EPCTRLSET (0x03) /* EP0 IN/OUT are control endpoints */
+#define LPC43_EPINTRSET (0xa8) /* Interrupt endpoints */
+#define LPC43_EPBULKSET (0xfc) /* Bulk endpoints */
+#define LPC43_EPISOCSET (0xfc) /* 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 */
+
+/* The address of the endpoint control register */
+#define LPC43_USBDEV_ENDPTCTRL(epphy) (LPC43_USBDEV_ENDPTCTRL0 + ((epphy)>>1)*4)
+
+/* 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 0x000f000f
+
+/* 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 */
+ 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
+
+ /* 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_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_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, NULL, 0);
+ }
+
+ 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 */
+
+ lpc43_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL0);
+ 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);
+
+ /* 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;
+
+ /* 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);
+
+ /* Starting a control request - update state */
+ lpc43_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)
+ 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_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;
+ }
+
+ if (disr & USBDEV_USBSTS_SLI)
+ {
+ // FIXME: what do we need to do here...
+ usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_SUSPENDCHG),0);
+ }
+
+ 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));
+ }
+ 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));
+ }
+
+ /* Reset endpoint status */
+ privep->stalled = false;
+
+ /* Enable the endpoint */
+ if (LPC43_EPPHYIN(privep->epphy))
+ lpc43_setbits (USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
+ else
+ lpc43_setbits (USBDEV_ENDPTCTRL_RXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
+
+ 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 = irqsave();
+
+ /* Disable Endpoint */
+ if (LPC43_EPPHYIN(privep->epphy))
+ lpc43_clrbits (USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
+ else
+ lpc43_clrbits (USBDEV_ENDPTCTRL_RXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy));
+
+ privep->stalled = true;
+
+ /* Cancel any ongoing activity */
+ lpc43_cancelrequests(privep, -ESHUTDOWN);
+
+ irqrestore(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 *)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);
+ 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 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
+ 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 = irqsave();
+
+ /* 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);
+ }
+ }
+
+ irqrestore(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;
+ FAR struct lpc43_usbdev_s *priv;
+ irqstate_t flags;
+
+#ifdef CONFIG_DEBUG
+ if (!ep || !req)
+ {
+ usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_INVALIDPARMS), 0);
+ return -EINVAL;
+ }
+#endif
+
+ usbtrace(TRACE_EPCANCEL, privep->epphy);
+ priv = privep->dev;
+
+ flags = irqsave();
+
+ /* 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);
+ irqrestore(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 = irqsave();
+ usbtrace(resume ? TRACE_EPRESUME : TRACE_EPSTALL, privep->epphy);
+
+ uint32_t addr = LPC43_USBDEV_ENDPTCTRL(privep->epphy);
+ 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);
+ }
+
+ irqrestore(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 = irqsave();
+ 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 the IN/OUT endpoint no longer available */
+
+ priv->epavail &= ~(3 << (bit & ~1));
+ irqrestore(flags);
+
+ /* And return the pointer to the standard endpoint structure */
+
+ return &priv->eplist[epndx].ep;
+ }
+ }
+ /* Shouldn't get here */
+ }
+ irqrestore(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 = irqsave();
+ priv->epavail |= (1 << privep->epphy);
+ irqrestore(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 = irqsave();
+ lpc43_setbits(USBDEV_PRTSC1_FPR, LPC43_USBDEV_PORTSC1);
+ irqrestore(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 = irqsave();
+ if (enable)
+ lpc43_setbits (USBDEV_USBCMD_RS, LPC43_USBDEV_USBCMD);
+ else
+ lpc43_clrbits (USBDEV_USBCMD_RS, LPC43_USBDEV_USBCMD);
+ irqrestore(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 lpc43_usbdev_s *priv = &g_usbdev;
+ int i;
+
+ usbtrace(TRACE_DEVINIT, 0);
+
+ /* Disable USB interrupts */
+
+ lpc43_putreg(0, LPC43_USBDEV_USBINTR);
+
+ /* 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;
+
+ /* 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 USB to AHB clock and to Event router*/
+
+ lpc43_enableclock (CLKID_USBOTGAHBCLK);
+ lpc43_enableclock (CLKID_EVENTROUTERPCLK);
+
+ /* Reset USB block */
+
+ lpc43_softreset (RESETID_USBOTGAHBRST);
+
+ /* Enable USB OTG PLL and wait for lock */
+
+ lpc43_putreg (0, LPC43_SYSCREG_USB_ATXPLLPDREG);
+
+ uint32_t bank = EVNTRTR_BANK(EVENTRTR_USBATXPLLLOCK);
+ uint32_t bit = EVNTRTR_BIT(EVENTRTR_USBATXPLLLOCK);
+
+ while (! (lpc43_getreg(LPC43_EVNTRTR_RSR(bank)) & (1 << bit)))
+ ;
+
+ /* Enable USB AHB clock */
+
+ lpc43_enableclock (CLKID_USBOTGAHBCLK);
+
+ /* Reset the controller */
+
+ lpc43_putreg (USBDEV_USBCMD_RST, LPC43_USBDEV_USBCMD);
+ while (lpc43_getreg (LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_RST)
+ ;
+
+ /* Attach USB controller interrupt handler */
+
+ if (irq_attach(LPC43_IRQ_USBOTG, lpc43_usbinterrupt) != 0)
+ {
+ usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_IRQREGISTRATION),
+ (uint16_t)LPC43_IRQ_USBOTG);
+ goto errout;
+ }
+
+
+ /* Program the controller to be the USB device controller */
+
+ lpc43_putreg (USBDEV_USBMODE_SDIS | USBDEV_USBMODE_SLOM | USBDEV_USBMODE_CMDEVICE,
+ LPC43_USBDEV_USBMODE);
+
+ /* Disconnect device */
+
+ lpc43_pullup(&priv->usbdev, false);
+
+ /* Reset/Re-initialize the USB hardware */
+
+ lpc43_usbreset(priv);
+
+ return;
+
+errout:
+ up_usbuninitialize();
+}
+
+/*******************************************************************************
+ * 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 = irqsave();
+ lpc43_pullup(&priv->usbdev, false);
+ priv->usbdev.speed = USB_SPEED_UNKNOWN;
+
+ /* Disable and detach IRQs */
+
+ up_disable_irq(LPC43_IRQ_USBOTG);
+ irq_detach(LPC43_IRQ_USBOTG);
+
+ /* Reset the controller */
+
+ lpc43_putreg (USBDEV_USBCMD_RST, LPC43_USBDEV_USBCMD);
+ while (lpc43_getreg (LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_RST)
+ ;
+
+ /* Turn off USB power and clocking */
+
+ lpc43_disableclock (CLKID_USBOTGAHBCLK);
+ lpc43_disableclock (CLKID_EVENTROUTERPCLK);
+
+
+ irqrestore(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(LPC43_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.
+ */
+
+ 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(LPC43_IRQ_USBOTG);
+
+ /* Unhook the driver */
+
+ g_usbdev.driver = NULL;
+ return OK;
+}
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_usb0dev.h b/nuttx/arch/arm/src/lpc43xx/lpc43_usb0dev.h
new file mode 100644
index 000000000..fae22d323
--- /dev/null
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_usb0dev.h
@@ -0,0 +1,98 @@
+/************************************************************************************
+ * arch/arm/src/lpc43xx/lpc43_usbdev.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <nuttx/usb/usbdev.h>
+#include <stdint.h>
+
+#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.
+ * Alternatively, if no pull-up GPIO the following EXTERN can be redefined to be
+ * NULL.
+ *
+ ************************************************************************************/
+
+EXTERN 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.
+ *
+ ************************************************************************************/
+
+EXTERN 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/nuttx/arch/arm/src/lpc43xx/lpc43_usbram.h b/nuttx/arch/arm/src/lpc43xx/lpc43_usbram.h
new file mode 100644
index 000000000..7f23013e4
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include "chip.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_USBRAM_H */
diff --git a/nuttx/arch/arm/src/sam3u/Kconfig b/nuttx/arch/arm/src/sam3u/Kconfig
new file mode 100644
index 000000000..b84565547
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/Kconfig
@@ -0,0 +1,6 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+comment "AT91SAM3U Configuration Options"
diff --git a/nuttx/arch/arm/src/sam3u/Make.defs b/nuttx/arch/arm/src/sam3u/Make.defs
new file mode 100644
index 000000000..b3bdac72b
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/Make.defs
@@ -0,0 +1,80 @@
+############################################################################
+# arch/arm/src/sam3u/Make.defs
+#
+# Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (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 = sam3u_vectors.S
+
+# Common ARM and Cortex-M3 files
+
+CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
+CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.c up_createstack.c \
+ up_mdelay.c up_udelay.c up_exit.c up_idle.c up_initialize.c \
+ up_initialstate.c up_interruptcontext.c up_memfault.c up_modifyreg8.c \
+ up_modifyreg16.c up_modifyreg32.c up_releasepending.c \
+ up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c \
+ up_sigdeliver.c up_unblocktask.c up_usestack.c up_doirq.c \
+ up_hardfault.c up_svcall.c
+
+# Configuration-dependent common files
+
+ifeq ($(CONFIG_NUTTX_KERNEL),y)
+CHIP_CSRCS += up_mpu.c
+endif
+
+# Required SAM3U files
+
+CHIP_ASRCS =
+CHIP_CSRCS = sam3u_allocateheap.c sam3u_clockconfig.c sam3u_gpioirq.c \
+ sam3u_irq.c sam3u_lowputc.c sam3u_pio.c sam3u_serial.c \
+ sam3u_start.c sam3u_timerisr.c
+
+# Configuration-dependent SAM3U files
+
+ifeq ($(CONFIG_NUTTX_KERNEL),y)
+CHIP_CSRCS += sam3u_userspace.c sam3u_mpuinit.c
+endif
+
+ifeq ($(CONFIG_SAM3U_DMA),y)
+CHIP_CSRCS += sam3u_dmac.c
+endif
+
+ifeq ($(CONFIG_SAM3U_HSMCI),y)
+CHIP_CSRCS += sam3u_hsmci.c
+endif
+
+ifeq ($(CONFIG_SAM3U_SPI),y)
+CHIP_CSRCS += sam3u_spi.c
+endif
diff --git a/nuttx/arch/arm/src/sam3u/chip.h b/nuttx/arch/arm/src/sam3u/chip.h
new file mode 100644
index 000000000..865cad5ea
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/chip.h
@@ -0,0 +1,97 @@
+/************************************************************************************
+ * arch/arm/src/sam3u/chip.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_CHIP_H
+#define __ARCH_ARM_SRC_SAM3U_CHIP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Get customizations for each supported chip */
+
+#ifdef CONFIG_ARCH_CHIP_AT91SAM3U4E
+/* Internal memory */
+
+# define CONFIG_SAM3U_SRAM0_SIZE 0x00008000 /* 32Kb */
+# define CONFIG_SAM3U_SRAM1_SIZE 0x00004000 /* 16Kb */
+# define CONFIG_SAM3U_NFCSRAM_SIZE 0x00001000 /* 4Kb */
+
+/* DMA */
+
+# define CONFIG_SAM3U_NDMACHAN 4 /* 4 DMA Channels */
+
+/* Memory card interface */
+
+# define CONFIG_SAM3U_MCI2 1
+#else
+# error "Unknown SAM3U chip type"
+#endif
+
+/* Include only the memory map. Other chip hardware files should then include this
+ * file for the proper setup
+ */
+
+#include "sam3u_memorymap.h"
+
+/* 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 */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_SAM3U_CHIP_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_adc.h b/nuttx/arch/arm/src/sam3u/sam3u_adc.h
new file mode 100644
index 000000000..4701c0c48
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_adc.h
@@ -0,0 +1,236 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_adc.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_ADC_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_ADC_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* ADC register offsets ****************************************************************/
+
+#define SAM3U_ADC_CR_OFFSET 0x00 /* Control Register (Both) */
+#define SAM3U_ADC_MR_OFFSET 0x04 /* Mode Register (Both) */
+ /* 0x08: Reserved */
+ /* 0x0c: Reserved */
+#define SAM3U_ADC_CHER_OFFSET 0x10 /* Channel Enable Register (Both) */
+#define SAM3U_ADC_CHDR_OFFSET 0x14 /* Channel Disable Register (Both) */
+#define SAM3U_ADC_CHSR_OFFSET 0x18 /* Channel Status Register (Both) */
+#define SAM3U_ADC_SR_OFFSET 0x1c /* Status Register (Both) */
+#define SAM3U_ADC_LCDR_OFFSET 0x20 /* Last Converted Data Register (Both) */
+#define SAM3U_ADC_IER_OFFSET 0x24 /* Interrupt Enable Register (Both) */
+#define SAM3U_ADC_IDR_OFFSET 0x28 /* Interrupt Disable Register (Both) */
+#define SAM3U_ADC_IMR_OFFSET 0x2c /* Interrupt Mask Register (Both) */
+#define SAM3U_ADC_CDR_OFFSET(n) (0x30+((n)<<2))
+#define SAM3U_ADC_CDR0_OFFSET 0x30 /* Channel Data Register 0 (Both) */
+#define SAM3U_ADC_CDR1_OFFSET 0x34 /* Channel Data Register 1 (Both) */
+#define SAM3U_ADC_CDR2_OFFSET 0x38 /* Channel Data Register 2 (Both) */
+#define SAM3U_ADC_CDR3_OFFSET 0x3c /* Channel Data Register 3 (Both) */
+#define SAM3U_ADC_CDR4_OFFSET 0x40 /* Channel Data Register 4 (Both) */
+#define SAM3U_ADC_CDR5_OFFSET 0x44 /* Channel Data Register 5 (Both) */
+#define SAM3U_ADC_CDR6_OFFSET 0x48 /* Channel Data Register 6 (Both) */
+#define SAM3U_ADC_CDR7_OFFSET 0x4c /* Channel Data Register 7 (Both) */
+#define SAM3U_ADC12B_ACR_OFFSET 0x64 /* Analog Control Register (ADC12B only) */
+#define SAM3U_ADC12B_EMR_OFFSET 0x68 /* Extended Mode Register (ADC12B only) */
+
+/* ADC register adresses ***************************************************************/
+
+#define SAM3U_ADC12B_CR (SAM3U_ADC12B_BASE+SAM3U_ADC_CR_OFFSET)
+#define SAM3U_ADC12B_MR (SAM3U_ADC12B_BASE+SAM3U_ADC_MR_OFFSET)
+#define SAM3U_ADC12B_CHER (SAM3U_ADC12B_BASE+SAM3U_ADC_CHER_OFFSET)
+#define SAM3U_ADC12B_CHDR (SAM3U_ADC12B_BASE+SAM3U_ADC_CHDR_OFFSET)
+#define SAM3U_ADC12B_CHSR (SAM3U_ADC12B_BASE+SAM3U_ADC_CHSR_OFFSET)
+#define SAM3U_ADC12B_SR (SAM3U_ADC12B_BASE+SAM3U_ADC_SR_OFFSET)
+#define SAM3U_ADC12B_LCDR_ (SAM3U_ADC12B_BASE+SAM3U_ADC_LCDR_OFFSET)
+#define SAM3U_ADC12B_IER (SAM3U_ADC12B_BASE+SAM3U_ADC_IER_OFFSET)
+#define SAM3U_ADC12B_IDR (SAM3U_ADC12B_BASE+SAM3U_ADC_IDR_OFFSET)
+#define SAM3U_ADC12B_IMR (SAM3U_ADC12B_BASE+SAM3U_ADC_IMR_OFFSET)
+#define SAM3U_ADC12B_CDR(n)) (SAM3U_ADC12B_BASE+SAM3U_ADC_CDR_OFFSET(n))
+#define SAM3U_ADC12B_CDR0 (SAM3U_ADC12B_BASE+SAM3U_ADC_CDR0_OFFSET)
+#define SAM3U_ADC12B_CDR1 (SAM3U_ADC12B_BASE+SAM3U_ADC_CDR1_OFFSET)
+#define SAM3U_ADC12B_CDR2 (SAM3U_ADC12B_BASE+SAM3U_ADC_CDR2_OFFSET)
+#define SAM3U_ADC12B_CDR3 (SAM3U_ADC12B_BASE+SAM3U_ADC_CDR3_OFFSET)
+#define SAM3U_ADC12B_CDR4 (SAM3U_ADC12B_BASE+SAM3U_ADC_CDR4_OFFSET)
+#define SAM3U_ADC12B_CDR5 (SAM3U_ADC12B_BASE+SAM3U_ADC_CDR5_OFFSET)
+#define SAM3U_ADC12B_CDR6 (SAM3U_ADC12B_BASE+SAM3U_ADC_CDR6_OFFSET)
+#define SAM3U_ADC12B_CDR7 (SAM3U_ADC12B_BASE+SAM3U_ADC_CDR7_OFFSET)
+#define SAM3U_ADC12B_ACR (SAM3U_ADC12B_BASE+SAM3U_ADC12B_ACR_OFFSET)
+#define SAM3U_ADC12B_EMR (SAM3U_ADC12B_BASE+SAM3U_ADC12B_EMR_OFFSET)
+
+#define SAM3U_ADC_CR (SAM3U_ADC_BASE+SAM3U_ADC_CR_OFFSET)
+#define SAM3U_ADC_MR (SAM3U_ADC_BASE+SAM3U_ADC_MR_OFFSET)
+#define SAM3U_ADC_CHER (SAM3U_ADC_BASE+SAM3U_ADC_CHER_OFFSET)
+#define SAM3U_ADC_CHDR (SAM3U_ADC_BASE+SAM3U_ADC_CHDR_OFFSET)
+#define SAM3U_ADC_CHSR (SAM3U_ADC_BASE+SAM3U_ADC_CHSR_OFFSET)
+#define SAM3U_ADC_SR (SAM3U_ADC_BASE+SAM3U_ADC_SR_OFFSET)
+#define SAM3U_ADC_LCDR (SAM3U_ADC_BASE+SAM3U_ADC_LCDR_OFFSET)
+#define SAM3U_ADC_IER (SAM3U_ADC_BASE+SAM3U_ADC_IER_OFFSET)
+#define SAM3U_ADC_IDR (SAM3U_ADC_BASE+SAM3U_ADC_IDR_OFFSET)
+#define SAM3U_ADC_IMR (SAM3U_ADC_BASE+SAM3U_ADC_IMR_OFFSET)
+#define SAM3U_ADC_CDR(n)) (SAM3U_ADC_BASE+SAM3U_ADC_CDR_OFFSET(n))
+#define SAM3U_ADC_CDR0 (SAM3U_ADC_BASE+SAM3U_ADC_CDR0_OFFSET)
+#define SAM3U_ADC_CDR1 (SAM3U_ADC_BASE+SAM3U_ADC_CDR1_OFFSET)
+#define SAM3U_ADC_CDR2 (SAM3U_ADC_BASE+SAM3U_ADC_CDR2_OFFSET)
+#define SAM3U_ADC_CDR3 (SAM3U_ADC_BASE+SAM3U_ADC_CDR3_OFFSET)
+#define SAM3U_ADC_CDR4 (SAM3U_ADC_BASE+SAM3U_ADC_CDR4_OFFSET)
+#define SAM3U_ADC_CDR5 (SAM3U_ADC_BASE+SAM3U_ADC_CDR5_OFFSET)
+#define SAM3U_ADC_CDR6 (SAM3U_ADC_BASE+SAM3U_ADC_CDR6_OFFSET)
+#define SAM3U_ADC_CDR7 (SAM3U_ADC_BASE+SAM3U_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_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 ADB12B_MRSTARTUP_SHIFT (16) /* Bits 16-23: Start Up Time (ADC12B) */
+#define ADB12B_MRSTARTUP_MASK (0xff << ADB12B_MRSTARTUP_SHIFT
+#define ADB10B_MRSTARTUP_SHIFT (16) /* Bits 16-22: Start Up Time (ADC10B) */
+#define ADB10B_MRSTARTUP_MASK (0x7f << ADB10B_MRSTARTUP_SHIFT)
+#define ADC_MR_SHTIM_SHIFT (24) /* Bits 24-27: Sample & Hold Time */
+#define ADC_MR_SHTIM_MASK (15 << 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 x Enable */
+#define ADC_CH1 (1 << 1) /* Bit 1: Channel x Enable */
+#define ADC_CH2 (1 << 2) /* Bit 2: Channel x Enable */
+#define ADC_CH3 (1 << 3) /* Bit 3: Channel x Enable */
+#define ADC_CH4 (1 << 4) /* Bit 4: Channel x Enable */
+#define ADC_CH5 (1 << 5) /* Bit 5: Channel x Enable */
+#define ADC_CH6 (1 << 6) /* Bit 6: Channel x Enable */
+#define ADC_CH7 (1 << 7) /* Bit 7: Channel x 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_IBCTL_SHIFT (8) /* Bits 8-9: Bias Current Control */
+#define ADC12B_ACR_IBCTL_MASK (3 << 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)
+
+/* 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 0: 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_SAM3U_SAM3U_ADC_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_allocateheap.c b/nuttx/arch/arm/src/sam3u/sam3u_allocateheap.c
new file mode 100644
index 000000000..1f4b5fdd2
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_allocateheap.c
@@ -0,0 +1,149 @@
+/****************************************************************************
+ * arch/arm/src/common/sam3u_allocateheap.c
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/kmalloc.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+#include "sam3u_internal.h"
+
+/****************************************************************************
+ * Private Definitions
+ ****************************************************************************/
+
+#if CONFIG_MM_REGIONS < 2
+# warning "CONFIG_MM_REGIONS < 2: SRAM1 not included in HEAP"
+#endif
+
+#if CONFIG_MM_REGIONS < 3 && !defined(CONFIG_SAM3U_NAND)
+# warning "CONFIG_MM_REGIONS < 3: NFC SRAM not included in HEAP"
+#endif
+
+#if CONFIG_MM_REGIONS > 2 && defined(CONFIG_SAM3U_NAND)
+# error "CONFIG_MM_REGIONS > 3 but cannot used NFC SRAM"
+# undef CONFIG_MM_REGIONS
+# define CONFIG_MM_REGIONS 2
+#endif
+
+#if CONFIG_DRAM_END > (SAM3U_INTSRAM0_BASE+CONFIG_SAM3U_SRAM0_SIZE)
+# error "CONFIG_DRAM_END is beyond the end of SRAM0"
+# undef CONFIG_DRAM_END
+# define CONFIG_DRAM_END (SAM3U_INTSRAM0_BASE+CONFIG_SAM3U_SRAM0_SIZE)
+#elif CONFIG_DRAM_END < (SAM3U_INTSRAM0_BASE+CONFIG_SAM3U_SRAM0_SIZE)
+# warning "CONFIG_DRAM_END is before end of SRAM0... not all of SRAM0 used"
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_allocate_heap
+ *
+ * Description:
+ * The heap may be statically allocated by
+ * defining CONFIG_HEAP_BASE and CONFIG_HEAP_SIZE. If these
+ * are not defined, then this function will be called to
+ * dynamically set aside the heap region.
+ *
+ ****************************************************************************/
+
+void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
+{
+ size_t size = CONFIG_DRAM_END - g_heapbase;
+
+ /* Return the heap settings */
+
+ up_ledon(LED_HEAPALLOCATE);
+ *heap_start = (FAR void*)g_heapbase;
+ *heap_size = size;
+
+ /* Allow access to the heap memory */
+
+ sam3u_mpuheap((uintptr_t)g_heapbase, size);
+}
+
+/************************************************************************
+ * 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)
+{
+ /* Add the region */
+
+ kmm_addregion((FAR void*)SAM3U_INTSRAM1_BASE, CONFIG_SAM3U_SRAM1_SIZE);
+
+ /* Allow access to the heap memory */
+
+ sam3u_mpuheap(SAM3U_INTSRAM1_BASE, CONFIG_SAM3U_SRAM1_SIZE);
+
+ /* Add the region */
+
+#if CONFIG_MM_REGIONS > 2
+ kmm_addregion((FAR void*)SAM3U_NFCSRAM_BASE, CONFIG_SAM3U_NFCSRAM_SIZE);
+
+ /* Allow access to the heap memory */
+
+ sam3u_mpuheap(SAM3U_NFCSRAM_BASE, CONFIG_SAM3U_NFCSRAM_SIZE);
+#endif
+}
+#endif
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_chipid.h b/nuttx/arch/arm/src/sam3u/sam3u_chipid.h
new file mode 100644
index 000000000..03071d77a
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_chipid.h
@@ -0,0 +1,167 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_chipid.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_CHIPID_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_CHIPID_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* CHIPID register offsets **************************************************************/
+
+#define SAM3U_CHIPID_CIDR 0x00 /* Chip ID Register */
+#define SAM3U_CHIPID_EXID 0x04 /* Chip ID Extension Register */
+
+/* CHIPID register adresses *************************************************************/
+
+#define SAM3U_CHIPID_CIDR (SAM3U_CHIPID_BASE+SAM3U_CHIPID_CIDR)
+#define SAM3U_CHIPID_EXID (SAM3U_CHIPID_BASE+SAM3U_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_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_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_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_SAM3SXB (0x89 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3SxB Series (64-pin version) */
+# define CHIPID_CIDR_ARCH_SAM3SXC (0x8a << CHIPID_CIDR_ARCH_SHIFT) /* SAM3SxC Series (100-pin version) */
+# define CHIPID_CIDR_ARCH_AT91X92 (0x92 << CHIPID_CIDR_ARCH_SHIFT) /* AT91x92 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_SAM3U_SAM3U_CHIPID_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_clockconfig.c b/nuttx/arch/arm/src/sam3u/sam3u_clockconfig.c
new file mode 100644
index 000000000..c9ddba964
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_clockconfig.c
@@ -0,0 +1,335 @@
+/****************************************************************************
+ * arch/arm/src/sam3u/sam3u_clockconfig.c
+ * arch/arm/src/chip/sam3u_clockconfig.c
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "sam3u_internal.h"
+#include "sam3u_pmc.h"
+#include "sam3u_eefc.h"
+#include "sam3u_wdt.h"
+#include "sam3u_supc.h"
+#include "sam3u_matrix.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* PMC register settings based on the board configuration values defined
+ * in board.h
+ */
+
+#define CKGR_MOR_KEY (0x37 << CKGR_MOR_KEY_SHIFT)
+#define SUPR_CR_KEY (0xa5 << SUPC_CR_KEY_SHIFT)
+
+#define BOARD_CKGR_MOR (CKGR_MOR_KEY|BOARD_CKGR_MOR_MOSCXTST|\
+ CKGR_MOR_MOSCRCEN|CKGR_MOR_MOSCXTEN)
+
+#define BOARD_CKGR_PLLAR (CKGR_PLLAR_ONE|BOARD_CKGR_PLLAR_MULA|\
+ BOARD_CKGR_PLLAR_STMODE|BOARD_CKGR_PLLAR_PLLACOUNT|\
+ BOARD_CKGR_PLLAR_DIVA)
+
+#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|CKGR_UCKR_UPLLEN)
+
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam3u_efcsetup
+ *
+ * Description:
+ * Configure 2 waitstates for embedded flash access
+ *
+ ****************************************************************************/
+
+static inline void sam3u_efcsetup(void)
+{
+ putreg32((2 << EEFC_FMR_FWS_SHIFT), SAM3U_EEFC0_FMR);
+ putreg32((2 << EEFC_FMR_FWS_SHIFT), SAM3U_EEFC1_FMR);
+}
+
+/****************************************************************************
+ * Name: sam3u_wdtsetup
+ *
+ * Description:
+ * Disable the watchdog timer
+ *
+ ****************************************************************************/
+
+static inline void sam3u_wdtsetup(void)
+{
+ putreg32(WDT_MR_WDDIS, SAM3U_WDT_MR);
+}
+
+/****************************************************************************
+ * Name: sam3u_supcsetup
+ *
+ * Description:
+ * Select the external slow clock
+ *
+ ****************************************************************************/
+
+static inline void sam3u_supcsetup(void)
+{
+ /* Check if the 32-kHz is already selected */
+
+ if ((getreg32(SAM3U_SUPC_SR) & SUPC_SR_OSCSEL) == 0)
+ {
+ uint32_t delay;
+ putreg32((SUPC_CR_XTALSEL|SUPR_CR_KEY), SAM3U_SUPC_CR);
+ for (delay = 0;
+ (getreg32(SAM3U_SUPC_SR) & SUPC_SR_OSCSEL) == 0 && delay < UINT32_MAX;
+ delay++);
+ }
+}
+
+/****************************************************************************
+ * Name: sam3u_pmcwait
+ *
+ * Description:
+ * Wait for the specide PMC status bit to become "1"
+ *
+ ****************************************************************************/
+
+static void sam3u_pmcwait(uint32_t bit)
+{
+ uint32_t delay;
+ for (delay = 0;
+ (getreg32(SAM3U_PMC_SR) & bit) == 0 && delay < UINT32_MAX;
+ delay++);
+}
+
+/****************************************************************************
+ * Name: sam3u_pmcsetup
+ *
+ * Description:
+ * Initialize clocking
+ *
+ ****************************************************************************/
+
+static inline void sam3u_pmcsetup(void)
+{
+ uint32_t regval;
+
+ /* Enable main oscillator (if it has not already been selected) */
+
+ if ((getreg32(SAM3U_CKGR_MOR) & 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, SAM3U_CKGR_MOR);
+ sam3u_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|CKGR_MOR_MOSCSEL), SAM3U_CKGR_MOR);
+ sam3u_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(SAM3U_PMC_MCKR);
+ regval &= ~PMC_MCKR_CSS_MASK;
+ regval |= PMC_MCKR_CSS_MAIN;
+ putreg32(regval, SAM3U_PMC_MCKR);
+ sam3u_pmcwait(PMC_INT_MCKRDY);
+
+ /* Settup PLLA and wait for LOCKA */
+
+ putreg32(BOARD_CKGR_PLLAR, SAM3U_CKGR_PLLAR);
+ sam3u_pmcwait(PMC_INT_LOCKA);
+
+ /* Setup UTMI for USB and wait for LOCKU */
+
+#ifdef CONFIG_USBDEV
+ regval = getreg32(SAM3U_CKGR_UCKR);
+ regval |= BOARD_CKGR_UCKR;
+ putreg32(regval, SAM3U_CKGR_UCKR);
+ sam3u_pmcwait(PMC_INT_LOCKU);
+#endif
+
+ /* Switch to the fast clock and wait for MCKRDY */
+
+ putreg32(BOARD_PMC_MCKR_FAST, SAM3U_PMC_MCKR);
+ sam3u_pmcwait(PMC_INT_MCKRDY);
+
+ putreg32(BOARD_PMC_MCKR, SAM3U_PMC_MCKR);
+ sam3u_pmcwait(PMC_INT_MCKRDY);
+}
+
+/****************************************************************************
+ * Name: sam3u_enabledefaultmaster and sam3u_disabledefaultmaster
+ *
+ * Description:
+ * Enable/disable default master access
+ *
+ ****************************************************************************/
+
+static inline void sam3u_enabledefaultmaster(void)
+{
+ uint32_t regval;
+
+ /* Set default master: SRAM0 -> Cortex-M3 System */
+
+ regval = getreg32(SAM3U_MATRIX_SCFG0);
+ regval |= (MATRIX_SCFG0_FIXEDDEFMSTR_ARMS|MATRIX_SCFG_DEFMSTRTYPE_FIXED);
+ putreg32(regval, SAM3U_MATRIX_SCFG0);
+
+ /* Set default master: SRAM1 -> Cortex-M3 System */
+
+ regval = getreg32(SAM3U_MATRIX_SCFG1);
+ regval |= (MATRIX_SCFG1_FIXEDDEFMSTR_ARMS|MATRIX_SCFG_DEFMSTRTYPE_FIXED);
+ putreg32(regval, SAM3U_MATRIX_SCFG1);
+
+ /* Set default master: Internal flash0 -> Cortex-M3 Instruction/Data */
+
+ regval = getreg32(SAM3U_MATRIX_SCFG3);
+ regval |= (MATRIX_SCFG3_FIXEDDEFMSTR_ARMC|MATRIX_SCFG_DEFMSTRTYPE_FIXED);
+ putreg32(regval, SAM3U_MATRIX_SCFG3);
+}
+
+#if 0 /* Not used */
+static inline void sam3u_disabledefaultmaster(void)
+{
+ uint32_t regval;
+
+ /* Clear default master: SRAM0 -> Cortex-M3 System */
+
+ regval = getreg32(SAM3U_MATRIX_SCFG0);
+ regval &= ~MATRIX_SCFG_DEFMSTRTYPE_MASK;
+ putreg32(regval, SAM3U_MATRIX_SCFG0);
+
+ /* Clear default master: SRAM1 -> Cortex-M3 System */
+
+ regval = getreg32(SAM3U_MATRIX_SCFG1);
+ regval &= ~MATRIX_SCFG_DEFMSTRTYPE_MASK;
+ putreg32(regval, SAM3U_MATRIX_SCFG1);
+
+ /* Clear default master: Internal flash0 -> Cortex-M3 Instruction/Data */
+
+ regval = getreg32(SAM3U_MATRIX_SCFG3);
+ regval &= ~MATRIX_SCFG_DEFMSTRTYPE_MASK;
+ putreg32(regval, SAM3U_MATRIX_SCFG3);
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/************************************************************************************
+ * Name: sam3u_clockconfig
+ *
+ * Description:
+ * Called to initialize the SAM3U. 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 sam3u is initiallyrunning 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 sam3u_clockconfig(void)
+{
+ /* Configure embedded flash access */
+
+ sam3u_efcsetup();
+
+ /* Configure the watchdog timer */
+
+ sam3u_wdtsetup();
+
+ /* Setup the supply controller to use the external slow clock */
+
+ sam3u_supcsetup();
+
+ /* Initialize clocking */
+
+ sam3u_pmcsetup();
+
+ /* Optimize CPU setting for speed */
+
+ sam3u_enabledefaultmaster();
+}
+
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_dmac.c b/nuttx/arch/arm/src/sam3u/sam3u_dmac.c
new file mode 100644
index 000000000..e3958af74
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_dmac.c
@@ -0,0 +1,1540 @@
+/****************************************************************************
+ * arch/arm/src/sam3u-ek/sam3u_dmac.c
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <semaphore.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "os_internal.h"
+#include "chip.h"
+
+#include "sam3u_internal.h"
+#include "sam3u_pmc.h"
+#include "sam3u_dmac.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+/* Condition out the whole file unless DMA is selected in the configuration */
+
+#ifdef CONFIG_SAM3U_DMA
+
+/* If AT90SAM3U support is enabled, then OS DMA support should also be enabled */
+
+#ifndef CONFIG_ARCH_DMA
+# warning "ATSAM3U DMA enabled but CONFIG_ARCH_DMA disabled"
+#endif
+
+/* Check the number of link list descriptors to allocate */
+
+#ifndef CONFIG_SAM3U_NLLDESC
+# define CONFIG_SAM3U_NLLDESC CONFIG_SAM3U_NDMACHAN
+#endif
+
+#if CONFIG_SAM3U_NLLDESC < CONFIG_SAM3U_NDMACHAN
+# warning "At least CONFIG_SAM3U_NDMACHAN descriptors must be allocated"
+
+# undef CONFIG_SAM3U_NLLDESC
+# define CONFIG_SAM3U_NLLDESC CONFIG_SAM3U_NDMACHAN
+#endif
+
+/* Register values **********************************************************/
+
+#define DMACHAN_CTRLB_BOTHDSCR \
+ (DMACHAN_CTRLB_SRCDSCR | DMACHAN_CTRLB_DSTDSCR)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This structure descibes one DMA channel */
+
+struct sam3u_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_SAM3U_NLLDESC];
+
+/* This array describes the state of each DMA */
+
+static struct sam3u_dma_s g_dma[CONFIG_SAM3U_NDMACHAN] =
+{
+#ifdef CONFIG_ARCH_CHIP_AT91SAM3U4E
+ /* the AT91SAM3U4E has four DMA channels. The FIFOs for channels 0-2 are
+ * 8 bytes in size; channel 3 is 32 bytes.
+ */
+
+#if CONFIG_SAM3U_NDMACHAN != 4
+# error "Logic here assumes CONFIG_SAM3U_NDMACHAN is 4"
+#endif
+
+ {
+ .chan = 0,
+ .flags = DMACH_FLAG_FIFO_8BYTES,
+ .base = SAM3U_DMACHAN0_BASE,
+ },
+ {
+ .chan = 1,
+ .flags = DMACH_FLAG_FIFO_8BYTES,
+ .base = SAM3U_DMACHAN1_BASE,
+ },
+ {
+ .chan = 2,
+ .flags = DMACH_FLAG_FIFO_8BYTES,
+ .base = SAM3U_DMACHAN2_BASE,
+ },
+ {
+ .chan = 3,
+ .flags = (DMACH_FLAG_FIFO_32BYTES | DMACH_FLAG_FLOWCONTROL),
+ .base = SAM3U_DMACHAN3_BASE,
+ }
+#else
+# error "Nothing is known about the DMA channels for this device"
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam3u_takechsem() and sam3u_givechsem()
+ *
+ * Description:
+ * Used to get exclusive access to the DMA channel table
+ *
+ ****************************************************************************/
+
+static void sam3u_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 sam3u_givechsem(void)
+{
+ (void)sem_post(&g_chsem);
+}
+
+/****************************************************************************
+ * Name: sam3u_takedsem() and sam3u_givedsem()
+ *
+ * Description:
+ * Used to wait for availability of descriptors in the descriptor table.
+ *
+ ****************************************************************************/
+
+static void sam3u_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 sam3u_givedsem(void)
+{
+ (void)sem_post(&g_dsem);
+}
+
+/****************************************************************************
+ * Name: sam3u_fifosize
+ *
+ * Description:
+ * Decode the FIFO size from the flags
+ *
+ ****************************************************************************/
+
+static unsigned int sam3u_fifosize(uint8_t dmach_flags)
+{
+ dmach_flags &= DMACH_FLAG_FIFOSIZE_MASK;
+ if (dmach_flags == DMACH_FLAG_FIFO_8BYTES)
+ {
+ return 8;
+ }
+ else /* if (dmach_flags == DMACH_FLAG_FIFO_32BYTES) */
+ {
+ return 32;
+ }
+}
+
+/****************************************************************************
+ * Name: sam3u_flowcontrol
+ *
+ * Description:
+ * Decode the FIFO flow control from the flags
+ *
+ ****************************************************************************/
+
+static inline bool sam3u_flowcontrol(uint8_t dmach_flags)
+{
+ return ((dmach_flags & DMACH_FLAG_FLOWCONTROL) != 0);
+}
+
+/****************************************************************************
+ * Name: sam3u_fifocfg
+ *
+ * Description:
+ * Decode the FIFO config from the flags
+ *
+ ****************************************************************************/
+
+static inline uint32_t sam3u_fifocfg(struct sam3u_dma_s *dmach)
+{
+ unsigned int ndx = (dmach->flags & DMACH_FLAG_FIFOCFG_MASK) >> DMACH_FLAG_FIFOCFG_SHIFT;
+ DEBUGASSERT(ndx < 3);
+ return g_fifocfg[ndx];
+}
+
+/****************************************************************************
+ * Name: sam3u_txcfg
+ *
+ * Description:
+ * Decode the the flags to get the correct CFG register bit settings for
+ * a transmit (memory to peripheral) transfer.
+ *
+ ****************************************************************************/
+
+static inline uint32_t sam3u_txcfg(struct sam3u_dma_s *dmach)
+{
+ uint32_t regval;
+
+ /* Set transfer (memory to peripheral) DMA channel configuration register */
+
+ 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 |= sam3u_fifocfg(dmach);
+ return regval;
+}
+
+/****************************************************************************
+ * Name: sam3u_rxcfg
+ *
+ * Description:
+ * Decode the the flags to get the correct CFG register bit settings for
+ * a receive (peripheral to memory) transfer.
+ *
+ ****************************************************************************/
+
+static inline uint32_t sam3u_rxcfg(struct sam3u_dma_s *dmach)
+{
+ uint32_t regval;
+
+ /* Set received (peripheral to memory) DMA channel config */
+
+ 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 |= sam3u_fifocfg(dmach);
+ return regval;
+}
+
+/****************************************************************************
+ * Name: sam3u_txctrlabits
+ *
+ * Description:
+ * Decode the 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 sam3u_txctrla).
+ *
+ ****************************************************************************/
+
+static inline uint32_t
+sam3u_txctrlabits(struct sam3u_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];
+
+ /* Set the source chuck 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
+
+ /* 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];
+
+ /* Set the destination chuck 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
+
+ return regval;
+}
+
+/****************************************************************************
+ * Name: sam3u_txctrla
+ *
+ * Description:
+ * Or in the variable CTRLA bits
+ *
+ ****************************************************************************/
+
+static inline uint32_t sam3u_txctrla(struct sam3u_dma_s *dmach,
+ uint32_t dmasize, uint32_t txctrlabits)
+{
+ /* 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.
+ */
+
+ /* Adjust the the source transfer size for the source chunk size (memory
+ * chunk size)
+ */
+
+ if ((dmach->flags & DMACH_FLAG_MEMCHUNKSIZE) == DMACH_FLAG_MEMCHUNKSIZE_4)
+ {
+ dmasize >>= 2;
+ }
+
+ DEBUGASSERT(dmasize <= DMACHAN_CTRLA_BTSIZE_MAX);
+ return (txctrlabits & ~DMACHAN_CTRLA_BTSIZE_MASK) | (dmasize << DMACHAN_CTRLA_BTSIZE_SHIFT);
+}
+
+/****************************************************************************
+ * Name: sam3u_rxctrlabits
+ *
+ * Description:
+ * Decode the 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 sam3u_rxctrla).
+ *
+ ****************************************************************************/
+
+static inline uint32_t sam3u_rxctrlabits(struct sam3u_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];
+
+ /* Set the source chuck 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
+
+ /* 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];
+
+ /* Set the destination chuck 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
+
+ return regval;
+}
+
+/****************************************************************************
+ * Name: sam3u_rxctrla
+ *
+ * Description:
+ * 'OR' in the variable CTRLA bits
+ *
+ ****************************************************************************/
+
+static inline uint32_t sam3u_rxctrla(struct sam3u_dma_s *dmach,
+ uint32_t dmasize, uint32_t txctrlabits)
+{
+ /* 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.
+ */
+
+ /* Adjust the the source transfer size for the source chunk size (peripheral
+ * chunk size)
+ */
+
+ if ((dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE) == DMACH_FLAG_PERIPHCHUNKSIZE_4)
+ {
+ dmasize >>= 2;
+ }
+
+ DEBUGASSERT(dmasize <= DMACHAN_CTRLA_BTSIZE_MAX);
+ return (txctrlabits & ~DMACHAN_CTRLA_BTSIZE_MASK) | (dmasize << DMACHAN_CTRLA_BTSIZE_SHIFT);
+}
+
+/****************************************************************************
+ * Name: sam3u_txctrlb
+ *
+ * Description:
+ * Decode the the flags to get the correct CTRLB register bit settings for
+ * a transmit (memory to peripheral) transfer.
+ *
+ ****************************************************************************/
+
+static inline uint32_t sam3u_txctrlb(struct sam3u_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: sam3u_rxctrlb
+ *
+ * Description:
+ * Decode the the flags to get the correct CTRLB register bit settings for
+ * a receive (peripheral to memory) transfer.
+ *
+ ****************************************************************************/
+
+static inline uint32_t sam3u_rxctrlb(struct sam3u_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: sam3u_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 *
+sam3u_allocdesc(struct sam3u_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.
+ */
+
+ sam3u_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.
+ */
+
+ sam3u_takechsem();
+ for (i = 0; i < CONFIG_SAM3U_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.
+ */
+
+ sam3u_givechsem();
+ DEBUGASSERT(desc != NULL);
+ }
+ return desc;
+}
+
+/****************************************************************************
+ * Name: sam3u_freelinklist
+ *
+ * Description:
+ * Free all descriptors in the DMA channel's link list.
+ *
+ * NOTE: Called from the DMA interrupt handler.
+ *
+ ****************************************************************************/
+
+static void sam3u_freelinklist(struct sam3u_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));
+ sam3u_givedsem();
+ desc = next;
+ }
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_txbuffer(struct sam3u_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 = sam3u_txctrlabits(dmach);
+ ctrlb = sam3u_txctrlb(dmach);
+ }
+ ctrla = sam3u_txctrla(dmach, regval, nbytes);
+
+ /* Add the new link list entry */
+
+ if (!sam3u_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 = sam3u_txcfg(dmach);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_rxbuffer(struct sam3u_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 = sam3u_rxctrlabits(dmach);
+ ctrlb = sam3u_rxctrlb(dmach);
+ }
+ ctrla = sam3u_rxctrla(dmach, regval, nbytes);
+
+ /* Add the new link list entry */
+
+ if (!sam3u_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 = sam3u_rxcfg(dmach);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: sam3u_single
+ *
+ * Description:
+ * Start a single buffer DMA.
+ *
+ ****************************************************************************/
+
+static inline int sam3u_single(struct sam3u_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.
+ */
+
+ (void)getreg32(SAM3U_DMAC_EBCISR);
+
+ /* Write the starting source address in the SADDR register */
+
+ DEBUGASSERT(llhead != NULL && llhead->src != 0);
+ putreg32(llhead->src, dmach->base + SAM3U_DMACHAN_SADDR_OFFSET);
+
+ /* Write the starting destination address in the DADDR register */
+
+ putreg32(llhead->dest, dmach->base + SAM3U_DMACHAN_DADDR_OFFSET);
+
+ /* Set up the CTRLA register */
+
+ putreg32(llhead->ctrla, dmach->base + SAM3U_DMACHAN_CTRLA_OFFSET);
+
+ /* Set up the CTRLB register */
+
+ putreg32(llhead->ctrlb, dmach->base + SAM3U_DMACHAN_CTRLA_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 + SAM3U_DMACHAN_CFG_OFFSET);
+
+ /* Enable the channel by writing a ‘1’ to the CHER enable bit */
+
+ putreg32(DMAC_CHER_ENA(dmach->chan), SAM3U_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), SAM3U_DMAC_EBCIER);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: sam3u_multiple
+ *
+ * Description:
+ * Start a multiple buffer DMA.
+ *
+ ****************************************************************************/
+
+static inline int sam3u_multiple(struct sam3u_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
+ */
+
+ (void)getreg32(SAM3U_DMAC_EBCISR);
+
+ /* Set up the initial CTRLB register (to enable descriptors) */
+
+ putreg32(llhead->ctrlb, dmach->base + SAM3U_DMACHAN_CTRLA_OFFSET);
+
+ /* Set up the CTRLB register */
+
+ putreg32(llhead->ctrlb, dmach->base + SAM3U_DMACHAN_CTRLA_OFFSET);
+
+ /* Write the channel configuration information into the CFG register */
+
+ putreg32(dmach->cfg, dmach->base + SAM3U_DMACHAN_CFG_OFFSET);
+
+ /* Program the DSCR register with the pointer to the firstlink list entry. */
+
+ putreg32((uint32_t)llhead, dmach->base + SAM3U_DMACHAN_DSCR_OFFSET);
+
+ /* Finally, enable the channel by writing a ‘1’ to the CHER enable */
+
+ putreg32(DMAC_CHER_ENA(dmach->chan), SAM3U_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 tranfer.
+ *
+ * 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), SAM3U_DMAC_EBCIER);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: sam3u_dmasterminate
+ *
+ * Description:
+ * Terminate the DMA transfer and disable the DMA channel
+ *
+ ****************************************************************************/
+
+static void sam3u_dmaterminate(struct sam3u_dma_s *dmach, int result)
+{
+ /* Disable all channel interrupts */
+
+ putreg32(DMAC_EBC_CHANINTS(dmach->chan), SAM3U_DMAC_EBCIDR);
+
+ /* Disable the channel by writing one to the write-only channel disable register */
+
+ putreg32(DMAC_CHDR_DIS(dmach->chan), SAM3U_DMAC_CHDR);
+
+ /* Free the linklist */
+
+ sam3u_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: sam3u_dmainterrupt
+ *
+ * Description:
+ * DMA interrupt handler
+ *
+ ****************************************************************************/
+
+static int sam3u_dmainterrupt(int irq, void *context)
+{
+ struct sam3u_dma_s *dmach;
+ unsigned int chndx;
+ uint32_t regval;
+
+ /* Get the DMAC status register value. Ignore all masked interrupt
+ * status bits.
+ */
+
+ regval = getreg32(SAM3U_DMAC_EBCISR) & getreg32(SAM3U_DMAC_EBCIMR);
+
+ /* Check if the any transfer has completed */
+
+ if (regval & DMAC_EBC_BTC_MASK)
+ {
+ /* Yes.. Check each bit to see which channel has interrupted */
+
+ for (chndx = 0; chndx < CONFIG_SAM3U_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? */
+
+ sam3u_dmaterminate(dmach, -EIO);
+ }
+
+ /* Is the transfer complete? */
+
+ else if ((regval & DMAC_EBC_CBTC(chndx)) != 0)
+ {
+ /* Yes.. Terminate the transfer with success */
+
+ sam3u_dmaterminate(dmach, OK);
+ }
+
+ /* Otherwise, this must be a Bufffer Transfer Complete (BTC)
+ * interrupt as part of a multiple buffer transfer.
+ */
+
+ else /* f ((regval & DMAC_EBC_BTC(chndx)) != 0) */
+ {
+ /* Write the KEEPON field to clear the STALL states */
+
+ putreg32(DMAC_CHER_KEEP(dmach->chan), SAM3U_DMAC_CHER);
+ }
+ }
+ }
+ }
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam3u_dmainitialize
+ *
+ * Description:
+ * Initialize the DMA subsystem
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void weak_function up_dmainitialize(void)
+{
+ /* Enable peripheral clock */
+
+ putreg32((1 << SAM3U_PID_DMAC), SAM3U_PMC_PCER);
+
+ /* Disable all DMA interrupts */
+
+ putreg32(DMAC_EBC_ALLINTS, SAM3U_DMAC_EBCIDR);
+
+ /* Disable all DMA channels */
+
+ putreg32(DMAC_CHDR_DIS_ALL, SAM3U_DMAC_CHDR);
+
+ /* Attach DMA interrupt vector */
+
+ (void)irq_attach(SAM3U_IRQ_DMAC, sam3u_dmainterrupt);
+
+ /* Enable the IRQ at the NVIC (still disabled at the DMA controller) */
+
+ up_enable_irq(SAM3U_IRQ_DMAC);
+
+ /* Enable the DMA controller */
+
+ putreg32(DMAC_EN_ENABLE, SAM3U_DMAC_EN);
+
+ /* Initialize semaphores */
+
+ sem_init(&g_chsem, 0, 1);
+ sem_init(&g_dsem, 0, CONFIG_SAM3U_NDMACHAN);
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_dmachannel(uint32_t dmach_flags)
+{
+ struct sam3u_dma_s *dmach;
+ unsigned int chndx;
+
+ /* Get the search parameters */
+
+ bool flowcontrol = sam3u_flowcontrol(dmach_flags);
+ unsigned int fifosize = sam3u_fifosize(dmach_flags);
+
+ /* Search for an available DMA channel with at least the requested FIFO
+ * size.
+ */
+
+ dmach = NULL;
+ sam3u_takechsem();
+ for (chndx = 0; chndx < CONFIG_SAM3U_NDMACHAN; chndx++)
+ {
+ struct sam3u_dma_s *candidate = &g_dma[chndx];
+ if (!candidate->inuse &&
+ (sam3u_fifosize(candidate->flags) >= fifosize) &&
+ (!flowcontrol || sam3u_flowcontrol(dmach_flags)))
+ {
+ dmach = candidate;
+ dmach->inuse = true;
+
+ /* Read the status register to clear any pending interrupts on the
+ * channel
+ */
+
+ (void)getreg32(SAM3U_DMAC_EBCISR);
+
+ /* Disable the channel by writing one to the write-only channel
+ * disable register
+ */
+
+ putreg32(DMAC_CHDR_DIS(chndx), SAM3U_DMAC_CHDR);
+
+ /* See the DMA channel flags, retaining the fifo size and flow
+ * control settings which are inherent properties of the FIFO
+ * and cannot be changed.
+ */
+
+ dmach->flags &= (DMACH_FLAG_FLOWCONTROL | DMACH_FLAG_FIFOSIZE_MASK);
+ dmach->flags |= (dmach_flags & ~((DMACH_FLAG_FLOWCONTROL | DMACH_FLAG_FIFOSIZE_MASK)));
+ break;
+ }
+ }
+ sam3u_givechsem();
+ return (DMA_HANDLE)dmach;
+}
+
+/****************************************************************************
+ * Name: sam3u_dmafree
+ *
+ * Description:
+ * Release a DMA channel. NOTE: The 'handle' used in this argument must
+ * NEVER be used again until sam3u_dmachannel() is called again to re-gain
+ * a valid handle.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void sam3u_dmafree(DMA_HANDLE handle)
+{
+ struct sam3u_dma_s *dmach = (struct sam3u_dma_s *)handle;
+
+ /* Mark the channel no longer in use. Clearing the inuse flag is an atomic
+ * operation and so should be safe.
+ */
+
+ DEBUGASSERT((dmach != NULL) && (dmach->inuse));
+ dmach->flags &= (DMACH_FLAG_FLOWCONTROL | DMACH_FLAG_FIFOSIZE_MASK);
+ dmach->inuse = false; /* No longer in use */
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_dmatxsetup() and sam3u_dmarxsetup()
+ * must not be intermixed on the same transfer, however.
+ *
+ ****************************************************************************/
+
+int sam3u_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes)
+{
+ struct sam3u_dma_s *dmach = (struct sam3u_dma_s *)handle;
+ int ret = OK;
+
+ DEBUGASSERT(dmach && dmach->llhead != NULL && dmach->lltail != 0);
+
+ /* If this is a large transfer, break it up into smaller buffers */
+
+ while (nbytes > DMACHAN_CTRLA_BTSIZE_MAX)
+ {
+ /* Set up the maximum size transfer */
+
+ ret = sam3u_txbuffer(dmach, paddr, maddr, DMACHAN_CTRLA_BTSIZE_MAX);
+ if (ret == OK);
+ {
+ /* Decrement the number of bytes left to transfer */
+
+ nbytes -= DMACHAN_CTRLA_BTSIZE_MAX;
+
+ /* Increment the memory & peripheral address (if it is appropriate to
+ * do do).
+ */
+
+ if ((dmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0)
+ {
+ paddr += DMACHAN_CTRLA_BTSIZE_MAX;
+ }
+
+ if ((dmach->flags & DMACH_FLAG_MEMINCREMENT) != 0)
+ {
+ maddr += DMACHAN_CTRLA_BTSIZE_MAX;
+ }
+ }
+ }
+
+ /* Then set up the final buffer transfer */
+
+ if (ret == OK && nbytes > 0)
+ {
+ ret = sam3u_txbuffer(dmach, paddr, maddr, nbytes);
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_dmatxsetup() and sam3u_dmarxsetup()
+ * must not be intermixed on the same transfer, however.
+ *
+ ****************************************************************************/
+
+int sam3u_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes)
+{
+ struct sam3u_dma_s *dmach = (struct sam3u_dma_s *)handle;
+ int ret = OK;
+
+ DEBUGASSERT(dmach && dmach->llhead != NULL && dmach->lltail != 0);
+
+ /* If this is a large transfer, break it up into smaller buffers */
+
+ while (nbytes > DMACHAN_CTRLA_BTSIZE_MAX)
+ {
+ /* Set up the maximum size transfer */
+
+ ret = sam3u_rxbuffer(dmach, paddr, maddr, DMACHAN_CTRLA_BTSIZE_MAX);
+ if (ret == OK);
+ {
+ /* Decrement the number of bytes left to transfer */
+
+ nbytes -= DMACHAN_CTRLA_BTSIZE_MAX;
+
+ /* Increment the memory & peripheral address (if it is appropriate to
+ * do do).
+ */
+
+ if ((dmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0)
+ {
+ paddr += DMACHAN_CTRLA_BTSIZE_MAX;
+ }
+
+ if ((dmach->flags & DMACH_FLAG_MEMINCREMENT) != 0)
+ {
+ maddr += DMACHAN_CTRLA_BTSIZE_MAX;
+ }
+ }
+ }
+
+ /* Then set up the final buffer transfer */
+
+ if (ret == OK && nbytes > 0)
+ {
+ ret = sam3u_rxbuffer(dmach, paddr, maddr, nbytes);
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * Name: sam3u_dmastart
+ *
+ * Description:
+ * Start the DMA transfer
+ *
+ ****************************************************************************/
+
+int sam3u_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
+{
+ struct sam3u_dma_s *dmach = (struct sam3u_dma_s *)handle;
+ int ret = -EINVAL;
+
+ /* Verify that the DMA has been setup (i.e., at least one entry in the
+ * link list).
+ */
+
+ DEBUGASSERT(dmach != NULL);
+ 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 tranfer? */
+
+ if (dmach->llhead == dmach->lltail)
+ {
+ ret = sam3u_single(dmach);
+ }
+ else
+ {
+ ret = sam3u_multiple(dmach);
+ }
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * Name: sam3u_dmastop
+ *
+ * Description:
+ * Cancel the DMA. After sam3u_dmastop() is called, the DMA channel is
+ * reset and sam3u_dmasetup() must be called before sam3u_dmastart() can be
+ * called again
+ *
+ ****************************************************************************/
+
+void sam3u_dmastop(DMA_HANDLE handle)
+{
+ struct sam3u_dma_s *dmach = (struct sam3u_dma_s *)handle;
+ irqstate_t flags;
+
+ DEBUGASSERT(dmach != NULL);
+ flags = irqsave();
+ sam3u_dmaterminate(dmach, -EINTR);
+ irqrestore(flags);
+}
+
+/****************************************************************************
+ * Name: sam3u_dmasample
+ *
+ * Description:
+ * Sample DMA register contents
+ *
+ * Assumptions:
+ * - DMA handle allocated by sam3u_dmachannel()
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_DMA
+void sam3u_dmasample(DMA_HANDLE handle, struct sam3u_dmaregs_s *regs)
+{
+ struct sam3u_dma_s *dmach = (struct sam3u_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 = irqsave();
+ regs->gcfg = getreg32(SAM3U_DMAC_GCFG);
+ regs->en = getreg32(SAM3U_DMAC_EN);
+ regs->sreq = getreg32(SAM3U_DMAC_SREQ);
+ regs->creq = getreg32(SAM3U_DMAC_CREQ);
+ regs->last = getreg32(SAM3U_DMAC_LAST);
+ regs->ebcimr = getreg32(SAM3U_DMAC_EBCIMR);
+ regs->ebcisr = getreg32(SAM3U_DMAC_EBCISR);
+ regs->chsr = getreg32(SAM3U_DMAC_CHSR);
+
+ /* Sample channel registers */
+
+ regs->saddr = getreg32(dmach->base + SAM3U_DMACHAN_SADDR_OFFSET);
+ regs->daddr = getreg32(dmach->base + SAM3U_DMACHAN_DADDR_OFFSET);
+ regs->dscr = getreg32(dmach->base + SAM3U_DMACHAN_DSCR_OFFSET);
+ regs->ctrla = getreg32(dmach->base + SAM3U_DMACHAN_CTRLA_OFFSET);
+ regs->ctrlb = getreg32(dmach->base + SAM3U_DMACHAN_CTRLB_OFFSET);
+ regs->cfg = getreg32(dmach->base + SAM3U_DMACHAN_CFG_OFFSET);
+ irqrestore(flags);
+}
+#endif /* CONFIG_DEBUG_DMA */
+
+/****************************************************************************
+ * Name: sam3u_dmadump
+ *
+ * Description:
+ * Dump previously sampled DMA register contents
+ *
+ * Assumptions:
+ * - DMA handle allocated by sam3u_dmachannel()
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_DMA
+void sam3u_dmadump(DMA_HANDLE handle, const struct sam3u_dmaregs_s *regs,
+ const char *msg)
+{
+ struct sam3u_dma_s *dmach = (struct sam3u_dma_s *)handle;
+
+ dmadbg("%s\n", msg);
+ dmadbg(" DMA Global Registers:\n");
+ dmadbg(" GCFG[%08x]: %08x\n", SAM3U_DMAC_GCFG, regs->gcfg);
+ dmadbg(" EN[%08x]: %08x\n", SAM3U_DMAC_EN, regs->en);
+ dmadbg(" SREQ[%08x]: %08x\n", SAM3U_DMAC_SREQ, regs->sreq);
+ dmadbg(" CREQ[%08x]: %08x\n", SAM3U_DMAC_CREQ, regs->creq);
+ dmadbg(" LAST[%08x]: %08x\n", SAM3U_DMAC_LAST, regs->last);
+ dmadbg(" EBCIMR[%08x]: %08x\n", SAM3U_DMAC_EBCIMR, regs->ebcimr);
+ dmadbg(" EBCISR[%08x]: %08x\n", SAM3U_DMAC_EBCISR, regs->ebcisr);
+ dmadbg(" CHSR[%08x]: %08x\n", SAM3U_DMAC_CHSR, regs->chsr);
+ dmadbg(" DMA Channel Registers:\n");
+ dmadbg(" SADDR[%08x]: %08x\n", dmach->base + SAM3U_DMACHAN_SADDR_OFFSET, regs->saddr);
+ dmadbg(" DADDR[%08x]: %08x\n", dmach->base + SAM3U_DMACHAN_DADDR_OFFSET, regs->daddr);
+ dmadbg(" DSCR[%08x]: %08x\n", dmach->base + SAM3U_DMACHAN_DSCR_OFFSET, regs->dscr);
+ dmadbg(" CTRLA[%08x]: %08x\n", dmach->base + SAM3U_DMACHAN_CTRLA_OFFSET, regs->ctrla);
+ dmadbg(" CTRLB[%08x]: %08x\n", dmach->base + SAM3U_DMACHAN_CTRLB_OFFSET, regs->ctrlb);
+ dmadbg(" CFG[%08x]: %08x\n", dmach->base + SAM3U_DMACHAN_CFG_OFFSET, regs->cfg);
+}
+#endif /* CONFIG_DEBUG_DMA */
+#endif /* CONFIG_SAM3U_DMA */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_dmac.h b/nuttx/arch/arm/src/sam3u/sam3u_dmac.h
new file mode 100644
index 000000000..9edf61df7
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_dmac.h
@@ -0,0 +1,441 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_dmac.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_DMAC_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_DMAC_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* DMAC register offsets ****************************************************************/
+
+/* Global Registers */
+
+#define SAM3U_DMAC_GCFG_OFFSET 0x00 /* DMAC Global Configuration Register */
+#define SAM3U_DMAC_EN_OFFSET 0x04 /* DMAC Enable Register */
+#define SAM3U_DMAC_SREQ_OFFSET 0x08 /* DMAC Software Single Request Register */
+#define SAM3U_DMAC_CREQ_OFFSET 0x0c /* DMAC Software Chunk Transfer Request Register */
+#define SAM3U_DMAC_LAST_OFFSET 0x10 /* DMAC Software Last Transfer Flag Register */
+ /* 0x014-0x18: Reserved */
+#define SAM3U_DMAC_EBCIER_OFFSET 0x18 /* DMAC Error Enable */
+#define SAM3U_DMAC_EBCIDR_OFFSET 0x1C /* DMAC Error Disable */
+#define SAM3U_DMAC_EBCIMR_OFFSET 0x20 /* DMAC Error Mask */
+#define SAM3U_DMAC_EBCISR_OFFSET 0x24 /* DMAC Error Status */
+#define SAM3U_DMAC_CHER_OFFSET 0x28 /* DMAC Channel Handler Enable Register */
+#define SAM3U_DMAC_CHDR_OFFSET 0x2c /* DMAC Channel Handler Disable Register */
+#define SAM3U_DMAC_CHSR_OFFSET 0x30 /* DMAC Channel Handler Status Register */
+ /* 0x034-0x38: Reserved */
+/* DMA channel registers */
+
+#define SAM3U_DMACHAN_OFFSET(n) (0x3c+((n)*0x28))
+#define SAM3U_DMACHAN0_OFFSET 0x3c /* 0x3c-0x60: Channel 0 */
+#define SAM3U_DMACHAN1_OFFSET 0x64 /* 0x64-0x88: Channel 1 */
+#define SAM3U_DMACHAN2_OFFSET 0x8c /* 0x8c-0xb0: Channel 2 */
+#define SAM3U_DMACHAN3_OFFSET 0xb4 /* 0xb4-0xd8: Channel 3 */
+
+#define SAM3U_DMACHAN_SADDR_OFFSET 0x00 /* DMAC Channel Source Address Register */
+#define SAM3U_DMACHAN_DADDR_OFFSET 0x04 /* DMAC Channel Destination Address Register */
+#define SAM3U_DMACHAN_DSCR_OFFSET 0x08 /* DMAC Channel Descriptor Address Register */
+#define SAM3U_DMACHAN_CTRLA_OFFSET 0x0c /* DMAC Channel Control A Register */
+#define SAM3U_DMACHAN_CTRLB_OFFSET 0x10 /* DMAC Channel Control B Register */
+#define SAM3U_DMACHAN_CFG_OFFSET 0x14 /* DMAC Channel Configuration Register */
+ /* 0x18-0x24: Reserved */
+
+ /* 0x017c-0x1fc: Reserved */
+
+/* DMAC register adresses ***************************************************************/
+
+/* Global Registers */
+
+#define SAM3U_DMAC_GCFG (SAM3U_DMAC_BASE+SAM3U_DMAC_GCFG_OFFSET)
+#define SAM3U_DMAC_EN (SAM3U_DMAC_BASE+SAM3U_DMAC_EN_OFFSET)
+#define SAM3U_DMAC_SREQ (SAM3U_DMAC_BASE+SAM3U_DMAC_SREQ_OFFSET)
+#define SAM3U_DMAC_CREQ (SAM3U_DMAC_BASE+SAM3U_DMAC_CREQ_OFFSET)
+#define SAM3U_DMAC_LAST (SAM3U_DMAC_BASE+SAM3U_DMAC_LAST_OFFSET)
+#define SAM3U_DMAC_EBCIER (SAM3U_DMAC_BASE+SAM3U_DMAC_EBCIER_OFFSET)
+#define SAM3U_DMAC_EBCIDR (SAM3U_DMAC_BASE+SAM3U_DMAC_EBCIDR_OFFSET)
+#define SAM3U_DMAC_EBCIMR (SAM3U_DMAC_BASE+SAM3U_DMAC_EBCIMR_OFFSET)
+#define SAM3U_DMAC_EBCISR (SAM3U_DMAC_BASE+SAM3U_DMAC_EBCISR_OFFSET)
+#define SAM3U_DMAC_CHER (SAM3U_DMAC_BASE+SAM3U_DMAC_CHER_OFFSET)
+#define SAM3U_DMAC_CHDR (SAM3U_DMAC_BASE+SAM3U_DMAC_CHDR_OFFSET)
+#define SAM3U_DMAC_CHSR (SAM3U_DMAC_BASE+SAM3U_DMAC_CHSR_OFFSET)
+
+/* DMA channel registers */
+
+#define SAM3U_DMACHAN_BASE(n) (SAM3U_DMAC_BASE+SAM3U_DMACHAN_OFFSET(n))
+#define SAM3U_DMACHAN0_BASE (SAM3U_DMAC_BASE+SAM3U_DMACHAN0_OFFSET)
+#define SAM3U_DMACHAN1_BASE (SAM3U_DMAC_BASE+SAM3U_DMACHAN1_OFFSET)
+#define SAM3U_DMACHAN2_BASE (SAM3U_DMAC_BASE+SAM3U_DMACHAN2_OFFSET)
+#define SAM3U_DMACHAN3_BASE (SAM3U_DMAC_BASE+SAM3U_DMACHAN3_OFFSET)
+
+#define SAM3U_DMACHAN_SADDR(n) (SAM3U_DMACHAN_BASE(n)+SAM3U_DMACHAN_SADDR_OFFSET)
+#define SAM3U_DMACHAN_DADDR(n) (SAM3U_DMACHAN_BASE(n)+SAM3U_DMACHAN_DADDR_OFFSET)
+#define SAM3U_DMACHAN_DSCR(n) (SAM3U_DMACHAN_BASE(n)+SAM3U_DMACHAN_DSCR_OFFSET)
+#define SAM3U_DMACHAN_CTRLA(n) (SAM3U_DMACHAN_BASE(n)+SAM3U_DMACHAN_CTRLA_OFFSET)
+#define SAM3U_DMACHAN_CTRLB(n) (SAM3U_DMACHAN_BASE(n)+SAM3U_DMACHAN_CTRLB_OFFSET)
+#define SAM3U_DMACHAN_CFG(n) (SAM3U_DMACHAN_BASE(n)+SAM3U_DMACHAN_CFG_OFFSET)
+
+#define SAM3U_DMACHAN0_SADDR (SAM3U_DMACHAN0_BASE+SAM3U_DMACHAN_SADDR_OFFSET)
+#define SAM3U_DMACHAN0_DADDR (SAM3U_DMACHAN0_BASE+SAM3U_DMACHAN_DADDR_OFFSET)
+#define SAM3U_DMACHAN0_DSCR (SAM3U_DMACHAN0_BASE+SAM3U_DMACHAN_DSCR_OFFSET)
+#define SAM3U_DMACHAN0_CTRLA (SAM3U_DMACHAN0_BASE+SAM3U_DMACHAN_CTRLA_OFFSET)
+#define SAM3U_DMACHAN0_CTRLB (SAM3U_DMACHAN0_BASE+SAM3U_DMACHAN_CTRLB_OFFSET)
+#define SAM3U_DMACHAN0_CFG (SAM3U_DMACHAN0_BASE+SAM3U_DMACHAN_CFG_OFFSET)
+
+#define SAM3U_DMACHAN1_SADDR (SAM3U_DMACHAN1_BASE+SAM3U_DMACHAN_SADDR_OFFSET)
+#define SAM3U_DMACHAN1_DADDR (SAM3U_DMACHAN1_BASE+SAM3U_DMACHAN_DADDR_OFFSET)
+#define SAM3U_DMACHAN1_DSCR (SAM3U_DMACHAN1_BASE+SAM3U_DMACHAN_DSCR_OFFSET)
+#define SAM3U_DMACHAN1_CTRLA (SAM3U_DMACHAN1_BASE+SAM3U_DMACHAN_CTRLA_OFFSET)
+#define SAM3U_DMACHAN1_CTRLB (SAM3U_DMACHAN1_BASE+SAM3U_DMACHAN_CTRLB_OFFSET)
+#define SAM3U_DMACHAN1_CFG (SAM3U_DMACHAN1_BASE+SAM3U_DMACHAN_CFG_OFFSET)
+
+#define SAM3U_DMACHAN2_SADDR (SAM3U_DMACHAN2_BASE+SAM3U_DMACHAN_SADDR_OFFSET)
+#define SAM3U_DMACHAN2_DADDR (SAM3U_DMACHAN2_BASE+SAM3U_DMACHAN_DADDR_OFFSET)
+#define SAM3U_DMACHAN2_DSCR (SAM3U_DMACHAN2_BASE+SAM3U_DMACHAN_DSCR_OFFSET)
+#define SAM3U_DMACHAN2_CTRLA (SAM3U_DMACHAN2_BASE+SAM3U_DMACHAN_CTRLA_OFFSET)
+#define SAM3U_DMACHAN2_CTRLB (SAM3U_DMACHAN2_BASE+SAM3U_DMACHAN_CTRLB_OFFSET)
+#define SAM3U_DMACHAN2_CFG (SAM3U_DMACHAN2_BASE+SAM3U_DMACHAN_CFG_OFFSET)
+
+#define SAM3U_DMACHAN3_SADDR (SAM3U_DMACHAN3_BASE+SAM3U_DMACHAN_SADDR_OFFSET)
+#define SAM3U_DMACHAN3_DADDR (SAM3U_DMACHAN3_BASE+SAM3U_DMACHAN_DADDR_OFFSET)
+#define SAM3U_DMACHAN3_DSCR (SAM3U_DMACHAN3_BASE+SAM3U_DMACHAN_DSCR_OFFSET)
+#define SAM3U_DMACHAN3_CTRLA (SAM3U_DMACHAN3_BASE+SAM3U_DMACHAN_CTRLA_OFFSET)
+#define SAM3U_DMACHAN3_CTRLB (SAM3U_DMACHAN3_BASE+SAM3U_DMACHAN_CTRLB_OFFSET)
+#define SAM3U_DMACHAN3_CFG (SAM3U_DMACHAN3_BASE+SAM3U_DMACHAN_CFG_OFFSET)
+
+/* 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] Control A Register */
+
+#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_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
+#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 */
+# 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 */
+# 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_AHBPRO_SHIFT (24) /* Bits 24-26: Bus access privilege */
+#define DMACHAN_CFG_AHBPRO_MASK (7 << DMACHAN_CFG_AHBPRO_SHIFT)
+# define DMACHAN_CFG_AHBPRO_PRIV (1 << DMACHAN_CFG_AHBPRO_SHIFT)
+# define DMACHAN_CFG_AHBPRO_BUFF (2 << DMACHAN_CFG_AHBPRO_SHIFT)
+# define DMACHAN_CFG_AHBPRO_CACHE (4 << DMACHAN_CFG_AHBPRO_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 */
+
+/* DMA Peripheral IDs *******************************************************************/
+
+#define DMACHAN_PID_MCI0 0
+#define DMACHAN_PID_SSC 3
+#define DMACHAN_PID_MCI1 13
+
+/****************************************************************************************
+ * 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_SAM3U_SAM3U_DMAC_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_eefc.h b/nuttx/arch/arm/src/sam3u/sam3u_eefc.h
new file mode 100644
index 000000000..d32c6670b
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_eefc.h
@@ -0,0 +1,120 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_eefc.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_EEFC_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_EEFC_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* EEFC register offsets ****************************************************************/
+
+#define SAM3U_EEFC_FMR_OFFSET 0x00 /* EEFC Flash Mode Register */
+#define SAM3U_EEFC_FCR_OFFSET 0x04 /* EEFC Flash Command Register */
+#define SAM3U_EEFC_FSR_OFFSET 0x08 /* EEFC Flash Status Register */
+#define SAM3U_EEFC_FRR_OFFSET 0x0c /* EEFC Flash Result Register */
+
+/* EEFC register adresses ***************************************************************/
+
+#define SAM3U_EEFC_FMR(n) (SAM3U_EEFCN_BASE(n)+SAM3U_EEFC_FMR_OFFSET)
+#define SAM3U_EEFC_FCR(n) (SAM3U_EEFCN_BASE(n)+SAM3U_EEFC_FCR_OFFSET)
+#define SAM3U_EEFC_FSR(n) (SAM3U_EEFCN_BASE(n)+SAM3U_EEFC_FSR_OFFSET)
+#define SAM3U_EEFC_FRR(n) (SAM3U_EEFCN_BASE(n)+SAM3U_EEFC_FRR_OFFSET)
+
+#define SAM3U_EEFC0_FMR (SAM3U_EEFC0_BASE+SAM3U_EEFC_FMR_OFFSET)
+#define SAM3U_EEFC0_FCR (SAM3U_EEFC0_BASE+SAM3U_EEFC_FCR_OFFSET)
+#define SAM3U_EEFC0_FSR (SAM3U_EEFC0_BASE+SAM3U_EEFC_FSR_OFFSET)
+#define SAM3U_EEFC0_FRR (SAM3U_EEFC0_BASE+SAM3U_EEFC_FRR_OFFSET)
+
+#define SAM3U_EEFC1_FMR (SAM3U_EEFC1_BASE+SAM3U_EEFC_FMR_OFFSET)
+#define SAM3U_EEFC1_FCR (SAM3U_EEFC1_BASE+SAM3U_EEFC_FCR_OFFSET)
+#define SAM3U_EEFC1_FSR (SAM3U_EEFC1_BASE+SAM3U_EEFC_FSR_OFFSET)
+#define SAM3U_EEFC1_FRR (SAM3U_EEFC1_BASE+SAM3U_EEFC_FRR_OFFSET)
+
+/* EEFC register bit definitions ********************************************************/
+
+#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_FAM (1 << 24) /* Bit 24: Flash Access Mode */
+
+#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 */
+# 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_FARG_SHIFT (8) /* Bits 8-23: Flash Command Argument */
+#define EEFC_FCR_FARG_MASK (0xffff << 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_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 */
+
+/****************************************************************************************
+ * Public Types
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Data
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Functions
+ ****************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_SAM3U_SAM3U_EEFC_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_gpbr.h b/nuttx/arch/arm/src/sam3u/sam3u_gpbr.h
new file mode 100644
index 000000000..7e9853180
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_gpbr.h
@@ -0,0 +1,90 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_gpbr.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_GPBR_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_GPBR_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* GPBR register offsets ****************************************************************/
+
+#define SAM3U_GPBR_OFFSET(n) ((n)<<2) /* General purpose back-up registers */
+#define SAM3U_GPBR0_OFFSET 0x00
+#define SAM3U_GPBR1_OFFSET 0x04
+#define SAM3U_GPBR2_OFFSET 0x08
+#define SAM3U_GPBR3_OFFSET 0x0c
+#define SAM3U_GPBR4_OFFSET 0x10
+#define SAM3U_GPBR5_OFFSET 0x14
+#define SAM3U_GPBR6_OFFSET 0x18
+#define SAM3U_GPBR7_OFFSET 0x1c
+
+/* GPBR register adresses ***************************************************************/
+
+#define SAM3U_GPBR(n)) (SAM3U_GPBR_BASE+SAM3U_GPBR_OFFSET(n))
+#define SAM3U_GPBR0 (SAM3U_GPBR_BASE+SAM3U_GPBR0_OFFSET)
+#define SAM3U_GPBR1 (SAM3U_GPBR_BASE+SAM3U_GPBR1_OFFSET)
+#define SAM3U_GPBR2 (SAM3U_GPBR_BASE+SAM3U_GPBR2_OFFSET)
+#define SAM3U_GPBR3 (SAM3U_GPBR_BASE+SAM3U_GPBR3_OFFSET)
+#define SAM3U_GPBR4 (SAM3U_GPBR_BASE+SAM3U_GPBR4_OFFSET)
+#define SAM3U_GPBR5 (SAM3U_GPBR_BASE+SAM3U_GPBR5_OFFSET)
+#define SAM3U_GPBR6 (SAM3U_GPBR_BASE+SAM3U_GPBR6_OFFSET)
+#define SAM3U_GPBR7 (SAM3U_GPBR_BASE+SAM3U_GPBR7_OFFSET)
+
+/* GPBR register bit definitions ********************************************************/
+
+/****************************************************************************************
+ * Public Types
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Data
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Functions
+ ****************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_SAM3U_SAM3U_GPBR_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_gpioirq.c b/nuttx/arch/arm/src/sam3u/sam3u_gpioirq.c
new file mode 100644
index 000000000..dc01374a9
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_gpioirq.c
@@ -0,0 +1,367 @@
+/****************************************************************************
+ * arch/arm/src/sam3u/sam3u_gpioirq.c
+ * arch/arm/src/chip/sam3u_gpioirq.c
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/init.h>
+#include <nuttx/arch.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "sam3u_internal.h"
+#include "sam3u_pio.h"
+#include "sam3u_pmc.h"
+
+#ifdef CONFIG_GPIO_IRQ
+
+/****************************************************************************
+ * Private Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam3u_gpiobase
+ *
+ * Description:
+ * Return the base address of the GPIO register set
+ *
+ ****************************************************************************/
+
+static inline uint32_t sam3u_gpiobase(uint16_t pinset)
+{
+ int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ return SAM3U_PION_BASE(port >> GPIO_PORT_SHIFT);
+}
+
+/****************************************************************************
+ * Name: sam3u_gpiopin
+ *
+ * Description:
+ * Returun the base address of the GPIO register set
+ *
+ ****************************************************************************/
+
+static inline int sam3u_gpiopin(uint16_t pinset)
+{
+ return 1 << ((pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT);
+}
+
+/****************************************************************************
+ * Name: sam3u_irqbase
+ *
+ * Description:
+ * Return gpio information associated with this IRQ
+ *
+ ****************************************************************************/
+
+static int sam3u_irqbase(int irq, uint32_t *base, int *pin)
+{
+ if (irq >= SAM3U_IRQ_NIRQS)
+ {
+#ifdef CONFIG_GPIOA_IRQ
+ if (irq <= SAM3U_IRQ_PA31)
+ {
+ *base = SAM3U_PIOA_BASE;
+ *pin = irq - SAM3U_IRQ_PA0;
+ return OK;
+ }
+#endif
+#ifdef CONFIG_GPIOB_IRQ
+ if (irq <= SAM3U_IRQ_PB31)
+ {
+ *base = SAM3U_PIOB_BASE;
+ *pin = irq - SAM3U_IRQ_PB0;
+ return OK;
+ }
+#endif
+#ifdef CONFIG_GPIOC_IRQ
+ if (irq <= SAM3U_IRQ_PC31)
+ {
+ *base = SAM3U_PIOC_BASE;
+ *pin = irq - SAM3U_IRQ_PC0;
+ return OK;
+ }
+#endif
+ }
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: up_gpioa/b/cinterrupt
+ *
+ * Description:
+ * Receive GPIOA/B/C interrupts
+ *
+ ****************************************************************************/
+
+static int up_gpiointerrupt(uint32_t base, int irq0, void *context)
+{
+ uint32_t pending;
+ uint32_t bit;
+ int irq;
+
+ pending = getreg32(base+SAM3U_PIO_ISR_OFFSET) & getreg32(base+SAM3U_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_GPIOA_IRQ
+static int up_gpioainterrupt(int irq, void *context)
+{
+ return up_gpiointerrupt(SAM3U_PIOA_BASE, SAM3U_IRQ_PA0, context);
+}
+#endif
+
+#ifdef CONFIG_GPIOB_IRQ
+static int up_gpiobinterrupt(int irq, void *context)
+{
+ return up_gpiointerrupt(SAM3U_PIOB_BASE, SAM3U_IRQ_PB0, context);
+}
+#endif
+
+#ifdef CONFIG_GPIOC_IRQ
+static int up_gpiocinterrupt(int irq, void *context)
+{
+ return up_gpiointerrupt(SAM3U_PIOC_BASE, SAM3U_IRQ_PC0, context);
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam3u_gpioirqinitialize
+ *
+ * Description:
+ * Initialize logic to support a second level of interrupt decoding for
+ * GPIO pins.
+ *
+ ****************************************************************************/
+
+void sam3u_gpioirqinitialize(void)
+{
+ uint32_t pcer;
+
+ /* Configure GPIOA interrupts */
+
+#ifdef CONFIG_GPIOA_IRQ
+ /* Enable GPIOA clocking */
+
+ pcer |= (1 << SAM3U_PID_PIOA);
+ putreg32(pcer, SAM3U_PMC_PCER);
+
+ /* Clear and disable all GPIOA interrupts */
+
+ (void)getreg32(SAM3U_PIOA_ISR);
+ putreg32(0xffffffff, SAM3U_PIOA_IDR);
+
+ /* Attach and enable the GPIOA IRQ */
+
+ (void)irq_attach(SAM3U_IRQ_PIOA, up_gpioainterrupt);
+ up_enable_irq(SAM3U_IRQ_PIOA);
+#endif
+
+ /* Configure GPIOB interrupts */
+
+#ifdef CONFIG_GPIOB_IRQ
+ /* Enable GPIOB clocking */
+
+ pcer |= (1 << SAM3U_PID_PIOB);
+ putreg32(pcer, SAM3U_PMC_PCER);
+
+ /* Clear and disable all GPIOB interrupts */
+
+ (void)getreg32(SAM3U_PIOB_ISR);
+ putreg32(0xffffffff, SAM3U_PIOB_IDR);
+
+ /* Attach and enable the GPIOB IRQ */
+
+ (void)irq_attach(SAM3U_IRQ_PIOB, up_gpiobinterrupt);
+ up_enable_irq(SAM3U_IRQ_PIOB);
+#endif
+
+ /* Configure GPIOC interrupts */
+
+#ifdef CONFIG_GPIOC_IRQ
+ /* Enable GPIOC clocking */
+
+ pcer |= (1 << SAM3U_PID_PIOC);
+ putreg32(pcer, SAM3U_PMC_PCER);
+
+ /* Clear and disable all GPIOC interrupts */
+
+ (void)getreg32(SAM3U_PIOC_ISR);
+ putreg32(0xffffffff, SAM3U_PIOC_IDR);
+
+ /* Attach and enable the GPIOC IRQ */
+
+ (void)irq_attach(SAM3U_IRQ_PIOC, up_gpioainterrupt);
+ up_enable_irq(SAM3U_IRQ_PIOC);
+#endif
+}
+
+/************************************************************************************
+ * Name: sam3u_gpioirq
+ *
+ * Description:
+ * Configure an interrupt for the specified GPIO pin.
+ *
+ ************************************************************************************/
+
+void sam3u_gpioirq(uint16_t pinset)
+{
+ uint32_t base = sam3u_gpiobase(pinset);
+ int pin = sam3u_gpiopin(pinset);
+
+ /* Are any additional interrupt modes selected? */
+
+ if ((pinset & GPIO_INT_MASK) != 0)
+ {
+ /* Yes.. Enable additional interrupt mode */
+
+ putreg32(pin, base+SAM3U_PIO_AIMER_OFFSET);
+
+ /* Level or edge detected interrupt? */
+
+ if ((pinset & GPIO_INT_LEVEL) != 0)
+ {
+ putreg32(pin, base+SAM3U_PIO_LSR_OFFSET); /* Level */
+ }
+ else
+ {
+ putreg32(pin, base+SAM3U_PIO_ESR_OFFSET); /* Edge */
+ }
+
+ /* High level/rising edge or low level /falling edge? */
+
+ if ((pinset & GPIO_INT_HIGHLEVEL) != 0)
+ {
+ putreg32(pin, base+SAM3U_PIO_REHLSR_OFFSET); /* High level/Rising edge */
+ }
+ else
+ {
+ putreg32(pin, base+SAM3U_PIO_FELLSR_OFFSET); /* Low level/Falling edge */
+ }
+ }
+ else
+ {
+ /* No.. Disable additional interrupt mode */
+
+ putreg32(pin, base+SAM3U_PIO_AIMDR_OFFSET);
+ }
+}
+
+/************************************************************************************
+ * Name: sam3u_gpioirqenable
+ *
+ * Description:
+ * Enable the interrupt for specified GPIO IRQ
+ *
+ ************************************************************************************/
+
+void sam3u_gpioirqenable(int irq)
+{
+ uint32_t base;
+ int pin;
+
+ if (sam3u_irqbase(irq, &base, &pin) == OK)
+ {
+ /* Clear (all) pending interrupts and enable this pin interrupt */
+
+ (void)getreg32(base+SAM3U_PIO_ISR_OFFSET);
+ putreg32((1 << pin), base+SAM3U_PIO_IER_OFFSET);
+ }
+}
+
+/************************************************************************************
+ * Name: sam3u_gpioirqdisable
+ *
+ * Description:
+ * Disable the interrupt for specified GPIO IRQ
+ *
+ ************************************************************************************/
+
+void sam3u_gpioirqdisable(int irq)
+{
+ uint32_t base;
+ int pin;
+
+ if (sam3u_irqbase(irq, &base, &pin) == OK)
+ {
+ /* Disable this pin interrupt */
+
+ putreg32((1 << pin), base+SAM3U_PIO_IDR_OFFSET);
+ }
+}
+
+#endif /* CONFIG_GPIO_IRQ */ \ No newline at end of file
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_hsmci.c b/nuttx/arch/arm/src/sam3u/sam3u_hsmci.c
new file mode 100644
index 000000000..9d7c308ca
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_hsmci.c
@@ -0,0 +1,2503 @@
+/****************************************************************************
+ * arch/arm/src/sam3u/sam3u_sdio.c
+ *
+ * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+#include <wdog.h>
+#include <errno.h>
+
+#include <nuttx/clock.h>
+#include <nuttx/arch.h>
+#include <nuttx/sdio.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/mmcsd.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+
+#include "sam3u_internal.h"
+#include "sam3u_dmac.h"
+#include "sam3u_pmc.h"
+#include "sam3u_hsmci.h"
+
+#if CONFIG_SAM3U_HSMCI
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_SAM3U_DMA
+# warning "HSMCI driver requires CONFIG_SAM3U_DMA"
+#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
+
+#ifndef CONFIG_HSMCI_PRI
+# define CONFIG_HSMCI_PRI NVIC_SYSH_PRIORITY_DEFAULT
+#endif
+
+#if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG_VERBOSE)
+# undef CONFIG_HSMCI_CMDDEBUG
+# undef CONFIG_HSMCI_XFRDEBUG
+#endif
+
+#ifdef CONFIG_SAM3U_HSMCI_RDPROOF
+# ifdef CONFIG_SAM3U_HSMCI_WRPROOF
+# define HSMCU_PROOF_BITS (HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF)
+# else
+# define HSMCU_PROOF_BITS HSMCI_MR_RDPROOF
+# endif
+#else
+# ifdef CONFIG_SAM3U_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)
+
+/* DMA configuration flags */
+
+#define DMA_FLAGS \
+ (DMACH_FLAG_FIFO_8BYTES | DMACH_FLAG_FIFOCFG_LARGEST | \
+ (DMACHAN_PID_MCI0 << 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)
+
+/* 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_DMARECV_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_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 */ )
+
+/* 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_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_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 SAM3U HSMCI interface */
+
+struct sam3u_dev_s
+{
+ struct sdio_dev_s dev; /* Standard, base SDIO interface */
+
+ /* SAM3U-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 */
+
+ /* 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 */
+ DMA_HANDLE dma; /* Handle for DMA channel */
+};
+
+/* Register logging support */
+
+#if defined(CONFIG_HSMCI_XFRDEBUG) || defined(CONFIG_HSMCI_CMDDEBUG)
+struct sam3u_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_HSMCI_XFRDEBUG
+struct sam3u_xfrregs_s
+{
+ struct sam3u_hsmciregs_s hsmci;
+#ifdef CONFIG_DEBUG_DMA
+ struct sam3u_dmaregs_s dma;
+#endif
+};
+#endif
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Low-level helpers ********************************************************/
+
+static void sam3u_takesem(struct sam3u_dev_s *priv);
+#define sam3u_givesem(priv) (sem_post(&priv->waitsem))
+static void sam3u_enablewaitints(struct sam3u_dev_s *priv, uint32_t waitmask,
+ sdio_eventset_t waitevents);
+static void sam3u_disablewaitints(struct sam3u_dev_s *priv, sdio_eventset_t wkupevents);
+static void sam3u_enablexfrints(struct sam3u_dev_s *priv, uint32_t xfrmask);
+static void sam3u_disablexfrints(struct sam3u_dev_s *priv);
+static inline void sam3u_disable(void);
+static inline void sam3u_enable(void);
+
+/* Register Sampling ********************************************************/
+
+#if defined(CONFIG_HSMCI_XFRDEBUG) || defined(CONFIG_HSMCI_CMDDEBUG)
+static void sam3u_hsmcisample(struct sam3u_hsmciregs_s *regs);
+static void sam3u_hsmcidump(struct sam3u_hsmciregs_s *regs, const char *msg);
+#endif
+
+#ifdef CONFIG_HSMCI_XFRDEBUG
+static void sam3u_xfrsampleinit(void);
+static void sam3u_xfrsample(struct sam3u_dev_s *priv, int index);
+static void sam3u_xfrdumpone(struct sam3u_dev_s *priv,
+ struct sam3u_xfrregs_s *regs, const char *msg);
+static void sam3u_xfrdump(struct sam3u_dev_s *priv);
+#else
+# define sam3u_xfrsampleinit()
+# define sam3u_xfrsample(priv,index)
+# define sam3u_xfrdump(priv)
+#endif
+
+#ifdef CONFIG_HSMCI_CMDDEBUG
+static void sam3u_cmdsampleinit(void);
+static inline void sam3u_cmdsample1(int index3);
+static inline void sam3u_cmdsample2(int index, uint32_t sr);
+static void sam3u_cmddump(void);
+#else
+# define sam3u_cmdsampleinit()
+# define sam3u_cmdsample1(index)
+# define sam3u_cmdsample2(index,sr)
+# define sam3u_cmddump()
+#endif
+
+/* DMA Helpers **************************************************************/
+
+static void sam3u_dmacallback(DMA_HANDLE handle, void *arg, int result);
+
+/* Data Transfer Helpers ****************************************************/
+
+static void sam3u_eventtimeout(int argc, uint32_t arg);
+static void sam3u_endwait(struct sam3u_dev_s *priv, sdio_eventset_t wkupevent);
+static void sam3u_endtransfer(struct sam3u_dev_s *priv, sdio_eventset_t wkupevent);
+static void sam3u_notransfer(struct sam3u_dev_s *priv);
+
+/* Interrupt Handling *******************************************************/
+
+static int sam3u_interrupt(int irq, void *context);
+
+/* SDIO interface methods ***************************************************/
+
+/* Initialization/setup */
+
+static void sam3u_reset(FAR struct sdio_dev_s *dev);
+static uint8_t sam3u_status(FAR struct sdio_dev_s *dev);
+static void sam3u_widebus(FAR struct sdio_dev_s *dev, bool enable);
+static void sam3u_clock(FAR struct sdio_dev_s *dev,
+ enum sdio_clock_e rate);
+static int sam3u_attach(FAR struct sdio_dev_s *dev);
+
+/* Command/Status/Data Transfer */
+
+static int sam3u_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
+ uint32_t arg);
+static void sam3u_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen,
+ unsigned int nblocks);
+static int sam3u_cancel(FAR struct sdio_dev_s *dev);
+static int sam3u_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd);
+static int sam3u_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd,
+ uint32_t *rshort);
+static int sam3u_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd,
+ uint32_t rlong[4]);
+static int sam3u_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd,
+ uint32_t *rnotimpl);
+
+/* EVENT handler */
+
+static void sam3u_waitenable(FAR struct sdio_dev_s *dev,
+ sdio_eventset_t eventset);
+static sdio_eventset_t
+ sam3u_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout);
+static void sam3u_callbackenable(FAR struct sdio_dev_s *dev,
+ sdio_eventset_t eventset);
+static int sam3u_registercallback(FAR struct sdio_dev_s *dev,
+ worker_t callback, void *arg);
+
+/* DMA */
+
+#ifdef CONFIG_SDIO_DMA
+static bool sam3u_dmasupported(FAR struct sdio_dev_s *dev);
+#endif
+static int sam3u_dmarecvsetup(FAR struct sdio_dev_s *dev,
+ FAR uint8_t *buffer, size_t buflen);
+static int sam3u_dmasendsetup(FAR struct sdio_dev_s *dev,
+ FAR const uint8_t *buffer, size_t buflen);
+
+/* Initialization/uninitialization/reset ************************************/
+
+static void sam3u_callback(void *arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct sam3u_dev_s g_sdiodev =
+{
+ .dev =
+ {
+ .reset = sam3u_reset,
+ .status = sam3u_status,
+ .widebus = sam3u_widebus,
+ .clock = sam3u_clock,
+ .attach = sam3u_attach,
+ .sendcmd = sam3u_sendcmd,
+ .blocksetup = sam3u_blocksetup,
+ .recvsetup = sam3u_dmarecvsetup,
+ .sendsetup = sam3u_dmasendsetup,
+ .cancel = sam3u_cancel,
+ .waitresponse = sam3u_waitresponse,
+ .recvR1 = sam3u_recvshort,
+ .recvR2 = sam3u_recvlong,
+ .recvR3 = sam3u_recvshort,
+ .recvR4 = sam3u_recvnotimpl,
+ .recvR5 = sam3u_recvnotimpl,
+ .recvR6 = sam3u_recvshort,
+ .recvR7 = sam3u_recvshort,
+ .waitenable = sam3u_waitenable,
+ .eventwait = sam3u_eventwait,
+ .callbackenable = sam3u_callbackenable,
+ .registercallback = sam3u_registercallback,
+#ifdef CONFIG_SDIO_DMA
+ .dmasupported = sam3u_dmasupported,
+ .dmarecvsetup = sam3u_dmarecvsetup,
+ .dmasendsetup = sam3u_dmasendsetup,
+#endif
+ },
+};
+
+/* Register logging support */
+
+#ifdef CONFIG_HSMCI_XFRDEBUG
+static struct sam3u_xfrregs_s g_xfrsamples[DEBUG_NDMASAMPLES];
+#endif
+#ifdef CONFIG_HSMCI_CMDDEBUG
+static struct sam3u_hsmciregs_s g_cmdsamples[DEBUG_NCMDSAMPLES];
+#endif
+#if defined(CONFIG_HSMCI_XFRDEBUG) && defined(CONFIG_HSMCI_CMDDEBUG)
+static bool g_xfrinitialized;
+static bool g_cmdinitialized;
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Low-level Helpers
+ ****************************************************************************/
+/****************************************************************************
+ * Name: sam3u_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 sam3u_takesem(struct sam3u_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: sam3u_enablewaitints
+ *
+ * Description:
+ * Enable HSMCI interrupts needed to suport the wait function
+ *
+ * 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 sam3u_enablewaitints(struct sam3u_dev_s *priv, uint32_t waitmask,
+ sdio_eventset_t waitevents)
+{
+ irqstate_t flags;
+
+ /* Save all of the data and set the new interrupt mask in one, atomic
+ * operation.
+ */
+
+ flags = irqsave();
+ priv->waitevents = waitevents;
+ priv->wkupevent = 0;
+ priv->waitmask = waitmask;
+ putreg32(priv->xfrmask | priv->waitmask, SAM3U_HSMCI_IER);
+ irqrestore(flags);
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_disablewaitints(struct sam3u_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 = irqsave();
+ priv->waitevents = 0;
+ priv->wkupevent = wkupevent;
+ priv->waitmask = 0;
+ putreg32(~priv->xfrmask, SAM3U_HSMCI_IDR);
+ irqrestore(flags);
+}
+
+/****************************************************************************
+ * Name: sam3u_enablexfrints
+ *
+ * Description:
+ * Enable 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 sam3u_enablexfrints(struct sam3u_dev_s *priv, uint32_t xfrmask)
+{
+ irqstate_t flags = irqsave();
+ priv->xfrmask = xfrmask;
+ putreg32(priv->xfrmask | priv->waitmask, SAM3U_HSMCI_IER);
+ irqrestore(flags);
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_disablexfrints(struct sam3u_dev_s *priv)
+{
+ irqstate_t flags = irqsave();
+ priv->xfrmask = 0;
+ putreg32(~priv->waitmask, SAM3U_HSMCI_IDR);
+ irqrestore(flags);
+}
+
+/****************************************************************************
+ * Name: sam3u_disable
+ *
+ * Description:
+ * Disable the HSMCI
+ *
+ ****************************************************************************/
+
+static inline void sam3u_disable(void)
+{
+ /* Disable the MCI peripheral clock */
+
+ putreg32((1 << SAM3U_PID_HSMCI), SAM3U_PMC_PCDR);
+
+ /* Disable the MCI */
+
+ putreg32(HSMCI_CR_MCIDIS, SAM3U_HSMCI_CR);
+
+ /* Disable all the interrupts */
+
+ putreg32(0xffffffff, SAM3U_HSMCI_IDR);
+}
+
+/****************************************************************************
+ * Name: sam3u_enable
+ *
+ * Description:
+ * Enable the HSMCI
+ *
+ ****************************************************************************/
+
+static inline void sam3u_enable(void)
+{
+ /* Enable the MCI peripheral clock */
+
+ putreg32((1 << SAM3U_PID_HSMCI), SAM3U_PMC_PCER);
+
+ /* Enable the MCI and the Power Saving */
+
+ putreg32(HSMCI_CR_MCIEN, SAM3U_HSMCI_CR);
+}
+
+/****************************************************************************
+ * Register Sampling
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam3u_hsmcisample
+ *
+ * Description:
+ * Sample HSMCI registers
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_HSMCI_XFRDEBUG) || defined(CONFIG_HSMCI_CMDDEBUG)
+static void sam3u_hsmcisample(struct sam3u_hsmciregs_s *regs)
+{
+ regs->mr = getreg32(SAM3U_HSMCI_MR);
+ regs->dtor = getreg32(SAM3U_HSMCI_DTOR);
+ regs->sdcr = getreg32(SAM3U_HSMCI_SDCR);
+ regs->argr = getreg32(SAM3U_HSMCI_ARGR);
+ regs->blkr = getreg32(SAM3U_HSMCI_BLKR);
+ regs->cstor = getreg32(SAM3U_HSMCI_CSTOR);
+ regs->rsp0 = getreg32(SAM3U_HSMCI_RSPR0);
+ regs->rsp1 = getreg32(SAM3U_HSMCI_RSPR1);
+ regs->rsp2 = getreg32(SAM3U_HSMCI_RSPR2);
+ regs->rsp3 = getreg32(SAM3U_HSMCI_RSPR3);
+ regs->sr = getreg32(SAM3U_HSMCI_SR);
+ regs->imr = getreg32(SAM3U_HSMCI_IMR);
+ regs->dma = getreg32(SAM3U_HSMCI_DMA);
+ regs->cfg = getreg32(SAM3U_HSMCI_CFG);
+ regs->wpmr = getreg32(SAM3U_HSMCI_WPMR);
+ regs->wpsr = getreg32(SAM3U_HSMCI_WPSR);
+}
+#endif
+
+/****************************************************************************
+ * Name: sam3u_hsmcidump
+ *
+ * Description:
+ * Dump one register sample
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_HSMCI_XFRDEBUG) || defined(CONFIG_HSMCI_CMDDEBUG)
+static void sam3u_hsmcidump(struct sam3u_hsmciregs_s *regs, const char *msg)
+{
+ fdbg("HSMCI Registers: %s\n", msg);
+ fdbg(" MR[%08x]: %08x\n", SAM3U_HSMCI_MR, regs->mr);
+ fdbg(" DTOR[%08x]: %08x\n", SAM3U_HSMCI_DTOR, regs->dtor);
+ fdbg(" SDCR[%08x]: %08x\n", SAM3U_HSMCI_SDCR, regs->sdcr);
+ fdbg(" ARGR[%08x]: %08x\n", SAM3U_HSMCI_ARGR, regs->argr);
+ fdbg(" BLKR[%08x]: %08x\n", SAM3U_HSMCI_BLKR, regs->blkr);
+ fdbg(" CSTOR[%08x]: %08x\n", SAM3U_HSMCI_CSTOR, regs->cstor);
+ fdbg(" RSPR0[%08x]: %08x\n", SAM3U_HSMCI_RSPR0, regs->rsp0);
+ fdbg(" RSPR1[%08x]: %08x\n", SAM3U_HSMCI_RSPR1, regs->rsp1);
+ fdbg(" RSPR2[%08x]: %08x\n", SAM3U_HSMCI_RSPR2, regs->rsp2);
+ fdbg(" RSPR3[%08x]: %08x\n", SAM3U_HSMCI_RSPR3, regs->rsp3);
+ fdbg(" SR[%08x]: %08x\n", SAM3U_HSMCI_SR, regs->sr);
+ fdbg(" IMR[%08x]: %08x\n", SAM3U_HSMCI_IMR, regs->imr);
+ fdbg(" DMA[%08x]: %08x\n", SAM3U_HSMCI_DMA, regs->dma);
+ fdbg(" CFG[%08x]: %08x\n", SAM3U_HSMCI_CFG, regs->cfg);
+ fdbg(" WPMR[%08x]: %08x\n", SAM3U_HSMCI_WPMR, regs->wpmr);
+ fdbg(" WPSR[%08x]: %08x\n", SAM3U_HSMCI_WPSR, regs->wpsr);
+}
+#endif
+
+/****************************************************************************
+ * Name: sam3u_xfrsample
+ *
+ * Description:
+ * Sample HSMCI/DMA registers
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_HSMCI_XFRDEBUG
+static void sam3u_xfrsample(struct sam3u_dev_s *priv, int index)
+{
+ struct sam3u_xfrregs_s *regs = &g_xfrsamples[index];
+#ifdef CONFIG_DEBUG_DMA
+ sam3u_dmasample(priv->dma, &regs->dma);
+#endif
+ sam3u_hsmcisample(&regs->hsmci);
+}
+#endif
+
+/****************************************************************************
+ * Name: sam3u_xfrsampleinit
+ *
+ * Description:
+ * Setup prior to collecting transfer samples
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_HSMCI_XFRDEBUG
+static void sam3u_xfrsampleinit(void)
+{
+ memset(g_xfrsamples, 0xff, DEBUG_NDMASAMPLES * sizeof(struct sam3u_xfrregs_s));
+#ifdef CONFIG_HSMCI_CMDDEBUG
+ g_xfrinitialized = true;
+#endif
+}
+#endif
+
+/****************************************************************************
+ * Name: sam3u_xfrdumpone
+ *
+ * Description:
+ * Dump one transfer register sample
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_HSMCI_XFRDEBUG
+static void sam3u_xfrdumpone(struct sam3u_dev_s *priv,
+ struct sam3u_xfrregs_s *regs, const char *msg)
+{
+#ifdef CONFIG_DEBUG_DMA
+ sam3u_dmadump(priv->dma, &regs->dma, msg);
+#endif
+ sam3u_hsmcidump(&regs->hsmci, msg);
+}
+#endif
+
+/****************************************************************************
+ * Name: sam3u_xfrdump
+ *
+ * Description:
+ * Dump all transfer-related, sampled register data
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_HSMCI_XFRDEBUG
+static void sam3u_xfrdump(struct sam3u_dev_s *priv)
+{
+#ifdef CONFIG_HSMCI_CMDDEBUG
+ if (g_xfrinitialized)
+#endif
+ {
+ sam3u_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_BEFORE_SETUP], "Before setup");
+#ifdef CONFIG_DEBUG_DMA
+ sam3u_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_BEFORE_ENABLE], "Before DMA enable");
+#endif
+ sam3u_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_AFTER_SETUP], "After setup");
+ sam3u_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_END_TRANSFER], "End of transfer");
+#ifdef CONFIG_DEBUG_DMA
+ sam3u_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_DMA_CALLBACK], "DMA Callback");
+#endif
+#ifdef CONFIG_HSMCI_CMDDEBUG
+ g_xfrinitialized = false;
+#endif
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: sam3u_cmdsampleinit
+ *
+ * Description:
+ * Setup prior to collecting command/response samples
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_HSMCI_CMDDEBUG
+static void sam3u_cmdsampleinit(void)
+{
+ memset(g_cmdsamples, 0xff, DEBUG_NCMDSAMPLES * sizeof(struct sam3u_hsmciregs_s));
+#ifdef CONFIG_HSMCI_XFRDEBUG
+ g_cmdinitialized = true;
+#endif
+}
+#endif
+
+/****************************************************************************
+ * Name: sam3u_cmdsample1 & 2
+ *
+ * Description:
+ * Sample command/response registers
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_HSMCI_CMDDEBUG
+static inline void sam3u_cmdsample1(int index)
+{
+ sam3u_hsmcisample(&g_cmdsamples[index]);
+}
+
+static inline void sam3u_cmdsample2(int index, uint32_t sr)
+{
+ sam3u_hsmcisample(&g_cmdsamples[index]);
+ g_cmdsamples[index].sr = sr;
+}
+#endif
+
+/****************************************************************************
+ * Name: sam3u_cmddump
+ *
+ * Description:
+ * Dump all comand/response register data
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_HSMCI_CMDDEBUG
+static void sam3u_cmddump(void)
+{
+#ifdef CONFIG_HSMCI_XFRDEBUG
+ if (g_cmdinitialized)
+#endif
+ {
+ sam3u_hsmcidump(&g_cmdsamples[SAMPLENDX_AFTER_CMDR], "After command setup");
+ sam3u_hsmcidump(&g_cmdsamples[SAMPLENDX_AT_WAKEUP], "After wakeup");
+#ifdef CONFIG_HSMCI_XFRDEBUG
+ g_cmdinitialized = false;
+#endif
+ }
+}
+#endif
+
+/****************************************************************************
+ * DMA Helpers
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam3u_dmacallback
+ *
+ * Description:
+ * Called when HSMCI DMA completes
+ *
+ ****************************************************************************/
+
+static void sam3u_dmacallback(DMA_HANDLE handle, void *arg, int result)
+{
+ /* We don't really do anything at the completion of DMA. The termination
+ * of the transfer is driven by the HSMCI interrupts.
+ */
+
+ sam3u_xfrsample((struct sam3u_dev_s*)arg, SAMPLENDX_DMA_CALLBACK);
+}
+
+/****************************************************************************
+ * Data Transfer Helpers
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_eventtimeout(int argc, uint32_t arg)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_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 */
+
+ sam3u_endwait(priv, SDIOWAIT_TIMEOUT);
+ flldbg("Timeout\n");
+ }
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_endwait(struct sam3u_dev_s *priv, sdio_eventset_t wkupevent)
+{
+ /* Cancel the watchdog timeout */
+
+ (void)wd_cancel(priv->waitwdog);
+
+ /* Disable event-related interrupts and save wakeup event */
+
+ sam3u_disablewaitints(priv, wkupevent);
+
+ /* Wake up the waiting thread */
+
+ sam3u_givesem(priv);
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_endtransfer(struct sam3u_dev_s *priv, sdio_eventset_t wkupevent)
+{
+ /* Disable all transfer related interrupts */
+
+ sam3u_disablexfrints(priv);
+
+ /* No data transfer */
+
+ sam3u_notransfer(priv);
+
+ /* DMA debug instrumentation */
+
+ sam3u_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.
+ */
+
+ sam3u_dmastop(priv->dma);
+
+ /* Disable the DMA handshaking */
+
+ putreg32(0, SAM3U_HSMCI_DMA);
+
+ /* Is a thread wait for these data transfer complete events? */
+
+ if ((priv->waitevents & wkupevent) != 0)
+ {
+ /* Yes.. wake up any waiting threads */
+
+ sam3u_endwait(priv, wkupevent);
+ }
+}
+
+/****************************************************************************
+ * Name: sam3u_notransfer
+ *
+ * Description:
+ * Setup for no transfer. This is the default setup that is overriddden
+ * by sam3u_dmarecvsetup or sam3u_dmasendsetup
+ *
+ * Input Parameters:
+ * priv - An instance of the HSMCI device interface
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void sam3u_notransfer(struct sam3u_dev_s *priv)
+{
+ uint32_t regval = getreg32(SAM3U_HSMCI_MR);
+ regval &= ~(HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF | HSMCI_MR_BLKLEN_MASK);
+ putreg32(regval, SAM3U_HSMCI_MR);
+}
+
+/****************************************************************************
+ * Interrrupt Handling
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_interrupt(int irq, void *context)
+{
+ struct sam3u_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(SAM3U_HSMCI_SR);
+ enabled = sr & getreg32(SAM3U_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. */
+
+ sam3u_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT);
+ }
+ else
+ {
+ /* No.. Terminate with an I/O error. */
+
+ sam3u_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_ERROR);
+ }
+ }
+ else
+ {
+ /* No.. Then the transfer must have completed successfully */
+
+ sam3u_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)
+ {
+ sam3u_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 */
+
+ sam3u_endwait(priv, wkupevent);
+ }
+ }
+ }
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * SDIO Interface Methods
+ ****************************************************************************/
+/****************************************************************************
+ * Name: sam3u_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 sam3u_reset(FAR struct sdio_dev_s *dev)
+{
+ FAR struct sam3u_dev_s *priv = (FAR struct sam3u_dev_s *)dev;
+ irqstate_t flags;
+
+ /* Enable the MCI clock */
+
+ flags = irqsave();
+ putreg32((1 << SAM3U_PID_HSMCI), SAM3U_PMC_PCER);
+ fdbg("PCSR: %08x\n", getreg32(SAM3U_PMC_PCSR));
+
+ /* Reset the MCI */
+
+ putreg32(HSMCI_CR_SWRST, SAM3U_HSMCI_CR);
+
+ /* Disable the MCI */
+
+ putreg32(HSMCI_CR_MCIDIS | HSMCI_CR_PWSDIS, SAM3U_HSMCI_CR);
+
+ /* Disable all the interrupts */
+
+ putreg32(0xffffffff, SAM3U_HSMCI_IDR);
+
+ /* Set the Data Timeout Register */
+
+ putreg32(HSMCI_DTOR_DTOCYC_MAX | HSMCI_DTOR_DTOMUL_MAX, SAM3U_HSMCI_DTOR);
+
+ /* Set the Mode Register for ID mode frequency (probably 400KHz) */
+
+ sam3u_clock(dev, CLOCK_IDMODE);
+
+ /* Set the SDCard Register */
+
+ putreg32(HSMCI_SDCR_SDCSEL_SLOTA | HSMCI_SDCR_SDCBUS_4BIT, SAM3U_HSMCI_SDCR);
+
+ /* Enable the MCI controller */
+
+ putreg32(HSMCI_CR_MCIEN, SAM3U_HSMCI_CR);
+
+ /* Disable the DMA interface */
+
+ putreg32(0, SAM3U_HSMCI_DMA);
+
+ /* Configure MCI */
+
+ putreg32(HSMCI_CFG_FIFOMODE, SAM3U_HSMCI_CFG);
+
+ /* No data transfer */
+
+ sam3u_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 */
+ 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 */
+ irqrestore(flags);
+}
+
+/****************************************************************************
+ * Name: sam3u_status
+ *
+ * Description:
+ * Get SDIO status.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ *
+ * Returned Value:
+ * Returns a bitset of status values (see sam3u_status_* defines)
+ *
+ ****************************************************************************/
+
+static uint8_t sam3u_status(FAR struct sdio_dev_s *dev)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_dev_s *)dev;
+ return priv->cdstatus;
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_widebus(FAR struct sdio_dev_s *dev, bool wide)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_dev_s *)dev;
+ uint32_t regval;
+
+ /* Set 1-bit or 4-bit bus by configuring the SDCBUS field of the SDCR register */
+
+ regval = getreg32(SAM3U_HSMCI_SDCR);
+ regval &= ~HSMCI_SDCR_SDCBUS_MASK;
+ regval |= wide ? HSMCI_SDCR_SDCBUS_4BIT : HSMCI_SDCR_SDCBUS_1BIT;
+ putreg32(regval, SAM3U_HSMCI_SDCR);
+
+ /* Remember the setting */
+
+ priv->widebus = wide;
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_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(SAM3U_HSMCI_MR);
+ regval &= ~(HSMCI_MR_CLKDIV_MASK | HSMCI_MR_PWSDIV_MASK);
+
+ /* 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, SAM3U_HSMCI_MR);
+ if (enable)
+ {
+ sam3u_enable();
+ }
+ else
+ {
+ sam3u_disable();
+ }
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_attach(FAR struct sdio_dev_s *dev)
+{
+ int ret;
+
+ /* Attach the HSMCI interrupt handler */
+
+ ret = irq_attach(SAM3U_IRQ_HSMCI, sam3u_interrupt);
+ if (ret == OK)
+ {
+
+ /* Disable all interrupts at the HSMCI controller and clear (most) static
+ * interrupt flags by reading the status register.
+ */
+
+ putreg32(0xffffffff, SAM3U_HSMCI_IDR);
+ (void)getreg32(SAM3U_HSMCI_SR);
+
+ /* Enable HSMCI interrupts at the NVIC. They can now be enabled at
+ * the HSMCI controller as needed.
+ */
+
+ up_enable_irq(SAM3U_IRQ_HSMCI);
+
+ /* Set the interrrupt priority */
+
+ up_prioritize_irq(SAM3U_IRQ_HSMCI, CONFIG_HSMCI_PRI);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t arg)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_dev_s*)dev;
+ uint32_t regval;
+ uint32_t cmdidx;
+
+ sam3u_cmdsampleinit();
+
+ /* Set the HSMCI Argument value */
+
+ putreg32(arg, SAM3U_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 transer 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, SAM3U_HSMCI_CMDR);
+ sam3u_cmdsample1(SAMPLENDX_AFTER_CMDR);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_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);
+
+ /* Set the block size */
+
+ regval = getreg32(SAM3U_HSMCI_MR);
+ regval &= ~(HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF | HSMCI_MR_BLKLEN_MASK);
+ regval |= HSMCU_PROOF_BITS;
+ regval |= (blocklen << HSMCI_MR_BLKLEN_SHIFT);
+ putreg32(regval, SAM3U_HSMCI_MR);
+
+ /* Set the block count */
+
+ regval = getreg32(SAM3U_HSMCI_BLKR);
+ regval &= ~HSMCI_BLKR_BCNT_MASK;
+ regval |= (nblocks << HSMCI_BLKR_BCNT_SHIFT);
+ putreg32(regval, SAM3U_HSMCI_BLKR);
+}
+
+/****************************************************************************
+ * Name: sam3u_cancel
+ *
+ * Description:
+ * Cancel the data transfer setup of HSMCI_RECVSETUP, HSMCI_SENDSETUP,
+ * HSMCI_DMARECVSETUP or HSMCI_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 sam3u_cancel(FAR struct sdio_dev_s *dev)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_dev_s*)dev;
+
+ /* Disable all transfer- and event- related interrupts */
+
+ sam3u_disablexfrints(priv);
+ sam3u_disablewaitints(priv, 0);
+
+ /* No data transfer */
+
+ sam3u_notransfer(priv);
+
+ /* Clearing (most) pending interrupt status by reading the status register */
+
+ (void)getreg32(SAM3U_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.
+ */
+
+ sam3u_dmastop(priv->dma);
+
+ /* Disable the DMA handshaking */
+
+ putreg32(0, SAM3U_HSMCI_DMA);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_dev_s*)dev;
+ uint32_t sr;
+ 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(SAM3U_HSMCI_SR);
+ if ((sr & priv->cmdrmask) != 0)
+ {
+ sam3u_cmdsample2(SAMPLENDX_AT_WAKEUP, sr);
+ sam3u_cmddump();
+
+ /* Yes.. Did the Command-Response sequence end with an error? */
+
+ if ((sr & 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 ((sr & 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: sam3u_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 sam3u_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rshort)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_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(SAM3U_HSMCI_RSPR0);
+ }
+
+ priv->wkupevent = 0;
+ return ret;
+}
+
+static int sam3u_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlong[4])
+{
+ struct sam3u_dev_s *priv = (struct sam3u_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(SAM3U_HSMCI_RSPR0);
+ rlong[1] = getreg32(SAM3U_HSMCI_RSPR1);
+ rlong[2] = getreg32(SAM3U_HSMCI_RSPR2);
+ rlong[3] = getreg32(SAM3U_HSMCI_RSPR3);
+ }
+
+ priv->wkupevent = 0;
+ return ret;
+}
+
+/* MMC responses not supported */
+
+static int sam3u_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rnotimpl)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_dev_s*)dev;
+ priv->wkupevent = 0;
+ return -ENOSYS;
+}
+
+/****************************************************************************
+ * Name: sam3u_waitenable
+ *
+ * Description:
+ * Enable/disable of a set of SDIO wait events. This is part of the
+ * the HSMCI_WAITEVENT sequence. The set of to-be-waited-for events is
+ * configured before calling sam3u_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) HSMCI_WAITENABLE is called
+ * again specifying a different set of wait events, or (2) HSMCI_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 sam3u_waitenable(FAR struct sdio_dev_s *dev,
+ sdio_eventset_t eventset)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_dev_s*)dev;
+ uint32_t waitmask;
+
+ DEBUGASSERT(priv != NULL);
+
+ /* Disable event-related interrupts */
+
+ sam3u_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;
+ }
+
+ /* Enable event-related interrupts */
+
+ (void)getreg32(SAM3U_HSMCI_SR);
+ sam3u_enablewaitints(priv, waitmask, eventset);
+}
+
+/****************************************************************************
+ * Name: sam3u_eventwait
+ *
+ * Description:
+ * Wait for one of the enabled events to occur (or a timeout). Note that
+ * all events enabled by HSMCI_WAITEVENTS are disabled when sam3u_eventwait
+ * returns. HSMCI_WAITEVENTS must be called again before sam3u_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 sam3u_eventwait(FAR struct sdio_dev_s *dev,
+ uint32_t timeout)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_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 cornercase */
+
+ if (!timeout)
+ {
+ return SDIOWAIT_TIMEOUT;
+ }
+
+ /* Start the watchdog timer */
+
+ delay = (timeout + (MSEC_PER_TICK-1)) / MSEC_PER_TICK;
+ ret = wd_start(priv->waitwdog, delay, (wdentry_t)sam3u_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 sam3u_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.
+ */
+
+ sam3u_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;
+ }
+ }
+
+ sam3u_cmddump();
+ sam3u_xfrdump(priv);
+ return wkupevent;
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_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 sam3u_callbackenable(FAR struct sdio_dev_s *dev,
+ sdio_eventset_t eventset)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_dev_s*)dev;
+
+ fvdbg("eventset: %02x\n", eventset);
+ DEBUGASSERT(priv != NULL);
+
+ priv->cbevents = eventset;
+ sam3u_callback(priv);
+}
+
+/****************************************************************************
+ * Name: sam3u_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 HSMCI_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 sam3u_registercallback(FAR struct sdio_dev_s *dev,
+ worker_t callback, void *arg)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_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: sam3u_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 sam3u_dmasupported(FAR struct sdio_dev_s *dev)
+{
+ return true;
+}
+#endif
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
+ size_t buflen)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_dev_s *)dev;
+
+ DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
+ DEBUGASSERT(((uint32_t)buffer & 3) == 0);
+
+ /* Setup register sampling */
+
+ sam3u_xfrsampleinit();
+ sam3u_xfrsample(priv, SAMPLENDX_BEFORE_SETUP);
+
+ /* Configure the RX DMA */
+
+ sam3u_enablexfrints(priv, HSMCI_DMARECV_INTS);
+ sam3u_dmarxsetup(priv->dma, SAM3U_HSMCI_FIFO, (uint32_t)buffer, buflen);
+
+ /* Enable DMA handshaking */
+
+ putreg32(HSMCI_DMA_DMAEN, SAM3U_HSMCI_DMA);
+ sam3u_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE);
+
+ /* Start the DMA */
+
+ sam3u_dmastart(priv->dma, sam3u_dmacallback, priv);
+ sam3u_xfrsample(priv, SAMPLENDX_AFTER_SETUP);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_dmasendsetup(FAR struct sdio_dev_s *dev,
+ FAR const uint8_t *buffer, size_t buflen)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_dev_s *)dev;
+
+ DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
+ DEBUGASSERT(((uint32_t)buffer & 3) == 0);
+
+ /* Setup register sampling */
+
+ sam3u_xfrsampleinit();
+ sam3u_xfrsample(priv, SAMPLENDX_BEFORE_SETUP);
+
+ /* Configure the TX DMA */
+
+ sam3u_dmatxsetup(priv->dma, SAM3U_HSMCI_FIFO, (uint32_t)buffer, buflen);
+
+ /* Enable DMA handshaking */
+
+ putreg32(HSMCI_DMA_DMAEN, SAM3U_HSMCI_DMA);
+ sam3u_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE);
+
+ /* Start the DMA */
+
+ sam3u_dmastart(priv->dma, sam3u_dmacallback, priv);
+ sam3u_xfrsample(priv, SAMPLENDX_AFTER_SETUP);
+
+ /* Enable TX interrrupts */
+
+ sam3u_enablexfrints(priv, HSMCI_DMASEND_INTS);
+ return OK;
+}
+
+/****************************************************************************
+ * Initialization/uninitialization/reset
+ ****************************************************************************/
+/****************************************************************************
+ * Name: sam3u_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 sam3u_callback(void *arg)
+{
+ struct sam3u_dev_s *priv = (struct sam3u_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: 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 sam3u_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);
+
+ /* Allocate a DMA channel. A FIFO size of 8 is sufficient. */
+
+ priv->dma = sam3u_dmachannel(DMA_FLAGS);
+ DEBUGASSERT(priv->dma);
+
+ /* 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.
+ */
+
+ sam3u_configgpio(GPIO_MCI_DAT0); /* Data 0 of Slot A */
+ sam3u_configgpio(GPIO_MCI_DAT1); /* Data 1 of Slot A */
+ sam3u_configgpio(GPIO_MCI_DAT2); /* Data 2 of Slot A */
+ sam3u_configgpio(GPIO_MCI_DAT3); /* Data 3 of Slot A */
+ sam3u_configgpio(GPIO_MCI_CK); /* SD clock */
+ sam3u_configgpio(GPIO_MCI_DA); /* Command/Response */
+
+#ifdef CONFIG_DEBUG_FS
+ sam3u_dumpgpio(GPIO_PORT_PIOA, "Pins: 3-8");
+ sam3u_dumpgpio(GPIO_PORT_PIOB, "Pins: 28-31");
+#endif
+
+ /* Reset the card and assure that it is in the initial, unconfigured
+ * state.
+ */
+
+ sam3u_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 sam3u_dev_s *priv = (struct sam3u_dev_s *)dev;
+ uint8_t cdstatus;
+ irqstate_t flags;
+
+ /* Update card status */
+
+ flags = irqsave();
+ 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)
+ {
+ sam3u_callback(priv);
+ }
+ irqrestore(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 sam3u_dev_s *priv = (struct sam3u_dev_s *)dev;
+ irqstate_t flags;
+
+ /* Update card status */
+
+ flags = irqsave();
+ if (wrprotect)
+ {
+ priv->cdstatus |= SDIO_STATUS_WRPROTECTED;
+ }
+ else
+ {
+ priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED;
+ }
+ fvdbg("cdstatus: %02x\n", priv->cdstatus);
+ irqrestore(flags);
+}
+#endif /* CONFIG_SAM3U_HSMCI */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_hsmci.h b/nuttx/arch/arm/src/sam3u/sam3u_hsmci.h
new file mode 100644
index 000000000..1667789a6
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_hsmci.h
@@ -0,0 +1,297 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_hsmci.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_HSMCI_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_HSMCI_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* HSMCI register offsets ***************************************************************/
+
+#define SAM3U_HSMCI_CR_OFFSET 0x0000 /* Control Register */
+#define SAM3U_HSMCI_MR_OFFSET 0x0004 /* Mode Register */
+#define SAM3U_HSMCI_DTOR_OFFSET 0x0008 /* Data Timeout Register */
+#define SAM3U_HSMCI_SDCR_OFFSET 0x000c /* SD/SDIO Card Register */
+#define SAM3U_HSMCI_ARGR_OFFSET 0x0010 /* Argument Register */
+#define SAM3U_HSMCI_CMDR_OFFSET 0x0014 /* Command Register */
+#define SAM3U_HSMCI_BLKR_OFFSET 0x0018 /* Block Register */
+#define SAM3U_HSMCI_CSTOR_OFFSET 0x001c /* Completion Signal Timeout Register */
+#define SAM3U_HSMCI_RSPR0_OFFSET 0x0020 /* Response Register 0 */
+#define SAM3U_HSMCI_RSPR1_OFFSET 0x0024 /* Response Register 1 */
+#define SAM3U_HSMCI_RSPR2_OFFSET 0x0028 /* Response Register 2 */
+#define SAM3U_HSMCI_RSPR3_OFFSET 0x002c /* Response Register 3 */
+#define SAM3U_HSMCI_RDR_OFFSET 0x0030 /* Receive Data Register */
+#define SAM3U_HSMCI_TDR_OFFSET 0x0034 /* Transmit Data Register */
+ /* 0x0038-0x003c: Reserved */
+#define SAM3U_HSMCI_SR_OFFSET 0x0040 /* Status Register */
+#define SAM3U_HSMCI_IER_OFFSET 0x0044 /* Interrupt Enable Register */
+#define SAM3U_HSMCI_IDR_OFFSET 0x0048 /* Interrupt Disable Register */
+#define SAM3U_HSMCI_IMR_OFFSET 0x004c /* Interrupt Mask Register */
+#define SAM3U_HSMCI_DMA_OFFSET 0x0050 /* DMA Configuration Register */
+#define SAM3U_HSMCI_CFG_OFFSET 0x0054 /* Configuration Register */
+ /* 0x0058-0x00e0: Reserved */
+#define SAM3U_HSMCI_WPMR_OFFSET 0x00e4 /* Write Protection Mode Register */
+#define SAM3U_HSMCI_WPSR_OFFSET 0x00e8 /* Write Protection Status Register */
+ /* 0x00ec-0x00fc: Reserved */
+ /* 0x0100-0x0124: Reserved */
+#define SAM3U_HSMCI_FIFO_OFFSET 0x0200 /* 0x0200-0x3ffc FIFO Memory Aperture */
+
+/* HSMCI register adresses **************************************************************/
+
+#define SAM3U_HSMCI_CR (SAM3U_MCI_BASE+SAM3U_HSMCI_CR_OFFSET)
+#define SAM3U_HSMCI_MR (SAM3U_MCI_BASE+SAM3U_HSMCI_MR_OFFSET)
+#define SAM3U_HSMCI_DTOR (SAM3U_MCI_BASE+SAM3U_HSMCI_DTOR_OFFSET)
+#define SAM3U_HSMCI_SDCR (SAM3U_MCI_BASE+SAM3U_HSMCI_SDCR_OFFSET)
+#define SAM3U_HSMCI_ARGR (SAM3U_MCI_BASE+SAM3U_HSMCI_ARGR_OFFSET)
+#define SAM3U_HSMCI_CMDR (SAM3U_MCI_BASE+SAM3U_HSMCI_CMDR_OFFSET)
+#define SAM3U_HSMCI_BLKR (SAM3U_MCI_BASE+SAM3U_HSMCI_BLKR_OFFSET)
+#define SAM3U_HSMCI_CSTOR (SAM3U_MCI_BASE+SAM3U_HSMCI_CSTOR_OFFSET)
+#define SAM3U_HSMCI_RSPR0 (SAM3U_MCI_BASE+SAM3U_HSMCI_RSPR0_OFFSET)
+#define SAM3U_HSMCI_RSPR1 (SAM3U_MCI_BASE+SAM3U_HSMCI_RSPR1_OFFSET)
+#define SAM3U_HSMCI_RSPR2 (SAM3U_MCI_BASE+SAM3U_HSMCI_RSPR2_OFFSET)
+#define SAM3U_HSMCI_RSPR3 (SAM3U_MCI_BASE+SAM3U_HSMCI_RSPR3_OFFSET)
+#define SAM3U_HSMCI_RDR (SAM3U_MCI_BASE+SAM3U_HSMCI_RDR_OFFSET)
+#define SAM3U_HSMCI_TDR (SAM3U_MCI_BASE+SAM3U_HSMCI_TDR_OFFSET)
+#define SAM3U_HSMCI_SR (SAM3U_MCI_BASE+SAM3U_HSMCI_SR_OFFSET)
+#define SAM3U_HSMCI_IER (SAM3U_MCI_BASE+SAM3U_HSMCI_IER_OFFSET)
+#define SAM3U_HSMCI_IDR (SAM3U_MCI_BASE+SAM3U_HSMCI_IDR_OFFSET)
+#define SAM3U_HSMCI_IMR (SAM3U_MCI_BASE+SAM3U_HSMCI_IMR_OFFSET)
+#define SAM3U_HSMCI_DMA (SAM3U_MCI_BASE+SAM3U_HSMCI_DMA_OFFSET)
+#define SAM3U_HSMCI_CFG (SAM3U_MCI_BASE+SAM3U_HSMCI_CFG_OFFSET)
+#define SAM3U_HSMCI_WPMR (SAM3U_MCI_BASE+SAM3U_HSMCI_WPMR_OFFSET)
+#define SAM3U_HSMCI_WPSR (SAM3U_MCI_BASE+SAM3U_HSMCI_WPSR_OFFSET)
+#define SAM3U_HSMCI_FIFO (SAM3U_MCI_BASE+SAM3U_HSMCI_FIFO_OFFSET)
+
+/* 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_BLKLEN_SHIFT (16) /* Bits 16-31: Data Block Length */
+#define HSMCI_MR_BLKLEN_MASK (0xffff << HSMCI_MR_BLKLEN_SHIFT)
+
+/* 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)
+# 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 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_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 << 17) /* 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_BLKLEN_SHIFT (16) /* Bits 16-31: Data Block Length */
+#define HSMCI_BLKR_BLKLEN_MASK (0xffff << 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_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 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_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 */
+
+#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 */
+
+/* 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)
+
+/* HSMCI Write Protect Status Register */
+
+#define HSMCI_WPSR_WP_VS_SHIFT (0) /* Bits 0-3: Write Protection Violation Status */
+#define HSMCI_WPSR_WP_VS_MASK (15 << HSMCI_WPSR_WP_VS_SHIFT)
+#define HSMCI_WPSR_WP_VSRC_SHIFT (8) /* Bits 8-23: Write Protection Violation Source */
+#define HSMCI_WPSR_WP_VSRC_MASK (0xffff << HSMCI_WPSR_WP_VSRC_SHIFT)
+
+/****************************************************************************************
+ * Public Types
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Data
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Functions
+ ****************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_SAM3U_SAM3U_HSMCI_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_internal.h b/nuttx/arch/arm/src/sam3u/sam3u_internal.h
new file mode 100644
index 000000000..d37968515
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_internal.h
@@ -0,0 +1,910 @@
+/************************************************************************************
+ * arch/arm/src/sam3u/sam3u_internal.h
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_INTERNAL_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_INTERNAL_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "up_internal.h"
+#include "chip.h"
+
+/************************************************************************************
+ * Definitions
+ ************************************************************************************/
+
+/* Configuration ********************************************************************/
+
+#if defined(CONFIG_GPIOA_IRQ) || defined(CONFIG_GPIOB_IRQ) || defined(CONFIG_GPIOC_IRQ)
+# define CONFIG_GPIO_IRQ 1
+#else
+# undef CONFIG_GPIO_IRQ
+#endif
+
+#ifndef CONFIG_DEBUG
+# undef CONFIG_DEBUG_GPIO
+# undef CONFIG_DEBUG_DMA
+#endif
+
+/* Bit-encoded input to sam3u_configgpio() ******************************************/
+
+/* 16-bit Encoding:
+ * MMCC CII. 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:
+ * .... .II. .... ....
+ */
+
+#define GPIO_INT_SHIFT (9) /* Bits 9-10: GPIO configuration bits */
+#define GPIO_INT_MASK (3 << GPIO_INT_SHIFT)
+# define GPIO_INT_LEVEL (1 << 10) /* Bit 10: Level detection interrupt */
+# define GPIO_INT_EDGE (0) /* (vs. Edge detection interrupt) */
+# define GPIO_INT_HIGHLEVEL (1 << 9) /* Bit 9: High level detection interrupt */
+# define GPIO_INT_LOWLEVEL (0) /* (vs. Low level detection interrupt) */
+# define GPIO_INT_RISING (1 << 9) /* Bit 9: Rising edge detection interrupt */
+# define GPIO_INT_FALLING (0) /* (vs. Falling edge detection interrupt) */
+
+/* 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)
+
+/* 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_MCI_DAT0 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN5)
+#define GPIO_MCI_DAT1 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN6)
+#define GPIO_MCI_DAT2 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN7)
+#define GPIO_MCI_DAT3 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN8)
+#define GPIO_MCI_DAT4 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN28)
+#define GPIO_MCI_DAT5 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN29)
+#define GPIO_MCI_DAT6 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN30)
+#define GPIO_MCI_DAT7 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN31)
+#define GPIO_MCI_CK (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN3)
+#define GPIO_MCI_DA (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN4)
+#define GPIO_MCI_DAT0IN (GPIO_INPUT|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN5)
+
+#define GPIO_PWMC_PWMH0 (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN0)
+#define GPIO_PWMC_PWML0 (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN7)
+#define GPIO_PWMC_PWMH1 (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN1)
+#define GPIO_PWMC_PWML1 (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN8)
+#define GPIO_PWMC_PWMH2 (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN2)
+#define GPIO_PWMC_PWML2 (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_TWI_TWD0 (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN9)
+#define GPIO_TWI_TWCK0 (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN10)
+#define GPIO_TWI_TWD1 (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN24)
+#define GPIO_TWI_TWCK1 (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN25)
+
+#define GPIO_UART_TXD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN12)
+#define GPIO_UART_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)
+
+/* 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 */
+
+#define DMACH_FLAG_FLOWCONTROL (1 << 0) /* Bit 0: Channel supports flow control */
+#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_PERIPHPID_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 << 22) /* 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 */
+
+/************************************************************************************
+ * 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 sam3u_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 */
+
+ /* 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: sam3u_clockconfig
+ *
+ * Description:
+ * Called to initialize the SAM3U. 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 sam3u is initiallyrunning on
+ * a 4MHz internal RC clock). This function also performs other low-level chip
+ * initialization of the chip including EFC, master clock, IRQ and watchdog
+ * configuration.
+ *
+ ************************************************************************************/
+
+EXTERN void sam3u_clockconfig(void);
+
+/************************************************************************************
+ * Name: sam3u_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.
+ *
+ ************************************************************************************/
+
+EXTERN void sam3u_lowsetup(void);
+
+/****************************************************************************
+ * Name: sam3u_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
+ * segements.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NUTTX_KERNEL
+EXTERN void sam3u_userspace(void);
+#endif
+
+/****************************************************************************
+ * Name: sam3u_mpuinitialize
+ *
+ * Description:
+ * Configure the MPU to permit user-space access to only restricted SAM3U
+ * resources.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NUTTX_KERNEL
+EXTERN void sam3u_mpuinitialize(void);
+#else
+# define sam3u_mpuinitialize()
+#endif
+
+/****************************************************************************
+ * Name: sam3u_mpuheap
+ *
+ * Description:
+ * Map a heap region.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NUTTX_KERNEL
+EXTERN void sam3u_mpuheap(uintptr_t start, size_t size);
+#else
+# define sam3u_mpuheap(start,size)
+#endif
+
+/************************************************************************************
+ * Name: sam3u_gpioirqinitialize
+ *
+ * Description:
+ * Initialize logic to support a second level of interrupt decoding for GPIO pins.
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_GPIO_IRQ
+EXTERN void sam3u_gpioirqinitialize(void);
+#else
+# define sam3u_gpioirqinitialize()
+#endif
+
+/************************************************************************************
+ * Name: sam3u_configgpio
+ *
+ * Description:
+ * Configure a GPIO pin based on bit-encoded description of the pin.
+ *
+ ************************************************************************************/
+
+EXTERN int sam3u_configgpio(uint16_t cfgset);
+
+/************************************************************************************
+ * Name: sam3u_gpiowrite
+ *
+ * Description:
+ * Write one or zero to the selected GPIO pin
+ *
+ ************************************************************************************/
+
+EXTERN void sam3u_gpiowrite(uint16_t pinset, bool value);
+
+/************************************************************************************
+ * Name: sam3u_gpioread
+ *
+ * Description:
+ * Read one or zero from the selected GPIO pin
+ *
+ ************************************************************************************/
+
+EXTERN bool sam3u_gpioread(uint16_t pinset);
+
+/************************************************************************************
+ * Name: sam3u_gpioirq
+ *
+ * Description:
+ * Configure an interrupt for the specified GPIO pin.
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_GPIO_IRQ
+EXTERN void sam3u_gpioirq(uint16_t pinset);
+#else
+# define sam3u_gpioirq(pinset)
+#endif
+
+/************************************************************************************
+ * Name: sam3u_gpioirqenable
+ *
+ * Description:
+ * Enable the interrupt for specified GPIO IRQ
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_GPIO_IRQ
+EXTERN void sam3u_gpioirqenable(int irq);
+#else
+# define sam3u_gpioirqenable(irq)
+#endif
+
+/************************************************************************************
+ * Name: sam3u_gpioirqdisable
+ *
+ * Description:
+ * Disable the interrupt for specified GPIO IRQ
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_GPIO_IRQ
+EXTERN void sam3u_gpioirqdisable(int irq);
+#else
+# define sam3u_gpioirqdisable(irq)
+#endif
+
+/************************************************************************************
+ * Function: sam3u_dumpgpio
+ *
+ * Description:
+ * Dump all GPIO registers associated with the base address of the provided pinset.
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_DEBUG_GPIO
+EXTERN int sam3u_dumpgpio(uint32_t pinset, const char *msg);
+#else
+# define sam3u_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Name: sam3u_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.
+ *
+ ****************************************************************************/
+
+EXTERN DMA_HANDLE sam3u_dmachannel(uint32_t dmach_flags);
+
+/****************************************************************************
+ * Name: sam3u_dmafree
+ *
+ * Description:
+ * Release a DMA channel. NOTE: The 'handle' used in this argument must
+ * NEVER be used again until sam3u_dmachannel() is called again to re-gain
+ * a valid handle.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+EXTERN void sam3u_dmafree(DMA_HANDLE handle);
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_dmatxsetup() and sam3u_dmatxsetup()
+ * must not be intermixed on the same transfer, however.
+ *
+ ****************************************************************************/
+
+EXTERN int sam3u_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr,
+ size_t nbytes);
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_dmatxsetup() and sam3u_dmatxsetup()
+ * must not be intermixed on the same transfer, however.
+ *
+ ****************************************************************************/
+
+EXTERN int sam3u_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr,
+ size_t nbytes);
+
+/****************************************************************************
+ * Name: sam3u_dmastart
+ *
+ * Description:
+ * Start the DMA transfer
+ *
+ ****************************************************************************/
+
+EXTERN int sam3u_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg);
+
+/****************************************************************************
+ * Name: sam3u_dmastop
+ *
+ * Description:
+ * Cancel the DMA. After sam3u_dmastop() is called, the DMA channel is
+ * reset and sam3u_dmasetup() must be called before sam3u_dmastart() can be
+ * called again
+ *
+ ****************************************************************************/
+
+EXTERN void sam3u_dmastop(DMA_HANDLE handle);
+
+/****************************************************************************
+ * Name: sam3u_dmasample
+ *
+ * Description:
+ * Sample DMA register contents
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_DMA
+EXTERN void sam3u_dmasample(DMA_HANDLE handle, struct sam3u_dmaregs_s *regs);
+#else
+# define sam3u_dmasample(handle,regs)
+#endif
+
+/****************************************************************************
+ * Name: sam3u_dmadump
+ *
+ * Description:
+ * Dump previously sampled DMA register contents
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_DMA
+EXTERN void sam3u_dmadump(DMA_HANDLE handle, const struct sam3u_dmaregs_s *regs,
+ const char *msg);
+#else
+# define sam3u_dmadump(handle,regs,msg)
+#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 */
+EXTERN 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
+ *
+ ****************************************************************************/
+
+EXTERN 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
+ *
+ ****************************************************************************/
+
+EXTERN void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect);
+
+/****************************************************************************
+ * Name: sam3u_spicsnumber, sam3u_spiselect, sam3u_spistatus, and
+ * sam3u_spicmddata
+ *
+ * Description:
+ * These external functions must be provided by board-specific logic. They
+ * include:
+ *
+ * o sam3u_spicsnumbe and sam3u_spiselect which are helper functions to
+ * manage the board-specific aspects of the unique SAM3U chip select
+ * architecture.
+ * o sam3u_spistatus and sam3u_spicmddata: Implementations of the status
+ * and cmddata methods of the SPI interface defined by struct spi_ops_
+ * (see include/nuttx/spi.h). All other methods including
+ * up_spiinitialize()) are provided by common SAM3U logic.
+ *
+ * To use this common SPI logic on your board:
+ *
+ * 1. Provide logic in sam3u_boardinitialize() to configure SPI chip select
+ * pins.
+ * 2. Provide sam3u_spicsnumber(), sam3u_spiselect() and sam3u_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
+ * sam3u_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 up_spiinitialize() in your low level application
+ * initialization logic
+ * 4. The handle returned by up_spiinitialize() 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_SAM3U_SPI
+struct spi_dev_s;
+enum spi_dev_e;
+
+/****************************************************************************
+ * Name: sam3u_spicsnumber
+ *
+ * Description:
+ * The SAM3U has 4 CS registers for controlling device features. This
+ * function must be provided by board-specific code. Given a logical device
+ * ID, this function returns a number from 0 to 3 that identifies one of
+ * these SAM3U CS resources.
+ *
+ * If CONFIG_SPI_OWNBUS is not defined and the GPIO is controlled by
+ * sam3u_spiselect, then the same CS register may be used to control
+ * multiple devices.
+ *
+ * Input Parameters:
+ * dev - SPI device info
+ * devid - Identifies the (logical) device
+ *
+ * Returned Values:
+ * On success, a CS number from 0 to 3 is returned; A negated errno may
+ * be returned on a failure.
+ *
+ ****************************************************************************/
+
+EXTERN int sam3u_spicsnumber(enum spi_dev_e devid);
+
+/****************************************************************************
+ * Name: sam3u_spiselect
+ *
+ * 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
+ *
+ ****************************************************************************/
+
+EXTERN void sam3u_spiselect(enum spi_dev_e devid, bool selected);
+
+/****************************************************************************
+ * Name: sam3u_spistatus
+ *
+ * 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.h.
+ *
+ ****************************************************************************/
+
+EXTERN uint8_t sam3u_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+
+/****************************************************************************
+ * Name: sam3u_spicmddata
+ *
+ * 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
+EXTERN int sam3u_spicmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+#endif
+#endif /* CONFIG_SAM3U_SPI */
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_SAM3U_SAM3U_INTERNAL_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_irq.c b/nuttx/arch/arm/src/sam3u/sam3u_irq.c
new file mode 100644
index 000000000..db79314c0
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_irq.c
@@ -0,0 +1,461 @@
+/****************************************************************************
+ * arch/arm/src/sam3u/sam3u_irq.c
+ * arch/arm/src/chip/sam3u_irq.c
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "nvic.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+#include "sam3u_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* Enable NVIC debug features that are probably only desireable during
+ * bringup
+ */
+
+#undef SAM3U_IRQ_DEBUG
+
+/* 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
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam3u_dumpnvic
+ *
+ * Description:
+ * Dump some interesting NVIC registers
+ *
+ ****************************************************************************/
+
+#if defined(SAM3U_IRQ_DEBUG) && defined (CONFIG_DEBUG)
+static void sam3u_dumpnvic(const char *msg, int irq)
+{
+ irqstate_t flags;
+
+ flags = irqsave();
+ slldbg("NVIC (%s, irq=%d):\n", msg, irq);
+ slldbg(" INTCTRL: %08x VECTAB: %08x\n",
+ getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB));
+#if 0
+ slldbg(" 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
+ slldbg(" IRQ ENABLE: %08x\n", getreg32(NVIC_IRQ0_31_ENABLE));
+ slldbg(" SYSH_PRIO: %08x %08x %08x\n",
+ getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY),
+ getreg32(NVIC_SYSH12_15_PRIORITY));
+ slldbg(" 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));
+ slldbg(" %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));
+ irqrestore(flags);
+}
+#else
+# define sam3u_dumpnvic(msg, irq)
+#endif
+
+/****************************************************************************
+ * Name: sam3u_nmi, sam3u_busfault, sam3u_usagefault, sam3u_pendsv,
+ * sam3u_dbgmonitor, sam3u_pendsv, sam3u_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 sam3u_nmi(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! NMI received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int sam3u_busfault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Bus fault recived\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int sam3u_usagefault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Usage fault received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int sam3u_pendsv(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! PendSV received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int sam3u_dbgmonitor(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Debug Monitor receieved\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int sam3u_reserved(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Reserved interrupt\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: sam3u_irqinfo
+ *
+ * Description:
+ * Given an IRQ number, provide the register and bit setting to enable or
+ * disable the irq.
+ *
+ ****************************************************************************/
+
+static int sam3u_irqinfo(int irq, uint32_t *regaddr, uint32_t *bit)
+{
+ DEBUGASSERT(irq >= SAM3U_IRQ_NMI && irq < NR_IRQS);
+
+ /* Check for external interrupt */
+
+ if (irq >= SAM3U_IRQ_EXTINT)
+ {
+ if (irq < SAM3U_IRQ_NIRQS)
+ {
+ *regaddr = NVIC_IRQ0_31_ENABLE;
+ *bit = 1 << (irq - SAM3U_IRQ_EXTINT);
+ }
+ else
+ {
+ return ERROR; /* Invalid interrupt */
+ }
+ }
+
+ /* Handle processor exceptions. Only a few can be disabled */
+
+ else
+ {
+ *regaddr = NVIC_SYSHCON;
+ if (irq == SAM3U_IRQ_MEMFAULT)
+ {
+ *bit = NVIC_SYSHCON_MEMFAULTENA;
+ }
+ else if (irq == SAM3U_IRQ_BUSFAULT)
+ {
+ *bit = NVIC_SYSHCON_BUSFAULTENA;
+ }
+ else if (irq == SAM3U_IRQ_USAGEFAULT)
+ {
+ *bit = NVIC_SYSHCON_USGFAULTENA;
+ }
+ else if (irq == SAM3U_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)
+{
+ /* Disable all interrupts */
+
+ putreg32(0, NVIC_IRQ0_31_ENABLE);
+
+ /* Set up the vector table address */
+
+#ifdef CONFIG_SAM3U_DFU
+ putreg32((uint32_t)sam3u_vectors, NVIC_VECTAB);
+#endif
+
+ /* Set all interrrupts (and exceptions) to the default priority */
+
+ putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);
+
+ putreg32(DEFPRIORITY32, NVIC_IRQ0_3_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ4_7_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ8_11_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ12_15_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ16_19_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ20_23_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ24_27_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_IRQ28_31_PRIORITY);
+
+ /* 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(SAM3U_IRQ_SVCALL, up_svcall);
+ irq_attach(SAM3U_IRQ_HARDFAULT, up_hardfault);
+
+ /* Set the priority of the SVCall interrupt */
+
+#ifdef CONFIG_ARCH_IRQPRIO
+/* up_prioritize_irq(SAM3U_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
+#endif
+
+ /* If the MPU is enabled, then attach and enable the Memory Management
+ * Fault handler.
+ */
+
+#ifdef CONFIG_ARMV7M_MPU
+ irq_attach(SAM3U_IRQ_MEMFAULT, up_memfault);
+ up_enable_irq(SAM3U_IRQ_MEMFAULT);
+#endif
+
+ /* Attach all other processor exceptions (except reset and sys tick) */
+
+#ifdef CONFIG_DEBUG
+ irq_attach(SAM3U_IRQ_NMI, sam3u_nmi);
+#ifndef CONFIG_ARMV7M_MPU
+ irq_attach(SAM3U_IRQ_MEMFAULT, up_memfault);
+#endif
+ irq_attach(SAM3U_IRQ_BUSFAULT, sam3u_busfault);
+ irq_attach(SAM3U_IRQ_USAGEFAULT, sam3u_usagefault);
+ irq_attach(SAM3U_IRQ_PENDSV, sam3u_pendsv);
+ irq_attach(SAM3U_IRQ_DBGMONITOR, sam3u_dbgmonitor);
+ irq_attach(SAM3U_IRQ_RESERVED, sam3u_reserved);
+#endif
+
+ sam3u_dumpnvic("initial", SAM3U_IRQ_NIRQS);
+
+#ifndef CONFIG_SUPPRESS_INTERRUPTS
+
+ /* Initialize logic to support a second level of interrupt decoding for
+ * GPIO pins.
+ */
+
+#ifdef CONFIG_GPIO_IRQ
+ sam3u_gpioirqinitialize();
+#endif
+
+ /* And finally, enable interrupts */
+
+ setbasepri(NVIC_SYSH_PRIORITY_MAX);
+ irqrestore(0);
+#endif
+}
+
+/****************************************************************************
+ * Name: up_disable_irq
+ *
+ * Description:
+ * Disable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_disable_irq(int irq)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (sam3u_irqinfo(irq, &regaddr, &bit) == 0)
+ {
+ /* Clear the appropriate bit in the register to enable the interrupt */
+
+ regval = getreg32(regaddr);
+ regval &= ~bit;
+ putreg32(regval, regaddr);
+ }
+#ifdef CONFIG_GPIO_IRQ
+ else
+ {
+ /* Maybe it is a (derived) GPIO IRQ */
+
+ sam3u_gpioirqdisable(irq);
+ }
+#endif
+ sam3u_dumpnvic("disable", irq);
+}
+
+/****************************************************************************
+ * Name: up_enable_irq
+ *
+ * Description:
+ * Enable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_enable_irq(int irq)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (sam3u_irqinfo(irq, &regaddr, &bit) == 0)
+ {
+ /* Set the appropriate bit in the register to enable the interrupt */
+
+ regval = getreg32(regaddr);
+ regval |= bit;
+ putreg32(regval, regaddr);
+ }
+#ifdef CONFIG_GPIO_IRQ
+ else
+ {
+ /* Maybe it is a (derived) GPIO IRQ */
+
+ sam3u_gpioirqenable(irq);
+ }
+#endif
+ sam3u_dumpnvic("enable", irq);
+}
+
+/****************************************************************************
+ * Name: up_maskack_irq
+ *
+ * Description:
+ * Mask the IRQ and acknowledge it
+ *
+ ****************************************************************************/
+
+void up_maskack_irq(int irq)
+{
+ up_disable_irq(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 >= SAM3U_IRQ_MEMFAULT && irq < SAM3U_IRQ_NIRQS && (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
+
+ if (irq < SAM3U_IRQ_EXTINT)
+ {
+ irq -= 4;
+ regaddr = NVIC_SYSH_PRIORITY(irq);
+ }
+ else
+ {
+ irq -= SAM3U_IRQ_EXTINT;
+ regaddr = NVIC_IRQ_PRIORITY(irq);
+ }
+
+ regval = getreg32(regaddr);
+ shift = ((irq & 3) << 3);
+ regval &= ~(0xff << shift);
+ regval |= (priority << shift);
+ putreg32(regval, regaddr);
+
+ sam3u_dumpnvic("prioritize", irq);
+ return OK;
+}
+#endif
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_lowputc.c b/nuttx/arch/arm/src/sam3u/sam3u_lowputc.c
new file mode 100644
index 000000000..7a1e74248
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_lowputc.c
@@ -0,0 +1,333 @@
+/**************************************************************************
+ * arch/arm/src/sam3u/sam3u_lowputc.c
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "sam3u_internal.h"
+#include "sam3u_pmc.h"
+#include "sam3u_uart.h"
+
+/**************************************************************************
+ * Private 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_SAM3U_USART0
+#endif
+#ifndef CONFIG_USART1_ISUART
+# undef CONFIG_SAM3U_USART1
+#endif
+#ifndef CONFIG_USART2_ISUART
+# undef CONFIG_SAM3U_USART2
+#endif
+#ifndef CONFIG_USART3_ISUART
+# undef CONFIG_SAM3U_USART3
+#endif
+
+/* Is there a serial console? It could be on the UART, or USARTn */
+
+#if defined(CONFIG_UART_SERIAL_CONSOLE) && defined(CONFIG_SAM3U_UART)
+# 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_SAM3U_USART0)
+# undef CONFIG_USART_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_SAM3U_USART1)
+# undef CONFIG_USART_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_SAM3U_USART2)
+# undef CONFIG_USART_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_SAM3U_USART3)
+# undef CONFIG_USART_SERIAL_CONSOLE
+# undef CONFIG_USART0_SERIAL_CONSOLE
+# undef CONFIG_USART1_SERIAL_CONSOLE
+# undef CONFIG_USART2_SERIAL_CONSOLE
+# define HAVE_CONSOLE 1
+#else
+# undef CONFIG_USART_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
+
+/* Select USART parameters for the selected console */
+
+#if defined(CONFIG_UART_SERIAL_CONSOLE)
+# define SAM3U_CONSOLE_BASE SAM3U_UART_BASE
+# define SAM3U_CONSOLE_BAUD CONFIG_UART_BAUD
+# define SAM3U_CONSOLE_BITS CONFIG_UART_BITS
+# define SAM3U_CONSOLE_PARITY CONFIG_UART_PARITY
+# define SAM3U_CONSOLE_2STOP CONFIG_UART_2STOP
+#elif defined(CONFIG_USART0_SERIAL_CONSOLE)
+# define SAM3U_CONSOLE_BASE SAM3U_USART0_BASE
+# define SAM3U_CONSOLE_BAUD CONFIG_USART0_BAUD
+# define SAM3U_CONSOLE_BITS CONFIG_USART0_BITS
+# define SAM3U_CONSOLE_PARITY CONFIG_USART0_PARITY
+# define SAM3U_CONSOLE_2STOP CONFIG_USART0_2STOP
+#elif defined(CONFIG_USART1_SERIAL_CONSOLE)
+# define SAM3U_CONSOLE_BASE SAM3U_USART1_BASE
+# define SAM3U_CONSOLE_BAUD CONFIG_USART1_BAUD
+# define SAM3U_CONSOLE_BITS CONFIG_USART1_BITS
+# define SAM3U_CONSOLE_PARITY CONFIG_USART1_PARITY
+# define SAM3U_CONSOLE_2STOP CONFIG_USART1_2STOP
+#elif defined(CONFIG_USART2_SERIAL_CONSOLE)
+# define SAM3U_CONSOLE_BASE SAM3U_USART2_BASE
+# define SAM3U_CONSOLE_BAUD CONFIG_USART2_BAUD
+# define SAM3U_CONSOLE_BITS CONFIG_USART2_BITS
+# define SAM3U_CONSOLE_PARITY CONFIG_USART2_PARITY
+# define SAM3U_CONSOLE_2STOP CONFIG_USART2_2STOP
+#elif defined(CONFIG_USART3_SERIAL_CONSOLE)
+# define SAM3U_CONSOLE_BASE SAM3U_USART3_BASE
+# define SAM3U_CONSOLE_BAUD CONFIG_USART3_BAUD
+# define SAM3U_CONSOLE_BITS CONFIG_USART3_BITS
+# define SAM3U_CONSOLE_PARITY CONFIG_USART3_PARITY
+# define SAM3U_CONSOLE_2STOP CONFIG_USART3_2STOP
+#else
+# error "No CONFIG_U[S]ARTn_SERIAL_CONSOLE Setting"
+#endif
+
+/* Select the settings for the mode register */
+
+#if SAM3U_CONSOLE_BITS == 5
+# define MR_CHRL_VALUE USART_MR_CHRL_5BITS /* 5 bits */
+#elif SAM3U_CONSOLE_BITS == 6
+# define MR_CHRL_VALUE USART_MR_CHRL_6BITS /* 6 bits */
+#elif SAM3U_CONSOLE_BITS == 7
+# define MR_CHRL_VALUE USART_MR_CHRL_7BITS /* 7 bits */
+#elif SAM3U_CONSOLE_BITS == 8
+# define MR_CHRL_VALUE USART_MR_CHRL_8BITS /* 8 bits */
+#elif SAM3U_CONSOLE_BITS == 9 && !defined(CONFIG_UART_SERIAL_CONSOLE)
+# define MR_CHRL_VALUE USART_MR_MODE9
+#else
+# error "Invlaid number of bits"
+#endif
+
+#if SAM3U_CONSOLE_PARITY == 1
+# define MR_PAR_VALUE UART_MR_PAR_ODD
+#elif SAM3U_CONSOLE_PARITY == 2
+# define MR_PAR_VALUE UART_MR_PAR_EVEN
+#else
+# define MR_PAR_VALUE UART_MR_PAR_NONE
+#endif
+
+#if SAM3U_CONSOLE_2STOP != 0
+# define MR_NBSTOP_VALUE USART_MR_NBSTOP_2
+#else
+# define MR_NBSTOP_VALUE USART_MR_NBSTOP_1
+#endif
+
+#define MR_VALUE (USART_MR_MODE_NORMAL|USART_MR_USCLKS_MCK|MR_CHRL_VALUE|MR_PAR_VALUE|MR_NBSTOP_VALUE)
+
+/**************************************************************************
+ * Private Types
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Function Prototypes
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Functions
+ **************************************************************************/
+
+/**************************************************************************
+ * Public Functions
+ **************************************************************************/
+
+/**************************************************************************
+ * Name: up_lowputc
+ *
+ * Description:
+ * Output one byte on the serial console
+ *
+ **************************************************************************/
+
+void up_lowputc(char ch)
+{
+ /* Wait for the transmitter to be available */
+
+ while ((getreg32(SAM3U_CONSOLE_BASE+SAM3U_UART_SR_OFFSET) & UART_INT_TXEMPTY) == 0);
+
+ /* Send the character */
+
+ putreg32((uint32_t)ch, SAM3U_CONSOLE_BASE+SAM3U_UART_THR_OFFSET);
+}
+
+/**************************************************************************
+ * Name: sam3u_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 sam3u_lowsetup(void)
+{
+ uint32_t regval;
+
+ /* Enable clocking for all selected UART/USARTs */
+
+ regval = 0;
+#ifdef CONFIG_SAM3U_UART
+ regval |= (1 << SAM3U_PID_UART);
+#endif
+#ifdef CONFIG_SAM3U_USART0
+ regval |= (1 << SAM3U_PID_USART0);
+#endif
+#ifdef CONFIG_SAM3U_USART1
+ regval |= (1 << SAM3U_PID_USART1);
+#endif
+#ifdef CONFIG_SAM3U_USART2
+ regval |= (1 << SAM3U_PID_USART2);
+#endif
+#ifdef CONFIG_SAM3U_USART3
+ regval |= (1 << SAM3U_PID_USART3);
+#endif
+ putreg32(regval, SAM3U_PMC_PCER);
+
+ /* Configure UART pins for all selected UART/USARTs */
+
+#ifdef CONFIG_SAM3U_UART
+ (void)sam3u_configgpio(GPIO_UART_RXD);
+ (void)sam3u_configgpio(GPIO_UART_TXD);
+#endif
+#ifdef CONFIG_SAM3U_USART0
+ (void)sam3u_configgpio(GPIO_USART0_RXD);
+ (void)sam3u_configgpio(GPIO_USART0_TXD);
+ (void)sam3u_configgpio(GPIO_USART0_CTS);
+ (void)sam3u_configgpio(GPIO_USART0_RTS);
+#endif
+#ifdef CONFIG_SAM3U_USART1
+ (void)sam3u_configgpio(GPIO_USART1_RXD);
+ (void)sam3u_configgpio(GPIO_USART1_TXD);
+ (void)sam3u_configgpio(GPIO_USART1_CTS);
+ (void)sam3u_configgpio(GPIO_USART1_RTS);
+#endif
+#ifdef CONFIG_SAM3U_USART2
+ (void)sam3u_configgpio(GPIO_USART2_RXD);
+ (void)sam3u_configgpio(GPIO_USART2_TXD);
+ (void)sam3u_configgpio(GPIO_USART2_CTS);
+ (void)sam3u_configgpio(GPIO_USART2_RTS);
+#endif
+#ifdef CONFIG_SAM3U_USART3
+ (void)sam3u_configgpio(GPIO_USART3_RXD);
+ (void)sam3u_configgpio(GPIO_USART3_TXD);
+ (void)sam3u_configgpio(GPIO_USART3_CTS);
+ (void)sam3u_configgpio(GPIO_USART3_RTS);
+#endif
+
+#ifdef GPIO_CONSOLE_RXD
+#endif
+#ifdef GPIO_CONSOLE_TXD
+ (void)sam3u_configgpio(GPIO_CONSOLE_TXD);
+#endif
+#ifdef GPIO_CONSOLE_CTS
+ (void)sam3u_configgpio(GPIO_CONSOLE_CTS);
+#endif
+#ifdef GPIO_CONSOLE_RTS
+ (void)sam3u_configgpio(GPIO_CONSOLE_RTS);
+#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),
+ SAM3U_CONSOLE_BASE+SAM3U_UART_CR_OFFSET);
+
+ /* Disable all interrupts */
+
+ putreg32(0xffffffff, SAM3U_CONSOLE_BASE+SAM3U_UART_IDR_OFFSET);
+
+ /* Set up the mode register */
+
+ putreg32(MR_VALUE, SAM3U_CONSOLE_BASE+SAM3U_UART_MR_OFFSET);
+
+ /* Configure the console baud */
+
+ putreg32(((SAM3U_MCK_FREQUENCY + (SAM3U_CONSOLE_BAUD << 3))/(SAM3U_CONSOLE_BAUD << 4)),
+ SAM3U_CONSOLE_BASE+SAM3U_UART_BRGR_OFFSET);
+
+ /* Enable receiver & transmitter */
+
+ putreg32((UART_CR_RXEN|UART_CR_TXEN),
+ SAM3U_CONSOLE_BASE+SAM3U_UART_CR_OFFSET);
+#endif
+}
+
+
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_matrix.h b/nuttx/arch/arm/src/sam3u/sam3u_matrix.h
new file mode 100644
index 000000000..52232bfa5
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_matrix.h
@@ -0,0 +1,214 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_matric.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_MATRIX_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_MATRIX_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* MATRIX register offsets **************************************************************/
+
+#define SAM3U_MATRIX_MCFG_OFFSET(n) ((n)<<2)
+#define SAM3U_MATRIX_MCFG0_OFFSET 0x0000 /* Master Configuration Register 0 */
+#define SAM3U_MATRIX_MCFG1_OFFSET 0x0004 /* Master Configuration Register 1 */
+#define SAM3U_MATRIX_MCFG2_OFFSET 0x0008 /* Master Configuration Register 2 */
+#define SAM3U_MATRIX_MCFG3_OFFSET 0x000c /* Master Configuration Register 3 */
+#define SAM3U_MATRIX_MCFG4_OFFSET 0x0010 /* Master Configuration Register 4 */
+ /* 0x0014-0x003c: Reserved */
+#define SAM3U_MATRIX_SCFG_OFFSET(n) (0x0040+((n)<<2))
+#define SAM3U_MATRIX_SCFG0_OFFSET 0x0040 /* Slave Configuration Register 0 */
+#define SAM3U_MATRIX_SCFG1_OFFSET 0x0044 /* Slave Configuration Register 1 */
+#define SAM3U_MATRIX_SCFG2_OFFSET 0x0048 /* Slave Configuration Register 2 */
+#define SAM3U_MATRIX_SCFG3_OFFSET 0x004c /* Slave Configuration Register 3 */
+#define SAM3U_MATRIX_SCFG4_OFFSET 0x0050 /* Slave Configuration Register 4 */
+#define SAM3U_MATRIX_SCFG5_OFFSET 0x0054 /* Slave Configuration Register 5 */
+#define SAM3U_MATRIX_SCFG6_OFFSET 0x0058 /* Slave Configuration Register 6 */
+#define SAM3U_MATRIX_SCFG7_OFFSET 0x005c /* Slave Configuration Register 7 */
+#define SAM3U_MATRIX_SCFG8_OFFSET 0x0060 /* Slave Configuration Register 8 */
+#define SAM3U_MATRIX_SCFG9_OFFSET 0x0064 /* Slave Configuration Register 9 */
+ /* 0x0068-0x007c: Reserved */
+#define SAM3U_MATRIX_PRAS_OFFSET(n) (0x0080+((n)<<3))
+#define SAM3U_MATRIX_PRAS0_OFFSET 0x0080 /* Priority Register A for Slave 0 */
+ /* 0x0084: Reserved */
+#define SAM3U_MATRIX_PRAS1_OFFSET 0x0088 /* Priority Register A for Slave 1 */
+ /* 0x008c: Reserved */
+#define SAM3U_MATRIX_PRAS2_OFFSET 0x0090 /* Priority Register A for Slave 2 */
+ /* 0x0094: Reserved */
+#define SAM3U_MATRIX_PRAS3_OFFSET 0x0098 /* Priority Register A for Slave 3 */
+ /* 0x009c: Reserved */
+#define SAM3U_MATRIX_PRAS4_OFFSET 0x00a0 /* Priority Register A for Slave 4 */
+ /* 0x00a4: Reserved */
+#define SAM3U_MATRIX_PRAS5_OFFSET 0x00a8 /* Priority Register A for Slave 5 */
+ /* 0x00ac: Reserved */
+#define SAM3U_MATRIX_PRAS6_OFFSET 0x00b0 /* Priority Register A for Slave 6 */
+ /* 0x00b4: Reserved */
+#define SAM3U_MATRIX_PRAS7_OFFSET 0x00b8 /* Priority Register A for Slave 7 */
+ /* 0x00bc: Reserved */
+#define SAM3U_MATRIX_PRAS8_OFFSET 0x00c0 /* Priority Register A for Slave 8 */
+ /* 0x00c4: Reserved */
+#define SAM3U_MATRIX_PRAS9_OFFSET 0x00c8 /* Priority Register A for Slave 9 */
+ /* 0x00cc-0x00fc: Reserved */
+#define SAM3U_MATRIX_MRCR_OFFSET 0x0100 /* Master Remap Control Register */
+ /* 0x0104-0x010c: Reserved */
+#define SAM3U_MATRIX_WPMR_OFFSET 0x01e4 /* Write Protect Mode Register */
+#define SAM3U_MATRIX_WPSR_OFFSET 0x01e8 /* Write Protect Status Register */
+ /* 0x0110 - 0x01fc: Reserved */
+
+/* MATRIX register adresses *************************************************************/
+
+#define SAM3U_MATRIX_MCFG(n)) (SAM3U_MATRIX_BASE+SAM3U_MATRIX_MCFG_OFFSET(n))
+#define SAM3U_MATRIX_MCFG0 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_MCFG0_OFFSET)
+#define SAM3U_MATRIX_MCFG1 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_MCFG1_OFFSET)
+#define SAM3U_MATRIX_MCFG2 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_MCFG2_OFFSET)
+#define SAM3U_MATRIX_MCFG3 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_MCFG3_OFFSET)
+#define SAM3U_MATRIX_MCFG4 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_MCFG4_OFFSET)
+
+#define SAM3U_MATRIX_SCFG(n) (SAM3U_MATRIX_BASE+SAM3U_MATRIX_SCFG_OFFSET(n))
+#define SAM3U_MATRIX_SCFG0 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_SCFG0_OFFSET)
+#define SAM3U_MATRIX_SCFG1 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_SCFG1_OFFSET)
+#define SAM3U_MATRIX_SCFG2 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_SCFG2_OFFSET)
+#define SAM3U_MATRIX_SCFG3 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_SCFG3_OFFSET)
+#define SAM3U_MATRIX_SCFG4 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_SCFG4_OFFSET)
+#define SAM3U_MATRIX_SCFG5 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_SCFG5_OFFSET)
+#define SAM3U_MATRIX_SCFG6 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_SCFG6_OFFSET)
+#define SAM3U_MATRIX_SCFG7 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_SCFG7_OFFSET)
+#define SAM3U_MATRIX_SCFG8 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_SCFG8_OFFSET)
+#define SAM3U_MATRIX_SCFG9 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_SCFG9_OFFSET)
+
+#define SAM3U_MATRIX_PRAS(n) (SAM3U_MATRIX_BASE+SAM3U_MATRIX_PRAS_OFFSET(n))
+#define SAM3U_MATRIX_PRAS0 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_PRAS0_OFFSET)
+#define SAM3U_MATRIX_PRAS1 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_PRAS1_OFFSET)
+#define SAM3U_MATRIX_PRAS2 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_PRAS2_OFFSET)
+#define SAM3U_MATRIX_PRAS3 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_PRAS3_OFFSET)
+#define SAM3U_MATRIX_PRAS4 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_PRAS4_OFFSET)
+#define SAM3U_MATRIX_PRAS5 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_PRAS5_OFFSET)
+#define SAM3U_MATRIX_PRAS6 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_PRAS6_OFFSET)
+#define SAM3U_MATRIX_PRAS7 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_PRAS7_OFFSET)
+#define SAM3U_MATRIX_PRAS8 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_PRAS8_OFFSET)
+#define SAM3U_MATRIX_PRAS9 (SAM3U_MATRIX_BASE+SAM3U_MATRIX_PRAS9_OFFSET)
+
+#define SAM3U_MATRIX_MRCR (SAM3U_MATRIX_BASE+SAM3U_MATRIX_MRCR_OFFSET)
+#define SAM3U_MATRIX_WPMR (SAM3U_MATRIX_BASE+SAM3U_MATRIX_WPMR_OFFSET)
+#define SAM3U_MATRIX_WPSR (SAM3U_MATRIX_BASE+SAM3U_MATRIX_WPSR_OFFSET)
+
+/* MATRIX register bit definitions ******************************************************/
+
+#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) /* Four Beat Burst */
+# define MATRIX_MCFG_ULBT_8BEAT (3 << MATRIX_MCFG_ULBT_SHIFT) /* Eight Beat Burst */
+# define MATRIX_MCFG_ULBT_16BEAT (4 << MATRIX_MCFG_ULBT_SHIFT) /* Sixteen Beat Burst */
+
+#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_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_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)
+
+#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 */
+
+#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_M1PR_SHIFT (4) /* Bits 4-5: Master 1 Priority */
+#define MATRIX_PRAS_M1PR_MASK (3 << 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_M3PR_SHIFT (12) /* Bits 12-13: Master 3 Priority */
+#define MATRIX_PRAS_M3PR_MASK (3 << 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_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 */
+
+#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_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_SAM3U_SAM3U_MATRIX_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_memorymap.h b/nuttx/arch/arm/src/sam3u/sam3u_memorymap.h
new file mode 100644
index 000000000..81027f7b4
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_memorymap.h
@@ -0,0 +1,145 @@
+/************************************************************************************************
+ * arch/arm/src/sam3u/sam3u_memorymap.h
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_MEMORYMAP_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_MEMORYMAP_H
+
+/************************************************************************************************
+ * Included Files
+ ************************************************************************************************/
+
+#include <nuttx/config.h>
+#include "chip.h"
+
+/************************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************************/
+
+#define SAM3U_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: Code space */
+# define SAM3U_BOOTMEMORY_BASE 0x00000000 /* 0x00000000-0x0007ffff: Boot Memory */
+# define SAM3U_INTFLASH0_BASE 0x00080000 /* 0x00080000-0x000fffff: Internal FLASH 0 */
+# define SAM3U_INTFLASH1_BASE 0x00100000 /* 0x00100000-0x0017ffff: Internal FLASH 1 */
+# define SAM3U_INTROM_BASE 0x00180000 /* 0x00180000-0x001fffff: Internal ROM */
+ /* 0x00200000-0x1fffffff: Reserved */
+#define SAM3U_INTSRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: Internal SRAM */
+# define SAM3U_INTSRAM0_BASE 0x20000000 /* 0x20000000-0x2007ffff: SRAM0 (see chip.h) */
+# define SAM3U_INTSRAM1_BASE 0x20080000 /* 0x20080000-0x200fffff: SRAM1 (see chip.h) */
+# define SAM3U_NFCSRAM_BASE 0x20100000 /* 0x20100000-0x207fffff: NAND FLASH controller (SRAM) */
+# define SAM3U_UDPHPSDMS_BASE 0x20180000 /* 0x20180000-0x201fffff: USB Device High Speed (DMA) */
+ /* 0x20200000-0x2fffffff: Undefined */
+# define SAM3U_BBSRAM_BASE 0x22000000 /* 0x22000000-0x23ffffff: 32Mb bit-band alias */
+ /* 0x24000000-0x3fffffff: Undefined */
+#define SAM3U_PERIPHERALS_BASE 0x40000000 /* 0x40000000-0x5fffffff: Peripherals */
+# define SAM3U_MCI_BASE 0x40000000 /* 0x40000000-0x400003ff: High Speed Multimedia Card Interface */
+# define SAM3U_SSC_BASE 0x40004000 /* 0x40004000-0x40007fff: Synchronous Serial Controller */
+# define SAM3U_SPI_BASE 0x40008000 /* 0x40008000-0x4000bfff: Serial Peripheral Interface */
+ /* 0x4000c000-0x4007ffff: Reserved */
+# define SAM3U_TC_BASE 0x40080000 /* 0x40080000-0x40083fff: Timer Counters */
+# define SAM3U_TCN_BASE(n) (0x40080000+((n)<<6))
+# define SAM3U_TC0_BASE 0x40080000 /* 0x40080000-0x4008003f: Timer Counter 0 */
+# define SAM3U_TC1_BASE 0x40080040 /* 0x40080040-0x4008007f: Timer Counter 1 */
+# define SAM3U_TC2_BASE 0x40080080 /* 0x40080080-0x400800bf: Timer Counter 2 */
+# define SAM3U_TWI_BASE 0x40084000 /* 0x40084000-0x4008ffff: Two-Wire Interface */
+# define SAM3U_TWIN_BASE(n) (0x40084000+((n)<<14))
+# define SAM3U_TWI0_BASE 0x40084000 /* 0x40084000-0x40087fff: Two-Wire Interface 0 */
+# define SAM3U_TWI1_BASE 0x40088000 /* 0x40088000-0x4008bfff: Two-Wire Interface 1 */
+# define SAM3U_PWM_BASE 0x4008c000 /* 0x4008c000-0x4008ffff: Pulse Width Modulation Controller */
+# define SAM3U_USART_BASE 0x40090000 /* 0x40090000-0x4009ffff: USART */
+# define SAM3U_USARTN_BASE(n) (0x40090000+((n)<<14))
+# define SAM3U_USART0_BASE 0x40090000 /* 0x40090000-0x40093fff: USART0 */
+# define SAM3U_USART1_BASE 0x40094000 /* 0x40094000-0x40097fff: USART1 */
+# define SAM3U_USART2_BASE 0x40098000 /* 0x40098000-0x4009bfff: USART2 */
+# define SAM3U_USART3_BASE 0x4009c000 /* 0x4009c000-0x4009ffff: USART3 */
+ /* 0x400a0000-0x400a3fff: Reserved */
+# define SAM3U_UDPHS_BASE 0x400a4000 /* 0x400a4000-0x400a7fff: USB Device High Speed */
+# define SAM3U_ADC12B_BASE 0x400a8000 /* 0x400a8000-0x400abfff: 12-bit ADC Controller */
+# define SAM3U_ADC_BASE 0x400ac000 /* 0x400ac000-0x400affff: 10-bit ADC Controller */
+# define SAM3U_DMAC_BASE 0x400b0000 /* 0x400b0000-0x400b3fff: DMA controller */
+ /* 0x400b4000-0x400dffff: Reserved */
+# define SAM3U_SYSCTRLR_BASE 0x400e0000 /* 0x400e0000-0x400e25ff: System controller */
+ /* 0x400e2600-0x400fffff: Reserved */
+ /* 0x40100000-0x41ffffff: Reserved */
+# define SAM3U_BBPERIPH__BASE 0x42000000 /* 0x42000000-0x43ffffff: 32Mb bit-band alias */
+ /* 0x44000000-0x5fffffff: Reserved */
+#define SAM3U_EXTSRAM_BASE 0x60000000 /* 0x60000000-0x9fffffff: External SRAM */
+# define SAM3U_EXTCS_BASE 0x60000000 /* 0x60000000-0x63ffffff: Chip selects */
+# define SAM3U_EXTCSN_BASE(n) (0x60000000*((n)<<24))
+# define SAM3U_EXTCS0_BASE 0x60000000 /* 0x60000000-0x60ffffff: Chip select 0 */
+# define SAM3U_EXTCS1_BASE 0x61000000 /* 0x61000000-0x601fffff: Chip select 1 */
+# define SAM3U_EXTCS2_BASE 0x62000000 /* 0x62000000-0x62ffffff: Chip select 2 */
+# define SAM3U_EXTCS3_BASE 0x63000000 /* 0x63000000-0x63ffffff: Chip select 3 */
+ /* 0x64000000-0x67ffffff: Reserved */
+# define SAM3U_NFC_BASE 0x68000000 /* 0x68000000-0x68ffffff: NAND FLASH controller */
+ /* 0x69000000-0x9fffffff: Reserved */
+ /* 0xa0000000-0xdfffffff: Reserved */
+#define SAM3U_SYSTEM_BASE 0xe0000000 /* 0xe0000000-0xffffffff: System */
+
+/* System Controller Register Blocks: 0x400e0000-0x4007ffff */
+
+#define SAM3U_SMC_BASE 0x400e0000 /* 0x400e0000-0x400e01ff: Static Memory Controller */
+#define SAM3U_MATRIX_BASE 0x400e0200 /* 0x400e0200-0x400e03ff: MATRIX */
+#define SAM3U_PMC_BASE 0x400e0400 /* 0x400e0400-0x400e05ff: Power Management Controller */
+#define SAM3U_UART_BASE 0x400e0600 /* 0x400e0600-0x400e073f: UART */
+#define SAM3U_CHIPID_BASE 0x400e0740 /* 0x400e0740-0x400e07ff: CHIP ID */
+#define SAM3U_EEFC_BASE 0x400e0800 /* 0x400e0800-0x400e0bff: Enhanced Embedded Flash Controllers*/
+# define SAM3U_EEFCN_BASE(n) (0x400e0800+((n)<<9))
+# define SAM3U_EEFC0_BASE 0x400e0800 /* 0x400e0800-0x400e09ff: Enhanced Embedded Flash Controller 0 */
+# define SAM3U_EEFC1_BASE 0x400e0a00 /* 0x400e0a00-0x400e0bff: Enhanced Embedded Flash Controller 1 */
+#define SAM3U_PIO_BASE 0x400e0c00 /* 0x400e0c00-0x400e11ff: Parallel I/O Controllers */
+# define SAM3U_PION_BASE(n) (0x400e0c00+((n)<<9))
+# define SAM3U_PIOA_BASE 0x400e0c00 /* 0x400e0c00-0x400e0dff: Parallel I/O Controller A */
+# define SAM3U_PIOB_BASE 0x400e0e00 /* 0x400e0e00-0x400e0fff: Parallel I/O Controller B */
+# define SAM3U_PIOC_BASE 0x400e1000 /* 0x400e1000-0x400e11ff: Parallel I/O Controller C */
+#define SAM3U_RSTC_BASE 0x400e1200 /* 0x400e1200-0x400e120f: Reset Controller */
+#define SAM3U_SUPC_BASE 0x400e1210 /* 0x400e1210-0x400e122f: Supply Controller */
+#define SAM3U_RTT_BASE 0x400e1230 /* 0x400e1230-0x400e124f: Real Time Timer */
+#define SAM3U_WDT_BASE 0x400e1250 /* 0x400e1250-0x400e125f: Watchdog Timer */
+#define SAM3U_RTC_BASE 0x400e1260 /* 0x400e1260-0x400e128f: Real Time Clock */
+#define SAM3U_GPBR_BASE 0x400e1290 /* 0x400e1290-0x400e13ff: GPBR */
+ /* 0x490e1400-0x4007ffff: Reserved */
+
+/************************************************************************************************
+ * Public Types
+ ************************************************************************************************/
+
+/************************************************************************************************
+ * Public Data
+ ************************************************************************************************/
+
+/************************************************************************************************
+ * Public Functions
+ ************************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_SAM3U_SAM3U_MEMORYMAP_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_mpuinit.c b/nuttx/arch/arm/src/sam3u/sam3u_mpuinit.c
new file mode 100644
index 000000000..c6788d3b5
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_mpuinit.c
@@ -0,0 +1,122 @@
+/****************************************************************************
+ * arch/arm/src/common/sam3u_mpuinit.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <arch/board/user_map.h>
+#include "mpu.h"
+
+#ifdef CONFIG_NUTTX_KERNEL
+
+/****************************************************************************
+ * Private 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: sam3u_mpuinitialize
+ *
+ * Description:
+ * Configure the MPU to permit user-space access to only restricted SAM3U
+ * resources.
+ *
+ ****************************************************************************/
+
+void sam3u_mpuinitialize(void)
+{
+ uintptr_t datastart = MIN(ONFIG_USER_DATADESTSTART, CONFIG_USER_BSSSTART);
+ uintptr_t dataend = MAX(ONFIG_USER_DATADESTEND, CONFIG_USER_BSSEND);
+
+ DEBUGASSERT(CONFIG_USER_TEXTEND >= CONFIG_USER_TEXTSTART && dataend >= datastart);
+
+ @echo "#define C 0x`grep \" _stext\" $(TOPDIR)/User.map | cut -d' ' -f1`" >> $(BOARD_INCLUDE)/user_map.h
+ @echo "#define 0x`grep \" _etext$\" $(TOPDIR)/User.map | cut -d' ' -f1`" >> $(BOARD_INCLUDE)/user_map.h
+ @echo "#define CONFIG_USER_DATASOURCE 0x`grep \" _eronly$\" $(TOPDIR)/User.map | cut -d' ' -f1`" >> $(BOARD_INCLUDE)/user_map.h
+ @echo "#define C 0x`grep \" _sdata$\" $(TOPDIR)/User.map | cut -d' ' -f1`" >> $(BOARD_INCLUDE)/user_map.h
+ @echo "#define CONFIG_USER_ 0x`grep \" _edata$\" $(TOPDIR)/User.map | cut -d' ' -f1`" >> $(BOARD_INCLUDE)/user_map.h
+ @echo "#define 0x`grep \" _sbss\" $(TOPDIR)/User.map | cut -d' ' -f1`" >> $(BOARD_INCLUDE)/user_map.h
+ @echo "#define CONFIG_USER_ 0x`grep \" _ebss$\" $(TOPDIR)/User.map | cut -d' ' -f1`" >> $(BOARD_INCLUDE)/user_map.h
+
+ /* Show MPU information */
+
+ mpu_showtype();
+
+ /* Configure user flash and SRAM space */
+
+ mpu_userflash(CONFIG_USER_TEXTSTART, CONFIG_USER_TEXTEND - CONFIG_USER_TEXTSTART);
+ mpu_userintsram(datastart, dataend - datastart);
+
+ /* Then enable the MPU */
+
+ mpu_control(true, false, true);
+}
+
+/****************************************************************************
+ * Name: sam3u_mpuheap
+ *
+ * Description:
+ * Map a heap region (probably needs to extension to handle external SRAM).
+ *
+ ****************************************************************************/
+
+void sam3u_mpuheap(uintptr_t start, size_t size)
+{
+ mpu_userintsram(start, size);
+}
+
+#endif /* CONFIG_NUTTX_KERNEL */
+
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_pdc.h b/nuttx/arch/arm/src/sam3u/sam3u_pdc.h
new file mode 100644
index 000000000..106b2cd91
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_pdc.h
@@ -0,0 +1,103 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_pdc.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_PDC_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_PDC_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* PDC register offsets *****************************************************************/
+
+#define SAM3U_PDC_RPR_OFFSET 0x100 /* Receive Pointer Register */
+#define SAM3U_PDC_RCR_OFFSET 0x104 /* Receive Counter Register */
+#define SAM3U_PDC_TPR_OFFSET 0x108 /* Transmit Pointer Register */
+#define SAM3U_PDC_TCR_OFFSET 0x10c /* Transmit Counter Register */
+#define SAM3U_PDC_RNPR_OFFSET 0x110 /* Receive Next Pointer Register */
+#define SAM3U_PDC_RNCR_OFFSET 0x114 /* Receive Next Counter Register */
+#define SAM3U_PDC_TNPR_OFFSET 0x118 /* Transmit Next Pointer Register */
+#define SAM3U_PDC_TNCR_OFFSET 0x11c /* Transmit Next Counter Register */
+#define SAM3U_PDC_PTCR_OFFSET 0x120 /* Transfer Control Register */
+#define SAM3U_PDC_PTSR_OFFSET 0x124 /* Transfer Status Register */
+
+/* PDC register adresses ****************************************************************/
+
+/* These 10 registers are mapped in the peripheral memory space at the same offset. */
+
+/* PDC register bit definitions *********************************************************/
+
+#define PDC_RCR_RXCTR_SHIFT (0) /* Bits 0-15: Receive Counter Register */
+#define PDC_RCR_RXCTR_MASK (0xffff << PDC_RCR_RXCTR_SHIFT)
+
+#define PDC_TCR_TXCTR_SHIFT (0) /* Bits 0-15: Transmit Counter Register */
+#define PDC_TCR_TXCTR_MASK (0xffff << PDC_TCR_TXCTR_SHIFT)
+
+#define PDC_RNCR_RXNCTR_SHIFT (0) /* Bits 0-15: Receive Next Counter */
+#define PDC_RNCR_RXNCTR_MASK (0xffff << PDC_RNCR_RXNCTR_SHIFT)
+
+#define PDC_TNCR_TXNCTR_SHIFT (0) /* Bits 0-15: Transmit Counter Next */
+#define PDC_TNCR_TXNCTR_MASK (0xffff << PDC_TNCR_TXNCTR_SHIFT)
+
+#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 */
+
+#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_SAM3U_SAM3U_PDC_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_pio.c b/nuttx/arch/arm/src/sam3u/sam3u_pio.c
new file mode 100644
index 000000000..833ff5e1f
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_pio.c
@@ -0,0 +1,394 @@
+/****************************************************************************
+ * arch/arm/src/sam3u/sam3u_pio.c
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <time.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "sam3u_internal.h"
+#include "sam3u_pio.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_GPIO
+static const char g_portchar[4] = { 'A', 'B', 'C', 'D' };
+#endif
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+/****************************************************************************
+ * Name: sam3u_gpiobase
+ *
+ * Description:
+ * Return the base address of the GPIO register set
+ *
+ ****************************************************************************/
+
+static inline uintptr_t sam3u_gpiobase(uint16_t cfgset)
+{
+ int port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ return SAM3U_PION_BASE(port);
+}
+
+/****************************************************************************
+ * Name: sam3u_gpiopin
+ *
+ * Description:
+ * Returun the base address of the GPIO register set
+ *
+ ****************************************************************************/
+
+static inline int sam3u_gpiopin(uint16_t cfgset)
+{
+ return 1 << ((cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT);
+}
+
+/****************************************************************************
+ * Name: sam3u_configinput
+ *
+ * Description:
+ * Configure a GPIO input pin based on bit-encoded description of the pin.
+ *
+ ****************************************************************************/
+
+static inline int sam3u_configinput(uintptr_t base, uint32_t pin,
+ uint16_t cfgset)
+{
+ /* Disable interrupts on the pin */
+
+ putreg32(pin, base+SAM3U_PIO_IDR_OFFSET);
+
+ /* Enable/disable the pull-up as requested */
+
+ if ((cfgset & GPIO_CFG_PULLUP) != 0)
+ {
+ putreg32(pin, base+SAM3U_PIO_PUER_OFFSET);
+ }
+ else
+ {
+ putreg32(pin, base+SAM3U_PIO_PUDR_OFFSET);
+ }
+
+ /* Check if filtering should be enabled */
+
+ if ((cfgset & GPIO_CFG_DEGLITCH) != 0)
+ {
+ putreg32(pin, base+SAM3U_PIO_IFER_OFFSET);
+ }
+ else
+ {
+ putreg32(pin, base+SAM3U_PIO_IFDR_OFFSET);
+ }
+
+ /* Configure the pin as an input and enable the GPIO function */
+
+ putreg32(pin, base+SAM3U_PIO_ODR_OFFSET);
+ putreg32(pin, base+SAM3U_PIO_PER_OFFSET);
+
+ /* To-Do: If DEGLITCH is selected, need to configure DIFSR, SCIFSR, and
+ * registers. This would probably best be done with another, new
+ * API... perhaps sam3u_configfilter()
+ */
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: sam3u_configoutput
+ *
+ * Description:
+ * Configure a GPIO output pin based on bit-encoded description of the pin.
+ *
+ ****************************************************************************/
+
+static inline int sam3u_configoutput(uintptr_t base, uint32_t pin,
+ uint16_t cfgset)
+{
+ /* Disable interrupts on the pin */
+
+ putreg32(pin, base+SAM3U_PIO_IDR_OFFSET);
+
+ /* Enable/disable the pull-up as requested */
+
+ if ((cfgset & GPIO_CFG_PULLUP) != 0)
+ {
+ putreg32(pin, base+SAM3U_PIO_PUER_OFFSET);
+ }
+ else
+ {
+ putreg32(pin, base+SAM3U_PIO_PUDR_OFFSET);
+ }
+
+ /* Enable the open drain driver if requrested */
+
+ if ((cfgset & GPIO_CFG_OPENDRAIN) != 0)
+ {
+ putreg32(pin, base+SAM3U_PIO_MDER_OFFSET);
+ }
+ else
+ {
+ putreg32(pin, base+SAM3U_PIO_MDDR_OFFSET);
+ }
+
+ /* Set default value */
+
+ if ((cfgset & GPIO_OUTPUT_SET) != 0)
+ {
+ putreg32(pin, base+SAM3U_PIO_SODR_OFFSET);
+ }
+ else
+ {
+ putreg32(pin, base+SAM3U_PIO_CODR_OFFSET);
+ }
+
+ /* Configure the pin as an input and enable the GPIO function */
+
+ putreg32(pin, base+SAM3U_PIO_OER_OFFSET);
+ putreg32(pin, base+SAM3U_PIO_PER_OFFSET);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: sam3u_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 sam3u_configperiph(uintptr_t base, uint32_t pin,
+ uint16_t cfgset)
+{
+ uint32_t regval;
+
+ /* Disable interrupts on the pin */
+
+ putreg32(pin, base+SAM3U_PIO_IDR_OFFSET);
+
+ /* Enable/disable the pull-up as requested */
+
+ if ((cfgset & GPIO_CFG_PULLUP) != 0)
+ {
+ putreg32(pin, base+SAM3U_PIO_PUER_OFFSET);
+ }
+ else
+ {
+ putreg32(pin, base+SAM3U_PIO_PUDR_OFFSET);
+ }
+
+ /* Configure pin, depending upon the peripheral A or B*/
+
+ regval = getreg32(base+SAM3U_PIO_ABSR_OFFSET);
+ if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA)
+ {
+ regval &= ~pin;
+ }
+ else
+ {
+ regval |= pin;
+ }
+ putreg32(regval, base+SAM3U_PIO_ABSR_OFFSET);
+
+ /* Disable PIO functionality */
+
+ putreg32(pin, base+SAM3U_PIO_PDR_OFFSET);
+ return OK;
+}
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam3u_configgpio
+ *
+ * Description:
+ * Configure a GPIO pin based on bit-encoded description of the pin.
+ *
+ ****************************************************************************/
+
+int sam3u_configgpio(uint16_t cfgset)
+{
+ uintptr_t base = sam3u_gpiobase(cfgset);
+ uint32_t pin = sam3u_gpiopin(cfgset);
+ int ret;
+
+ switch (cfgset & GPIO_MODE_MASK)
+ {
+ case GPIO_INPUT:
+ ret = sam3u_configinput(base, pin, cfgset);
+ break;
+
+ case GPIO_OUTPUT:
+ ret = sam3u_configoutput(base, pin, cfgset);
+ break;
+
+ case GPIO_PERIPHA:
+ case GPIO_PERIPHB:
+ ret = sam3u_configperiph(base, pin, cfgset);
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * Name: sam3u_gpiowrite
+ *
+ * Description:
+ * Write one or zero to the selected GPIO pin
+ *
+ ****************************************************************************/
+
+void sam3u_gpiowrite(uint16_t pinset, bool value)
+{
+ uintptr_t base = sam3u_gpiobase(pinset);
+ uint32_t pin = sam3u_gpiopin(pinset);
+
+ if (value)
+ {
+ putreg32(pin, base+SAM3U_PIO_SODR_OFFSET);
+ }
+ else
+ {
+ putreg32(pin, base+SAM3U_PIO_CODR_OFFSET);
+ }
+}
+
+/****************************************************************************
+ * Name: sam3u_gpioread
+ *
+ * Description:
+ * Read one or zero from the selected GPIO pin
+ *
+ ****************************************************************************/
+
+bool sam3u_gpioread(uint16_t pinset)
+{
+ uintptr_t base = sam3u_gpiobase(pinset);
+ uint32_t pin = sam3u_gpiopin(pinset);
+ uint32_t regval;
+
+ if ((pinset & GPIO_MODE_MASK) == GPIO_OUTPUT)
+ {
+ regval = getreg32(base+SAM3U_PIO_ODSR_OFFSET);
+ }
+ else
+ {
+ regval = getreg32(base+SAM3U_PIO_PDSR_OFFSET);
+ }
+
+ return (regval & pin) != 0;
+}
+
+/************************************************************************************
+ * Function: sam3u_dumpgpio
+ *
+ * Description:
+ * Dump all GPIO registers associated with the base address of the provided pinset.
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_DEBUG_GPIO
+int sam3u_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 = sam3u_gpiopin(pinset);
+ port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ base = SAM3U_PION_BASE(port);
+
+ /* The following requires exclusive access to the GPIO registers */
+
+ flags = irqsave();
+ 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 + SAM3U_PIO_PSR_OFFSET), getreg32(base + SAM3U_PIO_OSR_OFFSET),
+ getreg32(base + SAM3U_PIO_IFSR_OFFSET), getreg32(base + SAM3U_PIO_ODSR_OFFSET));
+ lldbg(" PDSR: %08x IMR: %08x ISR: %08x MDSR: %08x\n",
+ getreg32(base + SAM3U_PIO_PDSR_OFFSET), getreg32(base + SAM3U_PIO_IMR_OFFSET),
+ getreg32(base + SAM3U_PIO_ISR_OFFSET), getreg32(base + SAM3U_PIO_MDSR_OFFSET));
+ lldbg(" PUSR: %08x ABSR: %08x SCIFSR: %08x DIFSR: %08x\n",
+ getreg32(base + SAM3U_PIO_PUSR_OFFSET), getreg32(base + SAM3U_PIO_ABSR_OFFSET),
+ getreg32(base + SAM3U_PIO_SCIFSR_OFFSET), getreg32(base + SAM3U_PIO_DIFSR_OFFSET));
+ lldbg(" IFDGSR: %08x SCDR: %08x OWSR: %08x AIMMR: %08x\n",
+ getreg32(base + SAM3U_PIO_IFDGSR_OFFSET), getreg32(base + SAM3U_PIO_SCDR_OFFSET),
+ getreg32(base + SAM3U_PIO_OWSR_OFFSET), getreg32(base + SAM3U_PIO_AIMMR_OFFSET));
+ lldbg(" ESR: %08x LSR: %08x ELSR: %08x FELLSR: %08x\n",
+ getreg32(base + SAM3U_PIO_ESR_OFFSET), getreg32(base + SAM3U_PIO_LSR_OFFSET),
+ getreg32(base + SAM3U_PIO_ELSR_OFFSET), getreg32(base + SAM3U_PIO_FELLSR_OFFSET));
+ lldbg(" FRLHSR: %08x LOCKSR: %08x WPMR: %08x WPSR: %08x\n",
+ getreg32(base + SAM3U_PIO_FRLHSR_OFFSET), getreg32(base + SAM3U_PIO_LOCKSR_OFFSET),
+ getreg32(base + SAM3U_PIO_WPMR_OFFSET), getreg32(base + SAM3U_PIO_WPSR_OFFSET));
+ irqrestore(flags);
+ return OK;
+}
+#endif
+
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_pio.h b/nuttx/arch/arm/src/sam3u/sam3u_pio.h
new file mode 100644
index 000000000..b55197ae1
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_pio.h
@@ -0,0 +1,324 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_pio.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_PIO_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_PIO_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* PIO register offsets *****************************************************************/
+
+#define SAM3U_PIO_PER_OFFSET 0x0000 /* PIO Enable Register */
+#define SAM3U_PIO_PDR_OFFSET 0x0004 /* PIO Disable Register */
+#define SAM3U_PIO_PSR_OFFSET 0x0008 /* PIO Status Register */
+ /* 0x000c: Reserved */
+#define SAM3U_PIO_OER_OFFSET 0x0010 /* Output Enable Register */
+#define SAM3U_PIO_ODR_OFFSET 0x0014 /* Output Disable Register */
+#define SAM3U_PIO_OSR_OFFSET 0x0018 /* utput Status Register */
+ /* 0x001c: Reserved */
+#define SAM3U_PIO_IFER_OFFSET 0x0020 /* Glitch Input Filter Enable Register */
+#define SAM3U_PIO_IFDR_OFFSET 0x0024 /* Glitch Input Filter Disable Register */
+#define SAM3U_PIO_IFSR_OFFSET 0x0028 /* Glitch Input Filter Status Register */
+ /* 0x002c: Reserved */
+#define SAM3U_PIO_SODR_OFFSET 0x0030 /* Set Output Data Register */
+#define SAM3U_PIO_CODR_OFFSET 0x0034 /* Clear Output Data Register */
+#define SAM3U_PIO_ODSR_OFFSET 0x0038 /* Output Data Status Register */
+#define SAM3U_PIO_PDSR_OFFSET 0x003c /* Pin Data Status Register */
+#define SAM3U_PIO_IER_OFFSET 0x0040 /* Interrupt Enable Register */
+#define SAM3U_PIO_IDR_OFFSET 0x0044 /* Interrupt Disable Register */
+#define SAM3U_PIO_IMR_OFFSET 0x0048 /* Interrupt Mask Register */
+#define SAM3U_PIO_ISR_OFFSET 0x004c /* Interrupt Status Register */
+#define SAM3U_PIO_MDER_OFFSET 0x0050 /* Multi-driver Enable Register */
+#define SAM3U_PIO_MDDR_OFFSET 0x0054 /* Multi-driver Disable Register */
+#define SAM3U_PIO_MDSR_OFFSET 0x0058 /* Multi-driver Status Register */
+ /* 0x005c: Reserved */
+#define SAM3U_PIO_PUDR_OFFSET 0x0060 /* Pull-up Disable Register */
+#define SAM3U_PIO_PUER_OFFSET 0x0064 /* Pull-up Enable Register */
+#define SAM3U_PIO_PUSR_OFFSET 0x0068 /* Pad Pull-up Status Register */
+ /* 0x006c: Reserved */
+#define SAM3U_PIO_ABSR_OFFSET 0x0070 /* Peripheral AB Select Register */
+ /* 0x0074-0x007c: Reserved */
+#define SAM3U_PIO_SCIFSR_OFFSET 0x0080 /* System Clock Glitch Input Filter Select Register */
+#define SAM3U_PIO_DIFSR_OFFSET 0x0084 /* Debouncing Input Filter Select Register */
+#define SAM3U_PIO_IFDGSR_OFFSET 0x0088 /* Glitch or Debouncing Input Filter Clock Selection Status Register */
+#define SAM3U_PIO_SCDR_OFFSET 0x008c /* Slow Clock Divider Debouncing Register */
+ /* 0x0090-0x009c: Reserved */
+#define SAM3U_PIO_OWER_OFFSET 0x00a0 /* Output Write Enable */
+#define SAM3U_PIO_OWDR_OFFSET 0x00a4 /* Output Write Disable */
+#define SAM3U_PIO_OWSR_OFFSET 0x00a8 /* Output Write Status Register */
+ /* 0x00ac: Reserved */
+#define SAM3U_PIO_AIMER_OFFSET 0x00b0 /* Additional Interrupt Modes Enable Register */
+#define SAM3U_PIO_AIMDR_OFFSET 0x00b4 /* Additional Interrupt Modes Disables Register */
+#define SAM3U_PIO_AIMMR_OFFSET 0x00b8 /* Additional Interrupt Modes Mask Register */
+ /* 0x00bc: Reserved */
+#define SAM3U_PIO_ESR_OFFSET 0x00c0 /* Edge Select Register */
+#define SAM3U_PIO_LSR_OFFSET 0x00c4 /* Level Select Register */
+#define SAM3U_PIO_ELSR_OFFSET 0x00c8 /* Edge/Level Status Register */
+ /* 0x00cc: Reserved */
+#define SAM3U_PIO_FELLSR_OFFSET 0x00d0 /* Falling Edge/Low Level Select Register */
+#define SAM3U_PIO_REHLSR_OFFSET 0x00d4 /* Rising Edge/ High Level Select Register */
+#define SAM3U_PIO_FRLHSR_OFFSET 0x00d8 /* Fall/Rise - Low/High Status Register */
+ /* 0x00dc: Reserved */
+#define SAM3U_PIO_LOCKSR_OFFSET 0x00e0 /* Lock Status */
+#define SAM3U_PIO_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */
+#define SAM3U_PIO_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */
+ /* 0x00ec-0x00f8: Reserved */
+ /* 0x0100-0x0144: Reserved */
+
+/* PIO register adresses ****************************************************************/
+
+#define PIOA (0)
+#define PIOB (1)
+#define PIOC (2)
+#define NPIO (3)
+
+#define SAM3U_PIO_PER(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_PER_OFFSET)
+#define SAM3U_PIO_PDR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_PDR_OFFSET)
+#define SAM3U_PIO_PSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_PSR_OFFSET)
+#define SAM3U_PIO_OER(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_OER_OFFSET)
+#define SAM3U_PIO_ODR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_ODR_OFFSET)
+#define SAM3U_PIO_OSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_OSR_OFFSET)
+#define SAM3U_PIO_IFER(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_IFER_OFFSET)
+#define SAM3U_PIO_IFDR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_IFDR_OFFSET)
+#define SAM3U_PIO_IFSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_IFSR_OFFSET)
+#define SAM3U_PIO_SODR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_SODR_OFFSET)
+#define SAM3U_PIO_CODR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_CODR_OFFSET)
+#define SAM3U_PIO_ODSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_ODSR_OFFSET)
+#define SAM3U_PIO_PDSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_PDSR_OFFSET)
+#define SAM3U_PIO_IER(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_IER_OFFSET)
+#define SAM3U_PIO_IDR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_IDR_OFFSET)
+#define SAM3U_PIO_IMR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_IMR_OFFSET)
+#define SAM3U_PIO_ISR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_ISR_OFFSET)
+#define SAM3U_PIO_MDER(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_MDER_OFFSET)
+#define SAM3U_PIO_MDDR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_MDDR_OFFSET)
+#define SAM3U_PIO_MDSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_MDSR_OFFSET)
+#define SAM3U_PIO_PUDR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_PUDR_OFFSET)
+#define SAM3U_PIO_PUER(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_PUER_OFFSET)
+#define SAM3U_PIO_PUSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_PUSR_OFFSET)
+#define SAM3U_PIO_ABSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_ABSR_OFFSET)
+#define SAM3U_PIO_SCIFSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_SCIFSR_OFFSET)
+#define SAM3U_PIO_DIFSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_DIFSR_OFFSET)
+#define SAM3U_PIO_IFDGSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_IFDGSR_OFFSET)
+#define SAM3U_PIO_SCDR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_SCDR_OFFSET)
+#define SAM3U_PIO_OWER(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_OWER_OFFSET)
+#define SAM3U_PIO_OWDR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_OWDR_OFFSET)
+#define SAM3U_PIO_OWSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_OWSR_OFFSET)
+#define SAM3U_PIO_AIMER(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_AIMER_OFFSET)
+#define SAM3U_PIO_AIMDR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_AIMDR_OFFSET)
+#define SAM3U_PIO_AIMMR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_AIMMR_OFFSET)
+#define SAM3U_PIO_ESR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_ESR_OFFSET)
+#define SAM3U_PIO_LSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_LSR_OFFSET)
+#define SAM3U_PIO_ELSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_ELSR_OFFSET)
+#define SAM3U_PIO_FELLSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_FELLSR_OFFSET)
+#define SAM3U_PIO_REHLSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_REHLSR_OFFSET)
+#define SAM3U_PIO_FRLHSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_FRLHSR_OFFSET)
+#define SAM3U_PIO_LOCKSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_LOCKSR_OFFSET)
+#define SAM3U_PIO_WPMR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_WPMR_OFFSET)
+#define SAM3U_PIO_WPSR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_WPSR_OFFSET)
+
+#define SAM3U_PIOA_PER (SAM3U_PIOA_BASE+SAM3U_PIO_PER_OFFSET)
+#define SAM3U_PIOA_PDR_ (SAM3U_PIOA_BASE+SAM3U_PIO_PDR_OFFSET)
+#define SAM3U_PIOA_PSR (SAM3U_PIOA_BASE+SAM3U_PIO_PSR_OFFSET)
+#define SAM3U_PIOA_OER (SAM3U_PIOA_BASE+SAM3U_PIO_OER_OFFSET)
+#define SAM3U_PIOA_ODR (SAM3U_PIOA_BASE+SAM3U_PIO_ODR_OFFSET)
+#define SAM3U_PIOA_OSR (SAM3U_PIOA_BASE+SAM3U_PIO_OSR_OFFSET)
+#define SAM3U_PIOA_IFER (SAM3U_PIOA_BASE+SAM3U_PIO_IFER_OFFSET)
+#define SAM3U_PIOA_IFDR (SAM3U_PIOA_BASE+SAM3U_PIO_IFDR_OFFSET)
+#define SAM3U_PIOA_IFSR (SAM3U_PIOA_BASE+SAM3U_PIO_IFSR_OFFSET)
+#define SAM3U_PIOA_SODR (SAM3U_PIOA_BASE+SAM3U_PIO_SODR_OFFSET)
+#define SAM3U_PIOA_CODR (SAM3U_PIOA_BASE+SAM3U_PIO_CODR_OFFSET)
+#define SAM3U_PIOA_ODSR (SAM3U_PIOA_BASE+SAM3U_PIO_ODSR_OFFSET)
+#define SAM3U_PIOA_PDSR (SAM3U_PIOA_BASE+SAM3U_PIO_PDSR_OFFSET)
+#define SAM3U_PIOA_IER (SAM3U_PIOA_BASE+SAM3U_PIO_IER_OFFSET)
+#define SAM3U_PIOA_IDR (SAM3U_PIOA_BASE+SAM3U_PIO_IDR_OFFSET)
+#define SAM3U_PIOA_IMR (SAM3U_PIOA_BASE+SAM3U_PIO_IMR_OFFSET)
+#define SAM3U_PIOA_ISR (SAM3U_PIOA_BASE+SAM3U_PIO_ISR_OFFSET)
+#define SAM3U_PIOA_MDER (SAM3U_PIOA_BASE+SAM3U_PIO_MDER_OFFSET)
+#define SAM3U_PIOA_MDDR (SAM3U_PIOA_BASE+SAM3U_PIO_MDDR_OFFSET)
+#define SAM3U_PIOA_MDSR (SAM3U_PIOA_BASE+SAM3U_PIO_MDSR_OFFSET)
+#define SAM3U_PIOA_PUDR (SAM3U_PIOA_BASE+SAM3U_PIO_PUDR_OFFSET)
+#define SAM3U_PIOA_PUER (SAM3U_PIOA_BASE+SAM3U_PIO_PUER_OFFSET)
+#define SAM3U_PIOA_PUSR (SAM3U_PIOA_BASE+SAM3U_PIO_PUSR_OFFSET)
+#define SAM3U_PIOA_ABSR (SAM3U_PIOA_BASE+SAM3U_PIO_ABSR_OFFSET)
+#define SAM3U_PIOA_SCIFSR (SAM3U_PIOA_BASE+SAM3U_PIO_SCIFSR_OFFSET)
+#define SAM3U_PIOA_DIFSR (SAM3U_PIOA_BASE+SAM3U_PIO_DIFSR_OFFSET)
+#define SAM3U_PIOA_IFDGSR (SAM3U_PIOA_BASE+SAM3U_PIO_IFDGSR_OFFSET)
+#define SAM3U_PIOA_SCDR (SAM3U_PIOA_BASE+SAM3U_PIO_SCDR_OFFSET)
+#define SAM3U_PIOA_OWER (SAM3U_PIOA_BASE+SAM3U_PIO_OWER_OFFSET)
+#define SAM3U_PIOA_OWDR (SAM3U_PIOA_BASE+SAM3U_PIO_OWDR_OFFSET)
+#define SAM3U_PIOA_OWSR (SAM3U_PIOA_BASE+SAM3U_PIO_OWSR_OFFSET)
+#define SAM3U_PIOA_AIMER (SAM3U_PIOA_BASE+SAM3U_PIO_AIMER_OFFSET)
+#define SAM3U_PIOA_AIMDR (SAM3U_PIOA_BASE+SAM3U_PIO_AIMDR_OFFSET)
+#define SAM3U_PIOA_AIMMR (SAM3U_PIOA_BASE+SAM3U_PIO_AIMMR_OFFSET)
+#define SAM3U_PIOA_ESR (SAM3U_PIOA_BASE+SAM3U_PIO_ESR_OFFSET)
+#define SAM3U_PIOA_LSR (SAM3U_PIOA_BASE+SAM3U_PIO_LSR_OFFSET)
+#define SAM3U_PIOA_ELSR (SAM3U_PIOA_BASE+SAM3U_PIO_ELSR_OFFSET)
+#define SAM3U_PIOA_FELLSR (SAM3U_PIOA_BASE+SAM3U_PIO_FELLSR_OFFSET)
+#define SAM3U_PIOA_REHLSR (SAM3U_PIOA_BASE+SAM3U_PIO_REHLSR_OFFSET)
+#define SAM3U_PIOA_FRLHSR (SAM3U_PIOA_BASE+SAM3U_PIO_FRLHSR_OFFSET)
+#define SAM3U_PIOA_LOCKSR (SAM3U_PIOA_BASE+SAM3U_PIO_LOCKSR_OFFSET)
+#define SAM3U_PIOA_WPMR (SAM3U_PIOA_BASE+SAM3U_PIO_WPMR_OFFSET)
+#define SAM3U_PIOA_WPSR (SAM3U_PIOA_BASE+SAM3U_PIO_WPSR_OFFSET)
+
+#define SAM3U_PIOB_PER (SAM3U_PIOB_BASE+SAM3U_PIO_PER_OFFSET)
+#define SAM3U_PIOB_PDR_ (SAM3U_PIOB_BASE+SAM3U_PIO_PDR_OFFSET)
+#define SAM3U_PIOB_PSR (SAM3U_PIOB_BASE+SAM3U_PIO_PSR_OFFSET)
+#define SAM3U_PIOB_OER (SAM3U_PIOB_BASE+SAM3U_PIO_OER_OFFSET)
+#define SAM3U_PIOB_ODR (SAM3U_PIOB_BASE+SAM3U_PIO_ODR_OFFSET)
+#define SAM3U_PIOB_OSR (SAM3U_PIOB_BASE+SAM3U_PIO_OSR_OFFSET)
+#define SAM3U_PIOB_IFER (SAM3U_PIOB_BASE+SAM3U_PIO_IFER_OFFSET)
+#define SAM3U_PIOB_IFDR (SAM3U_PIOB_BASE+SAM3U_PIO_IFDR_OFFSET)
+#define SAM3U_PIOB_IFSR (SAM3U_PIOB_BASE+SAM3U_PIO_IFSR_OFFSET)
+#define SAM3U_PIOB_SODR (SAM3U_PIOB_BASE+SAM3U_PIO_SODR_OFFSET)
+#define SAM3U_PIOB_CODR (SAM3U_PIOB_BASE+SAM3U_PIO_CODR_OFFSET)
+#define SAM3U_PIOB_ODSR (SAM3U_PIOB_BASE+SAM3U_PIO_ODSR_OFFSET)
+#define SAM3U_PIOB_PDSR (SAM3U_PIOB_BASE+SAM3U_PIO_PDSR_OFFSET)
+#define SAM3U_PIOB_IER (SAM3U_PIOB_BASE+SAM3U_PIO_IER_OFFSET)
+#define SAM3U_PIOB_IDR (SAM3U_PIOB_BASE+SAM3U_PIO_IDR_OFFSET)
+#define SAM3U_PIOB_IMR (SAM3U_PIOB_BASE+SAM3U_PIO_IMR_OFFSET)
+#define SAM3U_PIOB_ISR (SAM3U_PIOB_BASE+SAM3U_PIO_ISR_OFFSET)
+#define SAM3U_PIOB_MDER (SAM3U_PIOB_BASE+SAM3U_PIO_MDER_OFFSET)
+#define SAM3U_PIOB_MDDR (SAM3U_PIOB_BASE+SAM3U_PIO_MDDR_OFFSET)
+#define SAM3U_PIOB_MDSR (SAM3U_PIOB_BASE+SAM3U_PIO_MDSR_OFFSET)
+#define SAM3U_PIOB_PUDR (SAM3U_PIOB_BASE+SAM3U_PIO_PUDR_OFFSET)
+#define SAM3U_PIOB_PUER (SAM3U_PIOB_BASE+SAM3U_PIO_PUER_OFFSET)
+#define SAM3U_PIOB_PUSR (SAM3U_PIOB_BASE+SAM3U_PIO_PUSR_OFFSET)
+#define SAM3U_PIOB_ABSR (SAM3U_PIOB_BASE+SAM3U_PIO_ABSR_OFFSET)
+#define SAM3U_PIOB_SCIFSR (SAM3U_PIOB_BASE+SAM3U_PIO_SCIFSR_OFFSET)
+#define SAM3U_PIOB_DIFSR (SAM3U_PIOB_BASE+SAM3U_PIO_DIFSR_OFFSET)
+#define SAM3U_PIOB_IFDGSR (SAM3U_PIOB_BASE+SAM3U_PIO_IFDGSR_OFFSET)
+#define SAM3U_PIOB_SCDR (SAM3U_PIOB_BASE+SAM3U_PIO_SCDR_OFFSET)
+#define SAM3U_PIOB_OWER (SAM3U_PIOB_BASE+SAM3U_PIO_OWER_OFFSET)
+#define SAM3U_PIOB_OWDR (SAM3U_PIOB_BASE+SAM3U_PIO_OWDR_OFFSET)
+#define SAM3U_PIOB_OWSR (SAM3U_PIOB_BASE+SAM3U_PIO_OWSR_OFFSET)
+#define SAM3U_PIOB_AIMER (SAM3U_PIOB_BASE+SAM3U_PIO_AIMER_OFFSET)
+#define SAM3U_PIOB_AIMDR (SAM3U_PIOB_BASE+SAM3U_PIO_AIMDR_OFFSET)
+#define SAM3U_PIOB_AIMMR (SAM3U_PIOB_BASE+SAM3U_PIO_AIMMR_OFFSET)
+#define SAM3U_PIOB_ESR (SAM3U_PIOB_BASE+SAM3U_PIO_ESR_OFFSET)
+#define SAM3U_PIOB_LSR (SAM3U_PIOB_BASE+SAM3U_PIO_LSR_OFFSET)
+#define SAM3U_PIOB_ELSR (SAM3U_PIOB_BASE+SAM3U_PIO_ELSR_OFFSET)
+#define SAM3U_PIOB_FELLSR (SAM3U_PIOB_BASE+SAM3U_PIO_FELLSR_OFFSET)
+#define SAM3U_PIOB_REHLSR (SAM3U_PIOB_BASE+SAM3U_PIO_REHLSR_OFFSET)
+#define SAM3U_PIOB_FRLHSR (SAM3U_PIOB_BASE+SAM3U_PIO_FRLHSR_OFFSET)
+#define SAM3U_PIOB_LOCKSR (SAM3U_PIOB_BASE+SAM3U_PIO_LOCKSR_OFFSET)
+#define SAM3U_PIOB_WPMR (SAM3U_PIOB_BASE+SAM3U_PIO_WPMR_OFFSET)
+#define SAM3U_PIOB_WPSR (SAM3U_PIOB_BASE+SAM3U_PIO_WPSR_OFFSET)
+
+#define SAM3U_PIOC_PER (SAM3U_PIOC_BASE+SAM3U_PIO_PER_OFFSET)
+#define SAM3U_PIOC_PDR_ (SAM3U_PIOC_BASE+SAM3U_PIO_PDR_OFFSET)
+#define SAM3U_PIOC_PSR (SAM3U_PIOC_BASE+SAM3U_PIO_PSR_OFFSET)
+#define SAM3U_PIOC_OER (SAM3U_PIOC_BASE+SAM3U_PIO_OER_OFFSET)
+#define SAM3U_PIOC_ODR (SAM3U_PIOC_BASE+SAM3U_PIO_ODR_OFFSET)
+#define SAM3U_PIOC_OSR (SAM3U_PIOC_BASE+SAM3U_PIO_OSR_OFFSET)
+#define SAM3U_PIOC_IFER (SAM3U_PIOC_BASE+SAM3U_PIO_IFER_OFFSET)
+#define SAM3U_PIOC_IFDR (SAM3U_PIOC_BASE+SAM3U_PIO_IFDR_OFFSET)
+#define SAM3U_PIOC_IFSR (SAM3U_PIOC_BASE+SAM3U_PIO_IFSR_OFFSET)
+#define SAM3U_PIOC_SODR (SAM3U_PIOC_BASE+SAM3U_PIO_SODR_OFFSET)
+#define SAM3U_PIOC_CODR (SAM3U_PIOC_BASE+SAM3U_PIO_CODR_OFFSET)
+#define SAM3U_PIOC_ODSR (SAM3U_PIOC_BASE+SAM3U_PIO_ODSR_OFFSET)
+#define SAM3U_PIOC_PDSR (SAM3U_PIOC_BASE+SAM3U_PIO_PDSR_OFFSET)
+#define SAM3U_PIOC_IER (SAM3U_PIOC_BASE+SAM3U_PIO_IER_OFFSET)
+#define SAM3U_PIOC_IDR (SAM3U_PIOC_BASE+SAM3U_PIO_IDR_OFFSET)
+#define SAM3U_PIOC_IMR (SAM3U_PIOC_BASE+SAM3U_PIO_IMR_OFFSET)
+#define SAM3U_PIOC_ISR (SAM3U_PIOC_BASE+SAM3U_PIO_ISR_OFFSET)
+#define SAM3U_PIOC_MDER (SAM3U_PIOC_BASE+SAM3U_PIO_MDER_OFFSET)
+#define SAM3U_PIOC_MDDR (SAM3U_PIOC_BASE+SAM3U_PIO_MDDR_OFFSET)
+#define SAM3U_PIOC_MDSR (SAM3U_PIOC_BASE+SAM3U_PIO_MDSR_OFFSET)
+#define SAM3U_PIOC_PUDR (SAM3U_PIOC_BASE+SAM3U_PIO_PUDR_OFFSET)
+#define SAM3U_PIOC_PUER (SAM3U_PIOC_BASE+SAM3U_PIO_PUER_OFFSET)
+#define SAM3U_PIOC_PUSR (SAM3U_PIOC_BASE+SAM3U_PIO_PUSR_OFFSET)
+#define SAM3U_PIOC_ABSR (SAM3U_PIOC_BASE+SAM3U_PIO_ABSR_OFFSET)
+#define SAM3U_PIOC_SCIFSR (SAM3U_PIOC_BASE+SAM3U_PIO_SCIFSR_OFFSET)
+#define SAM3U_PIOC_DIFSR (SAM3U_PIOC_BASE+SAM3U_PIO_DIFSR_OFFSET)
+#define SAM3U_PIOC_IFDGSR (SAM3U_PIOC_BASE+SAM3U_PIO_IFDGSR_OFFSET)
+#define SAM3U_PIOC_SCDR (SAM3U_PIOC_BASE+SAM3U_PIO_SCDR_OFFSET)
+#define SAM3U_PIOC_OWER (SAM3U_PIOC_BASE+SAM3U_PIO_OWER_OFFSET)
+#define SAM3U_PIOC_OWDR (SAM3U_PIOC_BASE+SAM3U_PIO_OWDR_OFFSET)
+#define SAM3U_PIOC_OWSR (SAM3U_PIOC_BASE+SAM3U_PIO_OWSR_OFFSET)
+#define SAM3U_PIOC_AIMER (SAM3U_PIOC_BASE+SAM3U_PIO_AIMER_OFFSET)
+#define SAM3U_PIOC_AIMDR (SAM3U_PIOC_BASE+SAM3U_PIO_AIMDR_OFFSET)
+#define SAM3U_PIOC_AIMMR (SAM3U_PIOC_BASE+SAM3U_PIO_AIMMR_OFFSET)
+#define SAM3U_PIOC_ESR (SAM3U_PIOC_BASE+SAM3U_PIO_ESR_OFFSET)
+#define SAM3U_PIOC_LSR (SAM3U_PIOC_BASE+SAM3U_PIO_LSR_OFFSET)
+#define SAM3U_PIOC_ELSR (SAM3U_PIOC_BASE+SAM3U_PIO_ELSR_OFFSET)
+#define SAM3U_PIOC_FELLSR (SAM3U_PIOC_BASE+SAM3U_PIO_FELLSR_OFFSET)
+#define SAM3U_PIOC_REHLSR (SAM3U_PIOC_BASE+SAM3U_PIO_REHLSR_OFFSET)
+#define SAM3U_PIOC_FRLHSR (SAM3U_PIOC_BASE+SAM3U_PIO_FRLHSR_OFFSET)
+#define SAM3U_PIOC_LOCKSR (SAM3U_PIOC_BASE+SAM3U_PIO_LOCKSR_OFFSET)
+#define SAM3U_PIOC_WPMR (SAM3U_PIOC_BASE+SAM3U_PIO_WPMR_OFFSET)
+#define SAM3U_PIOC_WPSR (SAM3U_PIOC_BASE+SAM3U_PIO_WPSR_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)
+
+/* 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_SAM3U_SAM3U_PIO_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_pmc.h b/nuttx/arch/arm/src/sam3u/sam3u_pmc.h
new file mode 100644
index 000000000..75545f239
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_pmc.h
@@ -0,0 +1,316 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_pmc.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_PMC_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_PMC_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* PMC register offsets *****************************************************************/
+
+#define SAM3U_PMC_SCER_OFFSET 0x0000 /* System Clock Enable Register */
+#define SAM3U_PMC_SCDR_OFFSET 0x0004 /* System Clock Disable Register */
+#define SAM3U_PMC_SCSR_OFFSET 0x0008 /* System Clock Status Register */
+ /* 0x000c: Reserved */
+#define SAM3U_PMC_PCER_OFFSET 0x0010 /* Peripheral Clock Enable Register */
+#define SAM3U_PMC_PCDR_OFFSET 0x0014 /* Peripheral Clock Disable Register */
+#define SAM3U_PMC_PCSR_OFFSET 0x0018 /* Peripheral Clock Status Register */
+#define SAM3U_CKGR_UCKR_OFFSET 0x001c /* UTMI Clock Register */
+#define SAM3U_CKGR_MOR_OFFSET 0x0020 /* Main Oscillator Register */
+#define SAM3U_CKGR_MCFR_OFFSET 0x0024 /* Main Clock Frequency Register */
+#define SAM3U_CKGR_PLLAR_OFFSET 0x0028 /* PLLA Register */
+ /* 0x002c: Reserved */
+#define SAM3U_PMC_MCKR_OFFSET 0x0030 /* Master Clock Register */
+ /* 0x0034-0x003C Reserved */
+#define SAM3U_PMC_PCK_OFFSET(n) (0x0040+((n)<<2))
+#define SAM3U_PMC_PCK0_OFFSET 0x0040 /* Programmable Clock 0 Register */
+#define SAM3U_PMC_PCK1_OFFSET 0x0044 /* Programmable Clock 1 Register */
+#define SAM3U_PMC_PCK2_OFFSET 0x0048 /* Programmable Clock 2 Register */
+ /* 0x004c-0x005c: Reserved */
+#define SAM3U_PMC_IER_OFFSET 0x0060 /* Interrupt Enable Register */
+#define SAM3U_PMC_IDR_OFFSET 0x0064 /* Interrupt Disable Register */
+#define SAM3U_PMC_SR_OFFSET 0x0068 /* Status Register */
+#define SAM3U_PMC_IMR_OFFSET 0x006c /* Interrupt Mask Register */
+#define SAM3U_PMC_FSMR_OFFSET 0x0070 /* Fast Startup Mode Register */
+#define SAM3U_PMC_FSPR_OFFSET 0x0074 /* Fast Startup Polarity Register */
+#define SAM3U_PMC_FOCR_OFFSET 0x0078 /* Fault Output Clear Register */
+ /* 0x007c-0x00fc: Reserved */
+#define SAM3U_PMC_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */
+#define SAM3U_PMC_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */
+
+/* PMC register adresses ****************************************************************/
+
+#define SAM3U_PMC_SCER (SAM3U_PMC_BASE+SAM3U_PMC_SCER_OFFSET)
+#define SAM3U_PMC_SCDR (SAM3U_PMC_BASE+SAM3U_PMC_SCDR_OFFSET)
+#define SAM3U_PMC_SCSR (SAM3U_PMC_BASE+SAM3U_PMC_SCSR_OFFSET)
+#define SAM3U_PMC_PCER (SAM3U_PMC_BASE+SAM3U_PMC_PCER_OFFSET)
+#define SAM3U_PMC_PCDR (SAM3U_PMC_BASE+SAM3U_PMC_PCDR_OFFSET)
+#define SAM3U_PMC_PCSR (SAM3U_PMC_BASE+SAM3U_PMC_PCSR_OFFSET)
+#define SAM3U_CKGR_UCKR (SAM3U_PMC_BASE+SAM3U_CKGR_UCKR_OFFSET)
+#define SAM3U_CKGR_MOR (SAM3U_PMC_BASE+SAM3U_CKGR_MOR_OFFSET)
+#define SAM3U_CKGR_MCFR (SAM3U_PMC_BASE+SAM3U_CKGR_MCFR_OFFSET)
+#define SAM3U_CKGR_PLLAR (SAM3U_PMC_BASE+SAM3U_CKGR_PLLAR_OFFSET)
+#define SAM3U_PMC_MCKR (SAM3U_PMC_BASE+SAM3U_PMC_MCKR_OFFSET)
+#define SAM3U_PMC_PCK(n) (SAM3U_PMC_BASE+SAM3U_PMC_PCK_OFFSET(n))
+#define SAM3U_PMC_PCK0 (SAM3U_PMC_BASE+SAM3U_PMC_PCK0_OFFSET)
+#define SAM3U_PMC_PCK1 (SAM3U_PMC_BASE+SAM3U_PMC_PCK1_OFFSET)
+#define SAM3U_PMC_PCK2 (SAM3U_PMC_BASE+SAM3U_PMC_PCK2_OFFSET)
+#define SAM3U_PMC_IER (SAM3U_PMC_BASE+SAM3U_PMC_IER_OFFSET)
+#define SAM3U_PMC_IDR (SAM3U_PMC_BASE+SAM3U_PMC_IDR_OFFSET)
+#define SAM3U_PMC_SR (SAM3U_PMC_BASE+SAM3U_PMC_SR_OFFSET)
+#define SAM3U_PMC_IMR (SAM3U_PMC_BASE+SAM3U_PMC_IMR_OFFSET)
+#define SAM3U_PMC_FSMR (SAM3U_PMC_BASE+SAM3U_PMC_FSMR_OFFSET)
+#define SAM3U_PMC_FSPR (SAM3U_PMC_BASE+SAM3U_PMC_FSPR_OFFSET)
+#define SAM3U_PMC_FOCR (SAM3U_PMC_BASE+SAM3U_PMC_FOCR_OFFSET)
+#define SAM3U_PMC_WPMR (SAM3U_PMC_BASE+SAM3U_PMC_WPMR_OFFSET)
+#define SAM3U_PMC_WPSR (SAM3U_PMC_BASE+SAM3U_PMC_WPSR_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_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 */
+
+/* PMC Peripheral Clock Enable Register, PMC Peripheral Clock Disable Register, and PMC
+ * Peripheral Clock Status Register common bit-field definitions.
+ */
+
+#define PMC_PID(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 CKGR_UCKR_UPLLEN (1 << 16) /* Bit 16: UTMI PLL Enable */
+#define CKGR_UCKR_UPLLCOUNT_SHIFT (20) /* Bits 20-23: UTMI PLL Start-up Time */
+#define CKGR_UCKR_UPLLCOUNT_MASK (15 << CKGR_UCKR_UPLLCOUNT_SHIFT)
+
+/* PMC Clock Generator Main Oscillator Register */
+
+#define CKGR_MOR_MOSCXTEN (1 << 0) /* Bit 0: Main Crystal Oscillator Enable */
+#define CKGR_MOR_MOSCXTBY (1 << 1) /* Bit 1: Main Crystal Oscillator Bypass */
+#define CKGR_MOR_WAITMODE (1 << 2) /* Bit 2: Wait Mode Command */
+#define CKGR_MOR_MOSCRCEN (1 << 3) /* Bit 3: Main On-Chip RC Oscillator Enable */
+#define CKGR_MOR_MOSCRCF_SHIFT (4) /* Bits 4-6: Main On-Chip RC Oscillator Frequency Selection */
+#define CKGR_MOR_MOSCRCF_MASK (7 << CKGR_MOR_MOSCRCF_SHIFT)
+#define CKGR_MOR_MOSCXTST_SHIFT (8) /* Bits 8-16: Main Crystal Oscillator Start-up Time */
+#define CKGR_MOR_MOSCXTST_MASK (0x1ff << CKGR_MOR_MOSCXTST_SHIFT)
+#define CKGR_MOR_KEY_SHIFT (16) /* Bits 16-23: Password */
+#define CKGR_MOR_KEY_MASK (0xff << CKGR_MOR_KEY_SHIFT)
+#define CKGR_MOR_MOSCSEL (1 << 24) /* Bit 24: Main Oscillator Selection */
+#define CKGR_MOR_CFDEN (1 << 25) /* Bit 25: Clock Failure Detector Enable */
+
+
+/* PMC Clock Generator Main Clock Frequency Register */
+
+#define CKGR_MCFR_MAINF_SHIFT (0) /* Bits 0-15: Main Clock Frequency */
+#define CKGR_MCFR_MAINF_MASK (0xffff << CKGR_MCFR_MAINF_SHIFT)
+#define CKGR_MCFR_MAINFRDY (1 << 16) /* Bit 16: Main Clock Ready */
+
+/* PMC Clock Generator PLLA Register */
+
+#define CKGR_PLLAR_DIVA_SHIFT (0) /* Bits 0-7: Divider */
+#define CKGR_PLLAR_DIVA_MASK (0xff << CKGR_PLLAR_DIVA_SHIFT)
+# define CKGR_PLLAR_DIVA_ZERO (0 << CKGR_PLLAR_DIVA_SHIFT) /* Divider output is 0 */
+# define CKGR_PLLAR_DIVA_BYPASS (1 << CKGR_PLLAR_DIVA_SHIFT) /* Divider is bypassed (DIVA=1) */
+# define CKGR_PLLAR_DIVA(n) ((n) << CKGR_PLLAR_DIVA_SHIFT) /* Divider output is DIVA=n, n=2..255 */
+#define CKGR_PLLAR_PLLACOUNT_SHIFT (8) /* Bits 8-13: PLLA Counter */
+#define CKGR_PLLAR_PLLACOUNT_MASK (63 << CKGR_PLLAR_PLLACOUNT_SHIFT)
+#define CKGR_PLLAR_STMODE_SHIFT (14) /* Bits 14-15: Start Mode */
+#define CKGR_PLLAR_STMODE_MASK (3 << CKGR_PLLAR_STMODE_SHIFT)
+# define CKGR_PLLAR_STMODE_FAST (0 << CKGR_PLLAR_STMODE_SHIFT) /* Fast Startup */
+# define CKGR_PLLAR_STMODE_NORMAL (2 << CKGR_PLLAR_STMODE_SHIFT) /* Normal Startup */
+#define CKGR_PLLAR_MULA_SHIFT (16) /* Bits 16-26: PLLA Multiplier */
+#define CKGR_PLLAR_MULA_MASK (0x7ff << CKGR_PLLAR_MULA_SHIFT)
+#define 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_DIV32K (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_UPLLDIV (1 << 13) /* Bit 13: UPLL Divider */
+
+/* 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_MASK)
+# define PMC_PCK_CSS_SLOW (0 << PMC_PCK_CSS_MASK) /* Slow Clock */
+# define PMC_PCK_CSS_MAIN (1 << PMC_PCK_CSS_MASK) /* Main Clock */
+# define PMC_PCK_CSS_PLLA (2 << PMC_PCK_CSS_MASK) /* PLLA Clock */
+# define PMC_PCK_CSS_UPLL (3 << PMC_PCK_CSS_MASK) /* UPLL Clock */
+# define PMC_PCK_CSS_MASTER (4 << PMC_PCK_CSS_MASK) /* 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_DIV32K (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 */
+#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_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) */
+#define PMC_FSMR_LPM (1 << 20) /* Bit 20: 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)
+
+/* 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)
+
+/****************************************************************************************
+ * Public Types
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Data
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Functions
+ ****************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_SAM3U_SAM3U_PMC_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_pwm.h b/nuttx/arch/arm/src/sam3u/sam3u_pwm.h
new file mode 100644
index 000000000..e8278d795
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_pwm.h
@@ -0,0 +1,633 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_pwm.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_PWM_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_PWM_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* PWM register offsets *****************************************************************/
+
+#define SAM3U_PWM_CLK_OFFSET 0x000 /* PWM Clock Register */
+#define SAM3U_PWM_ENA_OFFSET 0x004 /* PWM Enable Register */
+#define SAM3U_PWM_DIS_OFFSET 0x008 /* PWM Disable Register */
+#define SAM3U_PWM_SR_OFFSET 0x00c /* PWM Status Register */
+#define SAM3U_PWM_IER1_OFFSET 0x010 /* PWM Interrupt Enable Register 1 */
+#define SAM3U_PWM_IDR1_OFFSET 0x014 /* PWM Interrupt Disable Register 1 */
+#define SAM3U_PWM_IMR1_OFFSET 0x018 /* PWM Interrupt Mask Register 1 */
+#define SAM3U_PWM_ISR1_OFFSET 0x01c /* PWM Interrupt Status Register 1 */
+#define SAM3U_PWM_SCM_OFFSET 0x020 /* PWM Sync Channels Mode Register */
+ /* 0x024: Reserved */
+#define SAM3U_PWM_SCUC_OFFSET 0x028 /* PWM Sync Channels Update Control Register */
+#define SAM3U_PWM_SCUP_OFFSET 0x02c /* PWM Sync Channels Update Period Register */
+#define SAM3U_PWM_SCUPUPD_OFFSET 0x030 /* PWM Sync Channels Update Period Update Register */
+#define SAM3U_PWM_IER2_OFFSET 0x034 /* PWM Interrupt Enable Register 2 */
+#define SAM3U_PWM_IDR2_OFFSET 0x038 /* PWM Interrupt Disable Register 2 */
+#define SAM3U_PWM_IMR2_OFFSET 0x03c /* PWM Interrupt Mask Register 2 */
+#define SAM3U_PWM_ISR2_OFFSET 0x040 /* PWM Interrupt Status Register 2 */
+#define SAM3U_PWM_OOV_OFFSET 0x044 /* PWM Output Override Value Register */
+#define SAM3U_PWM_OS_OFFSET 0x048 /* PWM Output Selection Register */
+#define SAM3U_PWM_OSS_OFFSET 0x04c /* PWM Output Selection Set Register */
+#define SAM3U_PWM_OSC_OFFSET 0x050 /* PWM Output Selection Clear Register */
+#define SAM3U_PWM_OSSUPD_OFFSET 0x054 /* PWM Output Selection Set Update Register */
+#define SAM3U_PWM_OSCUPD_OFFSET 0x058 /* PWM Output Selection Clear Update Register */
+#define SAM3U_PWM_FMR_OFFSET 0x05c /* PWM Fault Mode Register */
+#define SAM3U_PWM_FSR_OFFSET 0x060 /* PWM Fault Status Register */
+#define SAM3U_PWM_FCR_OFFSET 0x064 /* PWM Fault Clear Register */
+#define SAM3U_PWM_FPV_OFFSET 0x068 /* PWM Fault Protection Value Register */
+#define SAM3U_PWM_FPE_OFFSET 0x06c /* PWM Fault Protection Enable Register */
+ /* 0x070-0x078: Reserved */
+#define SAM3U_PWM_EL0MR_OFFSET 0x07c /* PWM Event Line 0 Mode Register */
+#define SAM3U_PWM_EL1MR_OFFSET 0x080 /* PWM Event Line 1 Mode Register */
+ /* 0x084-0x0ac: Reserved */
+ /* 0x0b4-0x0e0: Reserved */
+#define SAM3U_PWM_WPCR_OFFSET 0x0e4 /* PWM Write Protect Control Register */
+#define SAM3U_PWM_WPSR_OFFSET 0x0e8 /* PWM Write Protect Status Register */
+ /* 0x100-0x128: Reserved for PDC registers */
+ /* 0x12c: Reserved */
+/* PWM Comparison Registers */
+
+#define SAM3U_PWMCMP_OFFSET(n) (0x130+((n)<<4))
+#define SAM3U_PWMCMP_V_OFFSET 0x00 /* PWM Comparison Value Register */
+#define SAM3U_PWMCMP_VUPD_OFFSET 0x04 /* PWM Comparison Value Update Register */
+#define SAM3U_PWMCMP_M_OFFSET 0x08 /* PWM Comparison Mode Register */
+#define SAM3U_PWMCMP_MUPD_OFFSET 0x0c /* PWM Comparison Mode Update Register */
+
+#define SAM3U_PWMCMP0_V_OFFSET 0x130 /* PWM Comparison 0 Value Register */
+#define SAM3U_PWMCMP0_VUPD_OFFSET 0x134 /* PWM Comparison 0 Value Update Register */
+#define SAM3U_PWMCMP0_M_OFFSET 0x138 /* PWM Comparison 0 Mode Register */
+#define SAM3U_PWMCMP0_MUPD_OFFSET 0x13c /* PWM Comparison 0 Mode Update Register */
+
+#define SAM3U_PWMCMP1_V_OFFSET 0x140 /* PWM Comparison 1 Value Register */
+#define SAM3U_PWMCMP1_VUPD_OFFSET 0x144 /* PWM Comparison 1 Value Update Register */
+#define SAM3U_PWMCMP1_M_OFFSET 0x148 /* PWM Comparison 1 Mode Register */
+#define SAM3U_PWMCMP1_MUPD_OFFSET 0x14c /* PWM Comparison 1 Mode Update Register */
+
+#define SAM3U_PWMCMP2_V_OFFSET 0x150 /* PWM Comparison 2 Value Register */
+#define SAM3U_PWMCMP2_VUPD_OFFSET 0x154 /* PWM Comparison 2 Value Update Register */
+#define SAM3U_PWMCMP2_M_OFFSET 0x158 /* PWM Comparison 2 Mode Register */
+#define SAM3U_PWMCMP2_MUPD_OFFSET 0x15c /* PWM Comparison 2 Mode Update Register */
+
+#define SAM3U_PWMCMP3_V_OFFSET 0x160 /* PWM Comparison 3 Value Register */
+#define SAM3U_PWMCMP3_VUPD_OFFSET 0x164 /* PWM Comparison 3 Value Update Register */
+#define SAM3U_PWMCMP3_M_OFFSET 0x168 /* PWM Comparison 3 Mode Register */
+#define SAM3U_PWMCMP3_MUPD_OFFSET 0x16c /* PWM Comparison 3 Mode Update Register */
+
+#define SAM3U_PWMCMP4_V_OFFSET 0x170 /* PWM Comparison 4 Value Register */
+#define SAM3U_PWMCMP4_VUPD_OFFSET 0x174 /* PWM Comparison 4 Value Update Register */
+#define SAM3U_PWMCMP4_M_OFFSET 0x178 /* PWM Comparison 4 Mode Register */
+#define SAM3U_PWMCMP4_MUPD_OFFSET 0x17c /* PWM Comparison 4 Mode Update Register */
+
+#define SAM3U_PWMCMP5_V_OFFSET 0x180 /* PWM Comparison 5 Value Register */
+#define SAM3U_PWMCMP5_VUPD_OFFSET 0x184 /* PWM Comparison 5 Value Update Register */
+#define SAM3U_PWMCMP5_M_OFFSET 0x188 /* PWM Comparison 5 Mode Register */
+#define SAM3U_PWMCMP5_MUPD_OFFSET 0x18c /* PWM Comparison 5 Mode Update Register */
+
+#define SAM3U_PWMCMP6_V_OFFSET 0x190 /* PWM Comparison 6 Value Register */
+#define SAM3U_PWMCMP6_VUPD_OFFSET 0x194 /* PWM Comparison 6 Value Update Register */
+#define SAM3U_PWMCMP6_M_OFFSET 0x198 /* PWM Comparison 6 Mode Register */
+#define SAM3U_PWMCMP6_MUPD_OFFSET 0x19c /* PWM Comparison 6 Mode Update Register */
+
+#define SAM3U_PWMCMP7_V_OFFSET 0x1a0 /* PWM Comparison 7 Value Register */
+#define SAM3U_PWMCMP7_VUPD_OFFSET 0x1a4 /* PWM Comparison 7 Value Update Register */
+#define SAM3U_PWMCMP7_M_OFFSET 0x1a8 /* PWM Comparison 7 Mode Register */
+#define SAM3U_PWMCMP7_MUPD_OFFSET 0x1ac /* PWM Comparison 7 Mode Update Register */
+ /* 0x1b0-0x1fc: Reserved */
+/* PWM Channel Registers */
+
+#define SAM3U_PWMCH_OFFSET(n) (0x200+((n)<< 5))
+#define SAM3U_PWMCH_MR_OFFSET 0x00 /* PWM Channel Mode Register */
+#define SAM3U_PWMCH_DTY_OFFSET 0x04 /* PWM Channel Duty Cycle Register */
+#define SAM3U_PWMCH_DTYUPD_OFFSET 0x08 /* PWM Channel Duty Cycle Update Register */
+#define SAM3U_PWMCH_PRD_OFFSET 0x0c /* PWM Channel Period Register */
+#define SAM3U_PWMCH_PRDUPD_OFFSET 0x10 /* PWM Channel Period Update Register */
+#define SAM3U_PWMCH_CCNT_OFFSET 0x14 /* PWM Channel Counter Register */
+#define SAM3U_PWMCH_DT_OFFSET 0x18 /* PWM Channel Dead Time Register */
+#define SAM3U_PWMCH_DTUPD_OFFSET 0x1c /* PWM Channel Dead Time Update Register */
+
+#define SAM3U_PWMCH0_MR_OFFSET 0x200 /* PWM Channel 0 Mode Register */
+#define SAM3U_PWMCH0_DTY_OFFSET 0x204 /* PWM Channel 0 Duty Cycle Register */
+#define SAM3U_PWMCH0_DTYUPD_OFFSET 0x208 /* PWM Channel 0 Duty Cycle Update Register */
+#define SAM3U_PWMCH0_PRD_OFFSET 0x20c /* PWM Channel 0 Period Register */
+#define SAM3U_PWMCH0_PRDUPD_OFFSET 0x210 /* PWM Channel 0 Period Update Register */
+#define SAM3U_PWMCH0_CCNT_OFFSET 0x214 /* PWM Channel 0 Counter Register */
+#define SAM3U_PWMCH0_DT_OFFSET 0x218 /* PWM Channel 0 Dead Time Register */
+#define SAM3U_PWMCH0_DTUPD_OFFSET 0x21c /* PWM Channel 0 Dead Time Update Register */
+
+#define SAM3U_PWMCH1_MR_OFFSET 0x220 /* PWM Channel 1 Mode Register */
+#define SAM3U_PWMCH1_DTY_OFFSET 0x224 /* PWM Channel 1 Duty Cycle Register */
+#define SAM3U_PWMCH1_DTYUPD_OFFSET 0x228 /* PWM Channel 1 Duty Cycle Update Register */
+#define SAM3U_PWMCH1_PRD_OFFSET 0x22c /* PWM Channel 1 Period Register */
+#define SAM3U_PWMCH1_PRDUPD_OFFSET 0x230 /* PWM Channel 1 Period Update Register */
+#define SAM3U_PWMCH1_CCNT_OFFSET 0x234 /* PWM Channel 1 Counter Register */
+#define SAM3U_PWMCH1_DT_OFFSET 0x238 /* PWM Channel 1 Dead Time Register */
+#define SAM3U_PWMCH1_DTUPD_OFFSET 0x23c /* PWM Channel 1 Dead Time Update Register */
+
+#define SAM3U_PWMCH2_MR_OFFSET 0x240 /* PWM Channel 2 Mode Register */
+#define SAM3U_PWMCH2_DTY_OFFSET 0x244 /* PWM Channel 2 Duty Cycle Register */
+#define SAM3U_PWMCH2_DTYUPD_OFFSET 0x248 /* PWM Channel 2 Duty Cycle Update Register */
+#define SAM3U_PWMCH2_PRD_OFFSET 0x24c /* PWM Channel 2 Period Register */
+#define SAM3U_PWMCH2_PRDUPD_OFFSET 0x250 /* PWM Channel 2 Period Update Register */
+#define SAM3U_PWMCH2_CCNT_OFFSET 0x254 /* PWM Channel 2 Counter Register */
+#define SAM3U_PWMCH2_DT_OFFSET 0x258 /* PWM Channel 2 Dead Time Register */
+#define SAM3U_PWMCH2_DTUPD_OFFSET 0x25c /* PWM Channel 2 Dead Time Update Register */
+
+#define SAM3U_PWMCH3_MR_OFFSET 0x260 /* PWM Channel 3 Mode Register */
+#define SAM3U_PWMCH3_DTY_OFFSET 0x264 /* PWM Channel 3 Duty Cycle Register */
+#define SAM3U_PWMCH3_DTYUPD_OFFSET 0x268 /* PWM Channel 3 Duty Cycle Update Register */
+#define SAM3U_PWMCH3_PRD_OFFSET 0x26c /* PWM Channel 3 Period Register */
+#define SAM3U_PWMCH3_PRDUPD_OFFSET 0x270 /* PWM Channel 3 Period Update Register */
+#define SAM3U_PWMCH3_CCNT_OFFSET 0x274 /* PWM Channel 3 Counter Register */
+#define SAM3U_PWMCH3_DT_OFFSET 0x278 /* PWM Channel 3 Dead Time Register */
+#define SAM3U_PWMCH3_DTUPD_OFFSET 0x27c /* PWM Channel 3 Dead Time Update Register */
+
+/* PWM register adresses ****************************************************************/
+
+#define SAM3U_PWM_CLK (SAM3U_PWM_BASE+SAM3U_PWM_CLK_OFFSET)
+#define SAM3U_PWM_ENA (SAM3U_PWM_BASE+SAM3U_PWM_ENA_OFFSET)
+#define SAM3U_PWM_DIS (SAM3U_PWM_BASE+SAM3U_PWM_DIS_OFFSET)
+#define SAM3U_PWM_SR (SAM3U_PWM_BASE+SAM3U_PWM_SR_OFFSET)
+#define SAM3U_PWM_IER1 (SAM3U_PWM_BASE+SAM3U_PWM_IER1_OFFSET)
+#define SAM3U_PWM_IDR1 (SAM3U_PWM_BASE+SAM3U_PWM_IDR1_OFFSET)
+#define SAM3U_PWM_IMR1 (SAM3U_PWM_BASE+SAM3U_PWM_IMR1_OFFSET)
+#define SAM3U_PWM_ISR1 (SAM3U_PWM_BASE+SAM3U_PWM_ISR1_OFFSET)
+#define SAM3U_PWM_SCM (SAM3U_PWM_BASE+SAM3U_PWM_SCM_OFFSET)
+#define SAM3U_PWM_SCUC (SAM3U_PWM_BASE+SAM3U_PWM_SCUC_OFFSET)
+#define SAM3U_PWM_SCUP (SAM3U_PWM_BASE+SAM3U_PWM_SCUP_OFFSET)
+#define SAM3U_PWM_SCUPUPD (SAM3U_PWM_BASE+SAM3U_PWM_SCUPUPD_OFFSET)
+#define SAM3U_PWM_IER2 (SAM3U_PWM_BASE+SAM3U_PWM_IER2_OFFSET)
+#define SAM3U_PWM_IDR2 (SAM3U_PWM_BASE+SAM3U_PWM_IDR2_OFFSET)
+#define SAM3U_PWM_IMR2 (SAM3U_PWM_BASE+SAM3U_PWM_IMR2_OFFSET)
+#define SAM3U_PWM_ISR2 (SAM3U_PWM_BASE+SAM3U_PWM_ISR2_OFFSET)
+#define SAM3U_PWM_OOV (SAM3U_PWM_BASE+SAM3U_PWM_OOV_OFFSET)
+#define SAM3U_PWM_OS (SAM3U_PWM_BASE+SAM3U_PWM_OS_OFFSET)
+#define SAM3U_PWM_OSS (SAM3U_PWM_BASE+SAM3U_PWM_OSS_OFFSET)
+#define SAM3U_PWM_OSC (SAM3U_PWM_BASE+SAM3U_PWM_OSC_OFFSET)
+#define SAM3U_PWM_OSSUPD (SAM3U_PWM_BASE+SAM3U_PWM_OSSUPD_OFFSET)
+#define SAM3U_PWM_OSCUPD (SAM3U_PWM_BASE+SAM3U_PWM_OSCUPD_OFFSET)
+#define SAM3U_PWM_FMR (SAM3U_PWM_BASE+SAM3U_PWM_FMR_OFFSET)
+#define SAM3U_PWM_FSR (SAM3U_PWM_BASE+SAM3U_PWM_FSR_OFFSET)
+#define SAM3U_PWM_FCR (SAM3U_PWM_BASE+SAM3U_PWM_FCR_OFFSET)
+#define SAM3U_PWM_FPV (SAM3U_PWM_BASE+SAM3U_PWM_FPV_OFFSET)
+#define SAM3U_PWM_FPE (SAM3U_PWM_BASE+SAM3U_PWM_FPE_OFFSET)
+#define SAM3U_PWM_EL0MR (SAM3U_PWM_BASE+SAM3U_PWM_EL0MR_OFFSET)
+#define SAM3U_PWM_EL1MR (SAM3U_PWM_BASE+SAM3U_PWM_EL1MR_OFFSET)
+#define SAM3U_PWM_WPCR (SAM3U_PWM_BASE+SAM3U_PWM_WPCR_OFFSET)
+#define SAM3U_PWM_WPSR (SAM3U_PWM_BASE+SAM3U_PWM_WPSR_OFFSET)
+
+/* PWM Comparison Registers */
+
+#define SAM3U_PWCMP_BASE(n) (SAM3U_PWM_BASE+SAM3U_PWCMP_OFFSET(n))
+#define SAM3U_PWMCMP0_BASE (SAM3U_PWM_BASE+0x0130)
+#define SAM3U_PWMCMP1_BASE (SAM3U_PWM_BASE+0x0140)
+#define SAM3U_PWMCMP2_BASE (SAM3U_PWM_BASE+0x0150)
+#define SAM3U_PWMCMP3_BASE (SAM3U_PWM_BASE+0x0160)
+#define SAM3U_PWMCMP4_BASE (SAM3U_PWM_BASE+0x0170)
+#define SAM3U_PWMCMP5_BASE (SAM3U_PWM_BASE+0x0180)
+#define SAM3U_PWMCMP6_BASE (SAM3U_PWM_BASE+0x0190)
+#define SAM3U_PWMCMP7_BASE (SAM3U_PWM_BASE+0x01a0)
+
+#define SAM3U_PWMCMP0_V (SAM3U_PWMCMP0_BASE+SAM3U_PWMCMP_V_OFFSET)
+#define SAM3U_PWMCMP0_VUPD (SAM3U_PWMCMP0_BASE+SAM3U_PWMCMP_VUPD_OFFSET)
+#define SAM3U_PWMCMP0_M (SAM3U_PWMCMP0_BASE+SAM3U_PWMCMP_M_OFFSET)
+#define SAM3U_PWMCMP0_MUPD (SAM3U_PWMCMP0_BASE+SAM3U_PWMCMP_MUPD_OFFSET)
+
+#define SAM3U_PWMCMP1_V (SAM3U_PWMCMP1_BASE+SAM3U_PWMCMP_V_OFFSET)
+#define SAM3U_PWMCMP1_VUPD (SAM3U_PWMCMP1_BASE+SAM3U_PWMCMP_VUPD_OFFSET)
+#define SAM3U_PWMCMP1_M (SAM3U_PWMCMP1_BASE+SAM3U_PWMCMP_M_OFFSET)
+#define SAM3U_PWMCMP1_MUPD (SAM3U_PWMCMP1_BASE+SAM3U_PWMCMP_MUPD_OFFSET)
+
+#define SAM3U_PWMCMP2_V (SAM3U_PWMCMP2_BASE+SAM3U_PWMCMP_V_OFFSET)
+#define SAM3U_PWMCMP2_VUPD (SAM3U_PWMCMP2_BASE+SAM3U_PWMCMP_VUPD_OFFSET)
+#define SAM3U_PWMCMP2_M (SAM3U_PWMCMP2_BASE+SAM3U_PWMCMP_M_OFFSET)
+#define SAM3U_PWMCMP2_MUPD (SAM3U_PWMCMP2_BASE+SAM3U_PWMCMP_MUPD_OFFSET)
+
+#define SAM3U_PWMCMP3_V (SAM3U_PWMCMP3_BASE+SAM3U_PWMCMP_V_OFFSET)
+#define SAM3U_PWMCMP3_VUPD (SAM3U_PWMCMP3_BASE+SAM3U_PWMCMP_VUPD_OFFSET)
+#define SAM3U_PWMCMP3_M (SAM3U_PWMCMP3_BASE+SAM3U_PWMCMP_M_OFFSET)
+#define SAM3U_PWMCMP3_MUPD (SAM3U_PWMCMP3_BASE+SAM3U_PWMCMP_MUPD_OFFSET)
+
+#define SAM3U_PWMCMP4_V (SAM3U_PWMCMP4_BASE+SAM3U_PWMCMP_V_OFFSET)
+#define SAM3U_PWMCMP4_VUPD (SAM3U_PWMCMP4_BASE+SAM3U_PWMCMP_VUPD_OFFSET)
+#define SAM3U_PWMCMP4_M (SAM3U_PWMCMP4_BASE+SAM3U_PWMCMP_M_OFFSET)
+#define SAM3U_PWMCMP4_MUPD (SAM3U_PWMCMP4_BASE+SAM3U_PWMCMP_MUPD_OFFSET)
+
+#define SAM3U_PWMCMP5_V (SAM3U_PWMCMP5_BASE+SAM3U_PWMCMP_V_OFFSET)
+#define SAM3U_PWMCMP5_VUPD (SAM3U_PWMCMP5_BASE+SAM3U_PWMCMP_VUPD_OFFSET)
+#define SAM3U_PWMCMP5_M (SAM3U_PWMCMP5_BASE+SAM3U_PWMCMP_M_OFFSET)
+#define SAM3U_PWMCMP5_MUPD (SAM3U_PWMCMP5_BASE+SAM3U_PWMCMP_MUPD_OFFSET)
+
+#define SAM3U_PWMCMP6_V (SAM3U_PWMCMP6_BASE+SAM3U_PWMCMP_V_OFFSET)
+#define SAM3U_PWMCMP6_VUPD (SAM3U_PWMCMP6_BASE+SAM3U_PWMCMP_VUPD_OFFSET)
+#define SAM3U_PWMCMP6_M (SAM3U_PWMCMP6_BASE+SAM3U_PWMCMP_M_OFFSET)
+#define SAM3U_PWMCMP6_MUPD (SAM3U_PWMCMP6_BASE+SAM3U_PWMCMP_MUPD_OFFSET)
+
+#define SAM3U_PWMCMP7_V (SAM3U_PWMCMP7_BASE+SAM3U_PWMCMP_V_OFFSET)
+#define SAM3U_PWMCMP7_VUPD (SAM3U_PWMCMP7_BASE+SAM3U_PWMCMP_VUPD_OFFSET)
+#define SAM3U_PWMCMP7_M (SAM3U_PWMCMP7_BASE+SAM3U_PWMCMP_M_OFFSET)
+#define SAM3U_PWMCMP7_MUPD (SAM3U_PWMCMP7_BASE+SAM3U_PWMCMP_MUPD_OFFSET)
+
+/* PWM Channel Registers */
+
+#define SAM3U_PWCH_BASE(n) (SAM3U_PWM_BASE+SAM3U_PWCH_OFFSET(n))
+#define SAM3U_PWMCH0_BASE (SAM3U_PWM_BASE+0x0200)
+#define SAM3U_PWMCH1_BASE (SAM3U_PWM_BASE+0x0220)
+#define SAM3U_PWMCH2_BASE (SAM3U_PWM_BASE+0x0240)
+#define SAM3U_PWMCH3_BASE (SAM3U_PWM_BASE+0x0260)
+
+#define SAM3U_PWMCH0_MR (SAM3U_PWMCH0_BASE+SAM3U_PWMCH_MR_OFFSET)
+#define SAM3U_PWMCH0_DTY (SAM3U_PWMCH0_BASE+SAM3U_PWMCH_DTY_OFFSET)
+#define SAM3U_PWMCH0_DTYUPD (SAM3U_PWMCH0_BASE+SAM3U_PWMCH_DTYUPD_OFFSET)
+#define SAM3U_PWMCH0_PRD (SAM3U_PWMCH0_BASE+SAM3U_PWMCH_PRD_OFFSET)
+#define SAM3U_PWMCH0_PRDUPD (SAM3U_PWMCH0_BASE+SAM3U_PWMCH_PRDUPD_OFFSET)
+#define SAM3U_PWMCH0_CCNT (SAM3U_PWMCH0_BASE+SAM3U_PWMCH_CCNT_OFFSET)
+#define SAM3U_PWMCH0_DT (SAM3U_PWMCH0_BASE+SAM3U_PWMCH_DT_OFFSET)
+#define SAM3U_PWMCH0_DTUPD (SAM3U_PWMCH0_BASE+SAM3U_PWMCH_DTUPD_OFFSET)
+
+#define SAM3U_PWMCH1_MR (SAM3U_PWMCH1_BASE+SAM3U_PWMCH_MR_OFFSET)
+#define SAM3U_PWMCH1_DTY (SAM3U_PWMCH1_BASE+SAM3U_PWMCH_DTY_OFFSET)
+#define SAM3U_PWMCH1_DTYUPD (SAM3U_PWMCH1_BASE+SAM3U_PWMCH_DTYUPD_OFFSET)
+#define SAM3U_PWMCH1_PRD (SAM3U_PWMCH1_BASE+SAM3U_PWMCH_PRD_OFFSET)
+#define SAM3U_PWMCH1_PRDUPD (SAM3U_PWMCH1_BASE+SAM3U_PWMCH_PRDUPD_OFFSET)
+#define SAM3U_PWMCH1_CCNT (SAM3U_PWMCH1_BASE+SAM3U_PWMCH_CCNT_OFFSET)
+#define SAM3U_PWMCH1_DT (SAM3U_PWMCH1_BASE+SAM3U_PWMCH_DT_OFFSET)
+#define SAM3U_PWMCH1_DTUPD (SAM3U_PWMCH1_BASE+SAM3U_PWMCH_DTUPD_OFFSET)
+
+#define SAM3U_PWMCH2_MR (SAM3U_PWMCH2_BASE+SAM3U_PWMCH_MR_OFFSET)
+#define SAM3U_PWMCH2_DTY (SAM3U_PWMCH2_BASE+SAM3U_PWMCH_DTY_OFFSET)
+#define SAM3U_PWMCH2_DTYUPD (SAM3U_PWMCH2_BASE+SAM3U_PWMCH_DTYUPD_OFFSET)
+#define SAM3U_PWMCH2_PRD (SAM3U_PWMCH2_BASE+SAM3U_PWMCH_PRD_OFFSET)
+#define SAM3U_PWMCH2_PRDUPD (SAM3U_PWMCH2_BASE+SAM3U_PWMCH_PRDUPD_OFFSET)
+#define SAM3U_PWMCH2_CCNT (SAM3U_PWMCH2_BASE+SAM3U_PWMCH_CCNT_OFFSET)
+#define SAM3U_PWMCH2_DT (SAM3U_PWMCH2_BASE+SAM3U_PWMCH_DT_OFFSET)
+#define SAM3U_PWMCH2_DTUPD (SAM3U_PWMCH2_BASE+SAM3U_PWMCH_DTUPD_OFFSET)
+
+#define SAM3U_PWMCH3_MR (SAM3U_PWMCH3_BASE+SAM3U_PWMCH_MR_OFFSET)
+#define SAM3U_PWMCH3_DTY (SAM3U_PWMCH3_BASE+SAM3U_PWMCH_DTY_OFFSET)
+#define SAM3U_PWMCH3_DTYUPD (SAM3U_PWMCH3_BASE+SAM3U_PWMCH_DTYUPD_OFFSET)
+#define SAM3U_PWMCH3_PRD (SAM3U_PWMCH3_BASE+SAM3U_PWMCH_PRD_OFFSET)
+#define SAM3U_PWMCH3_PRDUPD (SAM3U_PWMCH3_BASE+SAM3U_PWMCH_PRDUPD_OFFSET)
+#define SAM3U_PWMCH3_CCNT (SAM3U_PWMCH3_BASE+SAM3U_PWMCH_CCNT_OFFSET)
+#define SAM3U_PWMCH3_DT (SAM3U_PWMCH3_BASE+SAM3U_PWMCH_DT_OFFSET)
+#define SAM3U_PWMCH3_DTUPD (SAM3U_PWMCH3_BASE+SAM3U_PWMCH_DTUPD_OFFSET)
+
+/* 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_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_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 SAM3U_ENAB_CHID(n) (1 << ((n))
+#define SAM3U_ENAB_CHID0 (1 << 0) /* Bit 0: Counter Event Channel 0 Interrupt */
+#define SAM3U_ENAB_CHID1 (1 << 1) /* Bit 1: Counter Event Channel 1 Interrupt */
+#define SAM3U_ENAB_CHID2 (1 << 2) /* Bit 2: Counter Event Channel 2 Interrupt */
+#define SAM3U_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 SAM3U_INT_CHID(n) (1 << (n))
+#define SAM3U_INT_CHID0 (1 << 0) /* Bit 0: Counter Event Channel 0 Interrupt */
+#define SAM3U_INT_CHID1 (1 << 1) /* Bit 1: Counter Event Channel 1 Interrupt */
+#define SAM3U_INT_CHID2 (1 << 2) /* Bit 2: Counter Event Channel 2 Interrupt */
+#define SAM3U_INT_CHID3 (1 << 3) /* Bit 3: Counter Event Channel 3 Interrupt */
+#define SAM3U_INT_FCHID(n) (1 << ((n)+16))
+#define SAM3U_INT_FCHID0 (1 << 16) /* Bit 16: Fault Protection Trigger Channel 0 Interrupt */
+#define SAM3U_INT_FCHID1 (1 << 17) /* Bit 17: Fault Protection Trigger Channel 1 Interrupt */
+#define SAM3U_INT_FCHID2 (1 << 18) /* Bit 18: Fault Protection Trigger Channel 2 Interrupt */
+#define SAM3U_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)
+
+/* 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_UPRCNT_SHIFT (4) /* Bits 4-7: Update Period Counter */
+#define PWM_SCUP_UPRCNT_MASK (15 << 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)
+
+/* 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 SAM3U_INT_WRDY (1 << 0) /* Bit 0: Write Ready Update Interrupt */
+#define SAM3U_INT_ENDTX (1 << 1) /* Bit 1: PDC End of TX Buffer Interrupt */
+#define SAM3U_INT_TXBUFE (1 << 2) /* Bit 2: PDC TX Buffer Empty Interrupt */
+#define SAM3U_INT_UNRE (1 << 3) /* Bit 3: Synch Update Underrun Error Interrupt */
+#define SAM3U_INT_CMPM(n) (1 << ((n)+8))
+#define SAM3U_INT_CMPM0 (1 << 8) /* Bit 8: Comparison 0 Match Interrupt */
+#define SAM3U_INT_CMPM1 (1 << 9) /* Bit 9: Comparison 1 Match Interrupt */
+#define SAM3U_INT_CMPM2 (1 << 10) /* Bit 10: Comparison 2 Match Interrupt */
+#define SAM3U_INT_CMPM3 (1 << 11) /* Bit 11: Comparison 3 Match Interrupt */
+#define SAM3U_INT_CMPM4 (1 << 12) /* Bit 12: Comparison 4 Match Interrupt */
+#define SAM3U_INT_CMPM5 (1 << 13) /* Bit 13: Comparison 5 Match Interrupt */
+#define SAM3U_INT_CMPM6 (1 << 14) /* Bit 14: Comparison 6 Match Interrupt */
+#define SAM3U_INT_CMPM7 (1 << 15) /* Bit 15: Comparison 7 Match Interrupt */
+#define SAM3U_INT_CMPU(n) (1 << ((n)+16))
+#define SAM3U_INT_CMPU0 (1 << 16) /* Bit 16: Comparison o Update Interrupt */
+#define SAM3U_INT_CMPU1 (1 << 17) /* Bit 17: Comparison 1 Update Interrupt */
+#define SAM3U_INT_CMPU2 (1 << 18) /* Bit 18: Comparison 2 Update Interrupt */
+#define SAM3U_INT_CMPU3 (1 << 19) /* Bit 19: Comparison 3 Update Interrupt */
+#define SAM3U_INT_CMPU4 (1 << 20) /* Bit 20: Comparison 4 Update Interrupt */
+#define SAM3U_INT_CMPU5 (1 << 21) /* Bit 21: Comparison 5 Update Interrupt */
+#define SAM3U_INT_CMPU6 (1 << 22) /* Bit 22: Comparison 6 Update Interrupt */
+#define SAM3U_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_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_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 */
+
+/* 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_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 */
+
+/* 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 */
+
+/* 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 */
+
+/* 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 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)
+
+/* 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_CPR_SHIFT (8) /* Bits 8-11: Comparison x Period */
+#define PWMCMP_CPR_MASK (15 << 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_CUPR_SHIFT (16) /* Bits 16-19: Comparison x Update Period */
+#define PWMCMP_CUPR_MASK (15 << 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)
+
+/* 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 */
+#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_DTL_SHIFT (16) /* Bits 16-31: Dead-Time Value for PWMLx Output */
+#define PWMCH_DTL_MASK (0xffff << PWMCH_DTL_SHIFT)
+
+/****************************************************************************************
+ * Public Types
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Data
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Functions
+ ****************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_SAM3U_SAM3U_PWM_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_rstc.h b/nuttx/arch/arm/src/sam3u/sam3u_rstc.h
new file mode 100644
index 000000000..688631fb6
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_rstc.h
@@ -0,0 +1,102 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_rstc.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_RSTC_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_RSTC_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* RSTC register offsets ****************************************************************/
+
+#define SAM3U_RSTC_CR_OFFSET 0x00 /* Control Register */
+#define SAM3U_RSTC_SR_OFFSET 0x04 /* Status Register */
+#define SAM3U_RSTC_MR_OFFSET 0x08 /* Mode Register */
+
+/* RSTC register adresses ***************************************************************/
+
+#define SAM3U_RSTC_CR (SAM3U_RSTC_BASE+SAM3U_RSTC_CR_OFFSET)
+#define SAM3U_RSTC_SR (SAM3U_RSTC_BASE+SAM3U_RSTC_SR_OFFSET)
+#define SAM3U_RSTC_MR (SAM3U_RSTC_BASE+SAM3U_RSTC_MR_OFFSET)
+
+/* RSTC register bit definitions ********************************************************/
+
+#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_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 */
+
+#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_KEY_SHIFT (24) /* Bits 24-31: Password */
+#define RSTC_MR_KEY_MASK (0xff << RSTC_CR_KEY_SHIFT)
+
+/****************************************************************************************
+ * Public Types
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Data
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Functions
+ ****************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_SAM3U_SAM3U_RSTC_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_rtc.h b/nuttx/arch/arm/src/sam3u/sam3u_rtc.h
new file mode 100644
index 000000000..61e6bb68e
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_rtc.h
@@ -0,0 +1,184 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_rtc.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_RTC_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_RTC_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* RTC register offsets *****************************************************************/
+
+#define SAM3U_RTC_CR_OFFSET 0x00 /* Control Register */
+#define SAM3U_RTC_MR_OFFSET 0x04 /* Mode Register */
+#define SAM3U_RTC_TIMR_OFFSET 0x08 /* Time Register */
+#define SAM3U_RTC_CALR_OFFSET 0x0c /* Calendar Register */
+#define SAM3U_RTC_TIMALR_OFFSET 0x10 /* Time Alarm Register */
+#define SAM3U_RTC_CALALR_OFFSET 0x14 /* Calendar Alarm Register */
+#define SAM3U_RTC_SR_OFFSET 0x18 /* Status Register */
+#define SAM3U_RTC_SCCR_OFFSET 0x1c /* Status Clear Command Register */
+#define SAM3U_RTC_IER_OFFSET 0x20 /* Interrupt Enable Register */
+#define SAM3U_RTC_IDR_OFFSET 0x24 /* Interrupt Disable Register */
+#define SAM3U_RTC_IMR_OFFSET 0x28 /* Interrupt Mask Register */
+#define SAM3U_RTC_VER_OFFSET 0x2c /* Valid Entry Register */
+
+/* RTC register adresses ****************************************************************/
+
+#define SAM3U_RTC_CR (SAM3U_RTC_BASE+SAM3U_RTC_CR_OFFSET)
+#define SAM3U_RTC_MR (SAM3U_RTC_BASE+SAM3U_RTC_MR_OFFSET)
+#define SAM3U_RTC_TIMR (SAM3U_RTC_BASE+SAM3U_RTC_TIMR_OFFSET)
+#define SAM3U_RTC_CALR (SAM3U_RTC_BASE+SAM3U_RTC_CALR_OFFSET)
+#define SAM3U_RTC_TIMALR (SAM3U_RTC_BASE+SAM3U_RTC_TIMALR_OFFSET)
+#define SAM3U_RTC_CALALR (SAM3U_RTC_BASE+SAM3U_RTC_CALALR_OFFSET)
+#define SAM3U_RTC_SR (SAM3U_RTC_BASE+SAM3U_RTC_SR_OFFSET)
+#define SAM3U_RTC_SCCR (SAM3U_RTC_BASE+SAM3U_RTC_SCCR_OFFSET)
+#define SAM3U_RTC_IER (SAM3U_RTC_BASE+SAM3U_RTC_IER_OFFSET)
+#define SAM3U_RTC_IDR (SAM3U_RTC_BASE+SAM3U_RTC_IDR_OFFSET)
+#define SAM3U_RTC_IMR (SAM3U_RTC_BASE+SAM3U_RTC_IMR_OFFSET)
+#define SAM3U_RTC_VER (SAM3U_RTC_BASE+SAM3U_RTC_VER_OFFSET)
+
+/* RTC register bit definitions *********************************************************/
+
+#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)
+
+#define RTC_MR_HRMOD (1 << 0) /* Bit 0: 12-/24-hour Mode */
+
+#define RTC_TIMR_SEC_SHIFT (0) /* Bits 0-6: Current Second */
+#define RTC_TIMR_SEC_MASK (0x7f << 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_HOUR_SHIFT (16) /* Bits 16-21: Current Hour */
+#define RTC_TIMR_HOUR_MASK (0x3f << RTC_TIMR_HOUR_SHIFT)
+#define RTC_TIMR_AMPM (1 << 22) /* Bit 22: Ante Meridiem Post Meridiem Indicator */
+
+#define RTC_CALR_CENT_SHIFT (0) /* Bits 0-6: Current Century */
+#define RTC_CALR_CENT_MASK (0x7f << 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_MONTH_SHIFT (16) /* Bits 16-20: Current Month */
+#define RTC_CALR_MONTH_MASK (0x1f << 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_DATE_SHIFT (24) /* Bits 24-29: Current Day in Current Month */
+#define RTC_CALR_DATE_MASK (0x3f << RTC_CALR_DATE_SHIFT)
+
+#define RTC_TIMALR_SEC_SHIFT (0) /* Bits 0-6: Second Alarm */
+#define RTC_TIMALR_SEC_MASK (0x7f << 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_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_AMPM (1 << 22) /* Bit 22: AM/PM Indicator */
+#define RTC_TIMALR_HOUREN (1 << 23) /* Bit 23: Hour Alarm Enable */
+
+#define RTC_CALALR_MONTH_SHIFT (16) /* Bits 16-20: Month Alarm */
+#define RTC_CALALR_MONTH_MASK (0x1f << 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 (0x3c << RTC_CALALR_DATE_SHIFT)
+#define RTC_CALALR_DATEEN (1 << 31) /* Bit 31: Date Alarm Enable */
+
+#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_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_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_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_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_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_SAM3U_SAM3U_RTC_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_rtt.h b/nuttx/arch/arm/src/sam3u/sam3u_rtt.h
new file mode 100644
index 000000000..9cbb69b0a
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_rtt.h
@@ -0,0 +1,89 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_rtt.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_RTT_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_RTT_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* RTT register offsets *****************************************************************/
+
+#define SAM3U_RTT_MR_OFFSET 0x00 /* Mode Register */
+#define SAM3U_RTT_AR_OFFSET 0x04 /* Alarm Register */
+#define SAM3U_RTT_VR_OFFSET 0x08 /* Value Register */
+#define SAM3U_RTT_SR_OFFSET 0x0c /* Status Register */
+
+/* RTT register adresses ***************************************************************/
+
+#define SAM3U_RTT_MR (SAM3U_RTT_BASE+SAM3U_RTT_MR_OFFSET)
+#define SAM3U_RTT_AR (SAM3U_RTT_BASE+SAM3U_RTT_AR_OFFSET)
+#define SAM3U_RTT_VR (SAM3U_RTT_BASE+SAM3U_RTT_VR_OFFSET)
+#define SAM3U_RTT_SR (SAM3U_RTT_BASE+SAM3U_RTT_SR_OFFSET)
+
+/* RTT register bit definitions ********************************************************/
+
+#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_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 */
+
+#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_SAM3U_SAM3U_RTT_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_serial.c b/nuttx/arch/arm/src/sam3u/sam3u_serial.c
new file mode 100644
index 000000000..811bfda69
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_serial.c
@@ -0,0 +1,1450 @@
+/****************************************************************************
+ * arch/arm/src/sam3u/sam3u_serial.c
+ *
+ * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+
+#include <arch/serial.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "sam3u_uart.h"
+#include "up_arch.h"
+#include "up_internal.h"
+#include "os_internal.h"
+
+/****************************************************************************
+ * 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_SAM3U_USART0
+#endif
+#ifndef CONFIG_USART1_ISUART
+# undef CONFIG_SAM3U_USART1
+#endif
+#ifndef CONFIG_USART2_ISUART
+# undef CONFIG_SAM3U_USART2
+#endif
+#ifndef CONFIG_USART3_ISUART
+# undef CONFIG_SAM3U_USART3
+#endif
+
+/* Is there a USART/USART enabled? */
+
+#if !defined(CONFIG_SAM3U_UART) && !defined(CONFIG_SAM3U_USART0) && \
+ !defined(CONFIG_SAM3U_USART1) && !defined(CONFIG_SAM3U_USART2) && \
+ !defined(CONFIG_SAM3U_USART3)
+# error "No USARTs enabled"
+#endif
+
+#if defined(CONFIG_SAM3U_USART0) || defined(CONFIG_SAM3U_USART1) ||\
+ defined(CONFIG_SAM3U_USART2) || defined(CONFIG_SAM3U_USART3)
+# define HAVE_USART
+#endif
+
+/* Is there a serial console? */
+
+#if defined(CONFIG_UART_SERIAL_CONSOLE) && defined(CONFIG_SAM3U_UART)
+# 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_SAM3U_USART0)
+# undef CONFIG_UART_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_SAM3U_USART1)
+# undef CONFIG_UART_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_SAM3U_USART2)
+# undef CONFIG_UART_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_SAM3U_USART3)
+# undef CONFIG_UART_SERIAL_CONSOLE
+# undef CONFIG_USART0_SERIAL_CONSOLE
+# undef CONFIG_USART1_SERIAL_CONSOLE
+# undef CONFIG_USART2_SERIAL_CONSOLE
+# define HAVE_CONSOLE 1
+#else
+# warning "No valid CONFIG_USARTn_SERIAL_CONSOLE Setting"
+# undef CONFIG_UART_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 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/USART with be tty0/console and which tty1? tty2? tty3? tty4? */
+
+#if defined(CONFIG_UART_SERIAL_CONSOLE)
+# define CONSOLE_DEV g_uartport /* UART=console */
+# define TTYS0_DEV g_uartport /* UART=ttyS0 */
+# ifdef CONFIG_SAM3U_USART0
+# define TTYS1_DEV g_usart0port /* UART=ttyS0;USART0=ttyS1 */
+# ifdef CONFIG_SAM3U_USART1
+# define TTYS2_DEV g_usart1port /* UART=ttyS0;USART0=ttyS1;USART1=ttyS2 */
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS3_DEV g_usart2port /* UART=ttyS0;USART0=ttyS1;USART1=ttyS2;USART2=ttyS3 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS4_DEV g_usart3port /* UART=ttyS0;USART0=ttyS1;USART1=ttyS2;USART2=ttyS3;USART3=ttyS4 */
+# else
+# undef TTYS4_DEV /* UART=ttyS0;USART0=ttyS1;USART1=ttyS2;USART2=ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS3_DEV g_usart3port /* UART=ttyS0;USART0=ttyS1;USART1=ttyS;USART3=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* UART=ttyS0;USART0=ttyS1;USART1=ttyS;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS2_DEV g_usart2port /* UART=ttyS0;USART0=ttyS1;USART2=ttys2;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS3_DEV g_usart3port /* UART=ttyS0;USART0=ttyS1;USART2=ttys2;USART3=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* UART=ttyS0;USART0=ttyS1;USART2=ttys2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS2_DEV g_usart3port /* UART=ttyS0;USART0=ttyS1;USART3=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS2_DEV /* UART=ttyS0;USART0=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART1
+# define TTYS1_DEV g_usart1port /* UART=ttyS0;USART1=ttyS1;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS2_DEV g_usart2port /* UART=ttyS0;USART1=ttyS1;USART2=ttyS2;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS3_DEV g_usart3port /* UART=ttyS0;USART1=ttyS1;USART2=ttyS2;USART3=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* UART=ttyS0;USART1=ttyS1;USART2=ttyS2;No ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS2_DEV g_usart3port /* UART=ttyS0;USART1=ttyS1;USART3=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS2_DEV /* UART=ttyS0;USART1=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS1_DEV g_usart2port /* UART=ttyS0;USART2=ttyS1;No ttyS3;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS2_DEV g_usart3port /* UART=ttyS0;USART2=ttyS1;USART3=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS2_DEV /* UART=ttyS0;USART2=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS1_DEV g_usart3port /* UART=ttyS0;USART3=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS1_DEV /* UART=ttyS0;No ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS2_DEV /* No ttyS2 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+#elif defined(CONFIG_USART0_SERIAL_CONSOLE)
+# define CONSOLE_DEV g_usart0port /* USART0=console */
+# define TTYS0_DEV g_usart0port /* USART0=ttyS0 */
+# ifdef CONFIG_SAM3U_UART
+# define TTYS1_DEV g_uartport /* USART0=ttyS0;UART=ttyS1 */
+# ifdef CONFIG_SAM3U_USART1
+# define TTYS2_DEV g_usart1port /* USART0=ttyS0;UART=ttyS1;USART1=ttyS2 */
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS3_DEV g_usart2port /* USART0=ttyS0;UART=ttyS1;USART1=ttyS2;USART2=ttyS3 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS4_DEV g_usart3port /* USART0=ttyS0;UART=ttyS1;USART1=ttyS2;USART2=ttyS3;USART3=ttyS4 */
+# else
+# undef TTYS4_DEV /* USART0=ttyS0;UART=ttyS1;USART1=ttyS2;USART2=ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS3_DEV g_usart3port /* USART0=ttyS0;UART=ttyS1;USART1=ttyS;USART3=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART0=ttyS0;UART=ttyS1;USART1=ttyS;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS2_DEV g_usart2port /* USART0=ttyS0;UART=ttyS1;USART2=ttys2;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS3_DEV g_usart3port /* USART0=ttyS0;UART=ttyS1;USART2=ttys2;USART3=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART0=ttyS0;UART=ttyS1;USART2=ttys2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS2_DEV g_usart3port /* USART0=ttyS0;UART=ttyS1;USART3=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS2_DEV /* USART0=ttyS0;UART=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART1
+# define TTYS1_DEV g_usart1port /* USART0=ttyS0;USART1=ttyS1;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS2_DEV g_usart2port /* USART0=ttyS0;USART1=ttyS1;USART2=ttyS2;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS3_DEV g_usart3port /* USART0=ttyS0;USART1=ttyS1;USART2=ttyS2;USART3=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART0=ttyS0;USART1=ttyS1;USART2=ttyS2;No ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS2_DEV g_usart3port /* USART0=ttyS0;USART1=ttyS1;USART3=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS2_DEV /* USART0=ttyS0;USART1=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS1_DEV g_usart2port /* USART0=ttyS0;USART2=ttyS1;No ttyS3;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS2_DEV g_usart3port /* USART0=ttyS0;USART2=ttyS1;USART3=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART0=ttyS0;USART2=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS1_DEV g_usart3port /* USART0=ttyS0;USART3=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS1_DEV /* USART0=ttyS0;No ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS2_DEV /* No ttyS2 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+#elif defined(CONFIG_USART1_SERIAL_CONSOLE)
+# define CONSOLE_DEV g_usart1port /* USART1=console */
+# define TTYS0_DEV g_usart1port /* USART1=ttyS0 */
+# ifdef CONFIG_SAM3U_UART
+# define TTYS1_DEV g_uartport /* USART1=ttyS0;UART=ttyS1 */
+# ifdef CONFIG_SAM3U_USART0
+# define TTYS2_DEV g_usart0port /* USART1=ttyS0;UART=ttyS1;USART0=ttyS2 */
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS3_DEV g_usart2port /* USART1=ttyS0;UART=ttyS1;USART0=ttyS2;USART2=ttyS3 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS4_DEV g_usart3port /* USART1=ttyS0;UART=ttyS1;USART0=ttyS2;USART2=ttyS3;USART3=ttyS4 */
+# else
+# undef TTYS4_DEV /* USART1=ttyS0;UART=ttyS1;USART0=ttyS2;USART2=ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS3_DEV g_usart3port /* USART1=ttyS0;UART=ttyS1;USART0=ttyS;USART3=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART1=ttyS0;UART=ttyS1;USART0=ttyS;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS2_DEV g_usart2port /* USART1=ttyS0;UART=ttyS1;USART2=ttys2;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS3_DEV g_usart3port /* USART1=ttyS0;UART=ttyS1;USART2=ttys2;USART3=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART1=ttyS0;UART=ttyS1;USART2=ttys2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS2_DEV g_usart3port /* USART1=ttyS0;UART=ttyS1;USART3=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS2_DEV /* USART1=ttyS0;UART=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART0
+# define TTYS1_DEV g_usart0port /* USART1=ttyS0;USART0=ttyS1;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS2_DEV g_usart2port /* USART1=ttyS0;USART0=ttyS1;USART2=ttyS2;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS3_DEV g_usart3port /* USART1=ttyS0;USART0=ttyS1;USART2=ttyS2;USART3=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART1=ttyS0;USART0=ttyS1;USART2=ttyS2;No ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS2_DEV g_usart3port /* USART1=ttyS0;USART0=ttyS1;USART3=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS2_DEV /* USART1=ttyS0;USART0=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS1_DEV g_usart2port /* USART1=ttyS0;USART2=ttyS1;No ttyS3;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS2_DEV g_usart3port /* USART1=ttyS0;USART2=ttyS1;USART3=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART1=ttyS0;USART2=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS1_DEV g_usart3port /* USART1=ttyS0;USART3=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS1_DEV /* USART1=ttyS0;No ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS2_DEV /* No ttyS2 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+#elif defined(CONFIG_USART2_SERIAL_CONSOLE)
+# define CONSOLE_DEV g_usart2port /* USART2=console */
+# define TTYS0_DEV g_usart2port /* USART2=ttyS0 */
+# ifdef CONFIG_SAM3U_UART
+# define TTYS1_DEV g_uartport /* USART2=ttyS0;UART=ttyS1 */
+# ifdef CONFIG_SAM3U_USART0
+# define TTYS2_DEV g_usart0port /* USART2=ttyS0;UART=ttyS1;USART0=ttyS2 */
+# ifdef CONFIG_SAM3U_USART1
+# define TTYS3_DEV g_usart1port /* USART2=ttyS0;UART=ttyS1;USART0=ttyS2;USART1=ttyS3 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS4_DEV g_usart3port /* USART2=ttyS0;UART=ttyS1;USART0=ttyS2;USART1=ttyS3;USART3=ttyS4 */
+# else
+# undef TTYS4_DEV /* USART2=ttyS0;UART=ttyS1;USART0=ttyS2;USART1=ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS3_DEV g_usart3port /* USART2=ttyS0;UART=ttyS1;USART0=ttyS;USART3=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART2=ttyS0;UART=ttyS1;USART0=ttyS;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART1
+# define TTYS2_DEV g_usart1port /* USART2=ttyS0;UART=ttyS1;USART1=ttys2;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS3_DEV g_usart3port /* USART2=ttyS0;UART=ttyS1;USART1=ttys2;USART3=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART2=ttyS0;UART=ttyS1;USART1=ttys2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS2_DEV g_usart3port /* USART2=ttyS0;UART=ttyS1;USART3=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS2_DEV /* USART2=ttyS0;UART=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART0
+# define TTYS1_DEV g_usart0port /* USART2=ttyS0;USART0=ttyS1;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART1
+# define TTYS2_DEV g_usart1port /* USART2=ttyS0;USART0=ttyS1;USART1=ttyS2;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS3_DEV g_usart3port /* USART2=ttyS0;USART0=ttyS1;USART1=ttyS2;USART3=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART2=ttyS0;USART0=ttyS1;USART1=ttyS2;No ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS2_DEV g_usart3port /* USART2=ttyS0;USART0=ttyS1;USART3=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS2_DEV /* USART2=ttyS0;USART0=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART1
+# define TTYS1_DEV g_usart1port /* USART2=ttyS0;USART1=ttyS1;No ttyS3;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS2_DEV g_usart3port /* USART2=ttyS0;USART1=ttyS1;USART3=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS2_DEV /* USART2=ttyS0;USART1=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART3
+# define TTYS1_DEV g_usart3port /* USART2=ttyS0;USART3=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS1_DEV /* USART2=ttyS0;No ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS2_DEV /* No ttyS2 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+#elif defined(CONFIG_USART3_SERIAL_CONSOLE)
+# define CONSOLE_DEV g_usart3port /* USART3=console */
+# define TTYS0_DEV g_usart3port /* USART3=ttyS0 */
+# ifdef CONFIG_SAM3U_UART
+# define TTYS1_DEV g_uartport /* USART3=ttyS0;UART=ttyS1 */
+# ifdef CONFIG_SAM3U_USART0
+# define TTYS2_DEV g_usart0port /* USART3=ttyS0;UART=ttyS1;USART0=ttyS2 */
+# ifdef CONFIG_SAM3U_USART1
+# define TTYS3_DEV g_usart1port /* USART3=ttyS0;UART=ttyS1;USART0=ttyS2;USART1=ttyS3 */
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS4_DEV g_usart2port /* USART3=ttyS0;UART=ttyS1;USART0=ttyS2;USART1=ttyS3;USART2=ttyS4 */
+# else
+# undef TTYS4_DEV /* USART3=ttyS0;UART=ttyS1;USART0=ttyS2;USART1=ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS3_DEV g_usart2port /* USART3=ttyS0;UART=ttyS1;USART0=ttyS;USART2=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART3=ttyS0;UART=ttyS1;USART0=ttyS;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART1
+# define TTYS2_DEV g_usart1port /* USART3=ttyS0;UART=ttyS1;USART1=ttys2;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS3_DEV g_usart2port /* USART3=ttyS0;UART=ttyS1;USART1=ttys2;USART2=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART3=ttyS0;UART=ttyS1;USART1=ttys2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# else
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS2_DEV g_usart2port /* USART3=ttyS0;UART=ttyS1;USART2=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS2_DEV /* USART3=ttyS0;UART=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART0
+# define TTYS1_DEV g_usart0port /* USART3=ttyS0;USART0=ttyS1;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART1
+# define TTYS2_DEV g_usart1port /* USART3=ttyS0;USART0=ttyS1;USART1=ttyS2;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS3_DEV g_usart2port /* USART3=ttyS0;USART0=ttyS1;USART1=ttyS2;USART2=ttyS3;No ttyS4 */
+# else
+# undef TTYS3_DEV /* USART3=ttyS0;USART0=ttyS1;USART1=ttyS2;No ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS2_DEV g_usart2port /* USART3=ttyS0;USART0=ttyS1;USART2=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS2_DEV /* USART3=ttyS0;USART0=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART1
+# define TTYS1_DEV g_usart1port /* USART3=ttyS0;USART1=ttyS1;No ttyS3;No ttyS4 */
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS2_DEV g_EEEEport /* USART3=ttyS0;USART1=ttyS1;USART2=ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS2_DEV /* USART3=ttyS0;USART1=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# else
+# ifdef CONFIG_SAM3U_USART2
+# define TTYS1_DEV g_usart2port /* USART3=ttyS0;USART2=ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# else
+# undef TTYS1_DEV /* USART3=ttyS0;No ttyS1;No ttyS2;No ttyS3;No ttyS4 */
+# endif
+# undef TTYS2_DEV /* No ttyS2 */
+# endif
+# undef TTYS3_DEV /* No ttyS3 */
+# endif
+# undef TTYS4_DEV /* No ttyS4 */
+# endif
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct up_dev_s
+{
+ uint32_t usartbase; /* Base address of USART registers */
+ uint32_t baud; /* Configured baud */
+ uint32_t imr; /* Saved interrupt mask bits value */
+ 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 */
+};
+
+/****************************************************************************
+ * 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 Variables
+ ****************************************************************************/
+
+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,
+ .send = up_send,
+ .txint = up_txint,
+ .txready = up_txready,
+ .txempty = up_txempty,
+};
+
+/* I/O buffers */
+
+#ifdef CONFIG_SAM3U_UART
+static char g_uartrxbuffer[CONFIG_UART_RXBUFSIZE];
+static char g_uarttxbuffer[CONFIG_UART_TXBUFSIZE];
+#endif
+#ifdef CONFIG_SAM3U_USART0
+static char g_usart0rxbuffer[CONFIG_USART0_RXBUFSIZE];
+static char g_usart0txbuffer[CONFIG_USART0_TXBUFSIZE];
+#endif
+#ifdef CONFIG_SAM3U_USART1
+static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE];
+static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE];
+#endif
+#ifdef CONFIG_SAM3U_USART2
+static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE];
+static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE];
+#endif
+#ifdef CONFIG_SAM3U_USART3
+static char g_usart3rxbuffer[CONFIG_USART3_RXBUFSIZE];
+static char g_usart3txbuffer[CONFIG_USART3_TXBUFSIZE];
+#endif
+
+/* This describes the state of the SAM3U UART port. */
+
+#ifdef CONFIG_SAM3U_UART
+static struct up_dev_s g_uartpriv =
+{
+ .usartbase = SAM3U_UART_BASE,
+ .baud = CONFIG_UART_BAUD,
+ .irq = SAM3U_IRQ_UART,
+ .parity = CONFIG_UART_PARITY,
+ .bits = CONFIG_UART_BITS,
+ .stopbits2 = CONFIG_UART_2STOP,
+};
+
+static uart_dev_t g_uartport =
+{
+ .recv =
+ {
+ .size = CONFIG_UART_RXBUFSIZE,
+ .buffer = g_uartrxbuffer,
+ },
+ .xmit =
+ {
+ .size = CONFIG_UART_TXBUFSIZE,
+ .buffer = g_uarttxbuffer,
+ },
+ .ops = &g_uart_ops,
+ .priv = &g_uartpriv,
+};
+#endif
+
+/* This describes the state of the SAM3U USART1 ports. */
+
+#ifdef CONFIG_SAM3U_USART0
+static struct up_dev_s g_usart0priv =
+{
+ .usartbase = SAM3U_USART0_BASE,
+ .baud = CONFIG_USART0_BAUD,
+ .irq = SAM3U_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 SAM3U USART1 ports. */
+
+#ifdef CONFIG_SAM3U_USART1
+static struct up_dev_s g_usart1priv =
+{
+ .usartbase = SAM3U_USART1_BASE,
+ .baud = CONFIG_USART1_BAUD,
+ .irq = SAM3U_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 SAM3U USART2 port. */
+
+#ifdef CONFIG_SAM3U_USART2
+static struct up_dev_s g_usart2priv =
+{
+ .usartbase = SAM3U_USART2_BASE,
+ .baud = CONFIG_USART2_BAUD,
+ .irq = SAM3U_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
+
+/* This describes the state of the SAM3U USART3 port. */
+
+#ifdef CONFIG_SAM3U_USART3
+static struct up_dev_s g_usart3priv =
+{
+ .usartbase = SAM3U_USART3_BASE,
+ .baud = CONFIG_USART3_BAUD,
+ .irq = SAM3U_IRQ_USART3,
+ .parity = CONFIG_USART3_PARITY,
+ .bits = CONFIG_USART3_BITS,
+ .stopbits2 = CONFIG_USART3_2STOP,
+};
+
+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_enableint
+ ****************************************************************************/
+
+static inline void up_enableint(struct up_dev_s *priv)
+{
+ up_serialout(priv, SAM3U_UART_IER_OFFSET, priv->imr);
+}
+
+/****************************************************************************
+ * Name: up_disableint
+ ****************************************************************************/
+
+static inline void up_disableint(struct up_dev_s *priv)
+{
+ up_serialout(priv, SAM3U_UART_IDR_OFFSET, ~priv->imr);
+}
+
+/****************************************************************************
+ * Name: up_restoreusartint
+ ****************************************************************************/
+
+static void up_restoreusartint(struct up_dev_s *priv, uint32_t imr)
+{
+ /* Save the interrupt mask */
+
+ priv->imr = imr;
+
+ /* And re-enable interrrupts previoulsy disabled by up_disableallints */
+
+ up_enableint(priv);
+}
+
+/****************************************************************************
+ * Name: up_disableallints
+ ****************************************************************************/
+
+static void up_disableallints(struct up_dev_s *priv, uint32_t *imr)
+{
+ if (imr)
+ {
+ /* Return the current interrupt mask */
+
+ *imr = priv->imr;
+ }
+
+ /* Disable all interrupts */
+
+ priv->imr = 0;
+ up_disableint(priv);
+}
+
+/****************************************************************************
+ * 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 sam3u_lowsetup().
+ */
+
+ /* The shutdown method will put the UART in a known, disabled state */
+
+ up_shutdown(dev);
+
+ /* Set up the mode register. Start with normal UART mode and the MCK
+ * as the timing source
+ */
+
+ regval = (USART_MR_MODE_NORMAL|USART_MR_USCLKS_MCK);
+
+ /* OR in settings for the selected number of bits */
+
+ if (priv->bits == 5)
+ {
+ regval |= USART_MR_CHRL_5BITS; /* 5 bits */
+ }
+ else if (priv->bits == 6)
+ {
+ regval |= USART_MR_CHRL_6BITS; /* 6 bits */
+ }
+ else if (priv->bits == 7)
+ {
+ regval |= USART_MR_CHRL_7BITS; /* 7 bits */
+ }
+#ifdef HAVE_USART
+#ifdef CONFIG_SAM3U_UART
+ /* UART does not support 9bit mode */
+
+ else if (priv->bits == 9 && priv->usartbase != SAM3U_UART_BASE)
+#else
+ else if (priv->bits == 9) /* Only USARTS */
+#endif
+ {
+ regval |= USART_MR_MODE9; /* 9 bits */
+ }
+#endif
+ else /* if (priv->bits == 8) */
+ {
+ regval |= USART_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 |= USART_MR_NBSTOP_2;
+ }
+ else
+ {
+ regval |= USART_MR_NBSTOP_1;
+ }
+
+ /* And save the new mode register value */
+
+ up_serialout(priv, SAM3U_UART_MR_OFFSET, regval);
+
+ /* Configure the console baud */
+
+ regval = (SAM3U_MCK_FREQUENCY + (priv->baud << 3))/(priv->baud << 4);
+ up_serialout(priv, SAM3U_UART_BRGR_OFFSET, regval);
+
+ /* Enable receiver & transmitter */
+
+ up_serialout(priv, SAM3U_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, SAM3U_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;
+ int passes;
+ bool handled;
+
+#ifdef CONFIG_SAM3U_UART
+ if (g_uartpriv.irq == irq)
+ {
+ dev = &g_uartport;
+ }
+ else
+#endif
+#ifdef CONFIG_SAM3U_USART0
+ if (g_usart0priv.irq == irq)
+ {
+ dev = &g_usart0port;
+ }
+ else
+#endif
+#ifdef CONFIG_SAM3U_USART1
+ if (g_usart1priv.irq == irq)
+ {
+ dev = &g_usart1port;
+ }
+ else
+#endif
+#ifdef CONFIG_SAM3U_USART2
+ if (g_usart2priv.irq == irq)
+ {
+ dev = &g_usart2port;
+ }
+ else
+#endif
+#ifdef CONFIG_SAM3U_USART3
+ if (g_usart3priv.irq == irq)
+ {
+ dev = &g_usart3port;
+ }
+ else
+#endif
+ {
+ PANIC(OSERR_INTERNAL);
+ }
+ 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, SAM3U_UART_SR_OFFSET); /* Save for error reporting */
+ pending = priv->sr & priv->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 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)
+{
+ struct inode *inode = filep->f_inode;
+ struct uart_dev_s *dev = inode->i_private;
+ int ret = OK;
+
+ switch (cmd)
+ {
+ 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;
+
+ 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, SAM3U_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
+ priv->imr |= UART_INT_RXRDY;
+ up_enableint(priv);
+#endif
+ }
+ else
+ {
+ priv->imr &= ~UART_INT_RXRDY;
+ up_disableint(priv);
+ }
+}
+
+/****************************************************************************
+ * 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, SAM3U_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, SAM3U_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 = irqsave();
+ if (enable)
+ {
+ /* Set to receive an interrupt when the TX holding register register
+ * is empty
+ */
+
+#ifndef CONFIG_SUPPRESS_SERIAL_INTS
+ priv->imr |= UART_INT_TXRDY;
+ up_enableint(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->imr &= ~UART_INT_TXRDY;
+ up_disableint(priv);
+ }
+ irqrestore(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, SAM3U_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, SAM3U_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.
+ *
+ ****************************************************************************/
+
+void up_earlyserialinit(void)
+{
+ /* NOTE: All GPIO configuration for the USARTs was performed in
+ * sam3u_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
+
+ /* 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 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
+}
+
+/****************************************************************************
+ * 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 imr;
+
+ up_disableallints(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_CONSOLE
+ /* Check for LF */
+
+ if (ch == '\n')
+ {
+ /* Add CR */
+
+ up_lowputc('\r');
+ }
+
+ up_lowputc(ch);
+#endif
+ return ch;
+}
+
+#endif /* USE_SERIALDRIVER */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_smc.h b/nuttx/arch/arm/src/sam3u/sam3u_smc.h
new file mode 100644
index 000000000..c831a91cd
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_smc.h
@@ -0,0 +1,432 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_smc.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_SMC_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_SMC_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* SMC register offsets *****************************************************************/
+
+#define SAM3U_SMC_CFG_OFFSET 0x000 /* SMC NFC Configuration Register */
+#define SAM3U_SMC_CTRL_OFFSET 0x004 /* SMC NFC Control Register */
+#define SAM3U_SMC_SR_OFFSET 0x008 /* SMC NFC Status Register */
+#define SAM3U_SMC_IER_OFFSET 0x00c /* SMC NFC Interrupt Enable Register */
+#define SAM3U_SMC_IDR_OFFSET 0x010 /* SMC NFC Interrupt Disable Register */
+#define SAM3U_SMC_IMR_OFFSET 0x014 /* SMC NFC Interrupt Mask Register */
+#define SAM3U_SMC_ADDR_OFFSET 0x018 /* SMC NFC Address Cycle Zero Register */
+#define SAM3U_SMC_BANK_OFFSET 0x01c /* SMC Bank Address Register */
+#define SAM3U_SMC_ECCCTRL_OFFSET 0x020 /* SMC ECC Control Register */
+#define SAM3U_SMC_ECCMD_OFFSET 0x024 /* SMC ECC Mode Register */
+#define SAM3U_SMC_ECCSR1_OFFSET 0x028 /* SMC ECC Status 1 Register */
+#define SAM3U_SMC_ECCPR0_OFFSET 0x02c /* SMC ECC parity 0 Register */
+#define SAM3U_SMC_ECCPR1_OFFSET 0x030 /* SMC ECC parity 1 Register */
+#define SAM3U_SMC_ECCSR2_OFFSET 0x034 /* SMC ECC status 2 Register */
+#define SAM3U_SMC_ECCPR2_OFFSET 0x038 /* SMC ECC parity 2 Register */
+#define SAM3U_SMC_ECCPR3_OFFSET 0x03c /* SMC ECC parity 3 Register */
+#define SAM3U_SMC_ECCPR4_OFFSET 0x040 /* SMC ECC parity 4 Register */
+#define SAM3U_SMC_ECCPR5_OFFSET 0x044 /* SMC ECC parity 5 Register */
+#define SAM3U_SMC_ECCPR6_OFFSET 0x048 /* SMC ECC parity 6 Register */
+#define SAM3U_SMC_ECCPR7_OFFSET 0x04c /* SMC ECC parity 7 Register */
+#define SAM3U_SMC_ECCPR8_OFFSET 0x050 /* SMC ECC parity 8 Register */
+#define SAM3U_SMC_ECCPR9_OFFSET 0x054 /* SMC ECC parity 9 Register */
+#define SAM3U_SMC_ECCPR10_OFFSET 0x058 /* SMC ECC parity 10 Register */
+#define SAM3U_SMC_ECCPR11_OFFSET 0x05c /* SMC ECC parity 11 Register */
+#define SAM3U_SMC_ECCPR12_OFFSET 0x060 /* SMC ECC parity 12 Register */
+#define SAM3U_SMC_ECCPR13_OFFSET 0x064 /* SMC ECC parity 13 Register */
+#define SAM3U_SMC_ECCPR14_OFFSET 0x068 /* SMC ECC parity 14 Register */
+#define SAM3U_SMC_ECCPR15_OFFSET 0x06c /* SMC ECC parity 15 Register */
+
+#define SAM3U_SMCCS_OFFSET(n) (0x070+((n)*0x014))
+#define SAM3U_SMCCS_SETUP_OFFSET 0x000 /* SMC SETUP Register */
+#define SAM3U_SMCCS_PULSE_OFFSET 0x004 /* SMC PULSE Register */
+#define SAM3U_SMCCS_CYCLE_OFFSET 0x008 /* SMC CYCLE Register */
+#define SAM3U_SMCCS_TIMINGS_OFFSET 0x00c /* SMC TIMINGS Register */
+#define SAM3U_SMCCS_MODE_OFFSET 0x010 /* SMC MODE Register */
+
+#define SAM3U_SMC_OCMS_OFFSET 0x110 /* SMC OCMS MODE Register */
+#define SAM3U_SMC_KEY1_OFFSET 0x114 /* SMC KEY1 Register */
+#define SAM3U_SMC_KEY2_OFFSET 0x118 /* SMC KEY2 Register */
+#define SAM3U_SMC_WPCR_OFFSET 0x1e4 /* Write Protection Control Register */
+#define SAM3U_SMC_WPSR_OFFSET 0x1e8 /* Write Protection Status Register */
+
+/* SMC register adresses ****************************************************************/
+
+#define SAM3U_SMC_CFG (SAM3U_SMC_BASE+SAM3U_SMC_CFG_OFFSET)
+#define SAM3U_SMC_CTRL (SAM3U_SMC_BASE+SAM3U_SMC_CTRL_OFFSET)
+#define SAM3U_SMC_SR (SAM3U_SMC_BASE+SAM3U_SMC_SR_OFFSET)
+#define SAM3U_SMC_IER (SAM3U_SMC_BASE+SAM3U_SMC_IER_OFFSET)
+#define SAM3U_SMC_IDR (SAM3U_SMC_BASE+SAM3U_SMC_IDR_OFFSET)
+#define SAM3U_SMC_IMR (SAM3U_SMC_BASE+SAM3U_SMC_IMR_OFFSET)
+#define SAM3U_SMC_ADDR (SAM3U_SMC_BASE+SAM3U_SMC_ADDR_OFFSET)
+#define SAM3U_SMC_BANK (SAM3U_SMC_BASE+SAM3U_SMC_BANK_OFFSET)
+#define SAM3U_SMC_ECCCTRL (SAM3U_SMC_BASE+SAM3U_SMC_ECCCTRL_OFFSET)
+#define SAM3U_SMC_ECCMD (SAM3U_SMC_BASE+SAM3U_SMC_ECCMD_OFFSET)
+#define SAM3U_SMC_ECCSR1 (SAM3U_SMC_BASE+SAM3U_SMC_ECCSR1_OFFSET)
+#define SAM3U_SMC_ECCPR0 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR0_OFFSET)
+#define SAM3U_SMC_ECCPR1 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR1_OFFSET)
+#define SAM3U_SMC_ECCSR2 (SAM3U_SMC_BASE+SAM3U_SMC_ECCSR2_OFFSET)
+#define SAM3U_SMC_ECCPR2 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR2_OFFSET)
+#define SAM3U_SMC_ECCPR3 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR3_OFFSET)
+#define SAM3U_SMC_ECCPR4 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR4_OFFSET)
+#define SAM3U_SMC_ECCPR5 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR5_OFFSET)
+#define SAM3U_SMC_ECCPR6 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR6_OFFSET)
+#define SAM3U_SMC_ECCPR7 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR7_OFFSET)
+#define SAM3U_SMC_ECCPR8 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR8_OFFSET)
+#define SAM3U_SMC_ECCPR9 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR9_OFFSET)
+#define SAM3U_SMC_ECCPR10 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR10_OFFSET)
+#define SAM3U_SMC_ECCPR11 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR11_OFFSET)
+#define SAM3U_SMC_ECCPR12 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR12_OFFSET)
+#define SAM3U_SMC_ECCPR13 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR13_OFFSET)
+#define SAM3U_SMC_ECCPR14 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR14_OFFSET)
+#define SAM3U_SMC_ECCPR15 (SAM3U_SMC_BASE+SAM3U_SMC_ECCPR15_OFFSET)
+
+#define SAM3U_SMCCS_BASE(n) (SAM3U_SMC_BASE+SAM3U_SMCCS_OFFSET(n))
+# define SAM3U_SMC_CS0_BASE (SAM3U_SMC_BASE+SAM3U_SMCCS_OFFSET(0))
+# define SAM3U_SMC_CS1_BASE (SAM3U_SMC_BASE+SAM3U_SMCCS_OFFSET(1))
+# define SAM3U_SMC_CS2_BASE (SAM3U_SMC_BASE+SAM3U_SMCCS_OFFSET(2))
+# define SAM3U_SMC_CS3_BASE (SAM3U_SMC_BASE+SAM3U_SMCCS_OFFSET(3))
+#define SAM3U_SMCCS_SETUP(n) (SAM3U_SMCCS_BASE(n)+SAM3U_SMCCS_SETUP_OFFSET)
+#define SAM3U_SMCCS_PULSE(n) (SAM3U_SMCCS_BASE(n)+SAM3U_SMCCS_PULSE_OFFSET)
+#define SAM3U_SMCCS_CYCLE(n) (SAM3U_SMCCS_BASE(n)+SAM3U_SMCCS_CYCLE_OFFSET)
+#define SAM3U_SMCCS_TIMINGS(n) (SAM3U_SMCCS_BASE(n)+SAM3U_SMCCS_TIMINGS_OFFSET)
+#define SAM3U_SMCCS_MODE(n) (SAM3U_SMCCS_BASE(n)+SAM3U_SMCCS_MODE_OFFSET)
+
+#define SAM3U_SMC_OCMS (SAM3U_SMC_BASE+SAM3U_SMC_OCMS_OFFSET)
+#define SAM3U_SMC_KEY1 (SAM3U_SMC_BASE+SAM3U_SMC_KEY1_OFFSET)
+#define SAM3U_SMC_KEY2 (SAM3U_SMC_BASE+SAM3U_SMC_KEY2_OFFSET)
+#define SAM3U_SMC_WPCR (SAM3U_SMC_BASE+SAM3U_SMC_WPCR_OFFSET)
+#define SAM3U_SMC_WPSR (SAM3U_SMC_BASE+SAM3U_SMC_WPSR_OFFSET)
+
+/* SMC register bit definitions *********************************************************/
+
+/* SMC NFC Configuration Register */
+
+#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_16 BYTES (0 << SMC_CFG_PAGESIZE_SHIFT) /* 528 Bytes 16 byte */
+# define SMC_CFG_PAGESIZE_ 2 BYTES (1 << SMC_CFG_PAGESIZE_SHIFT) /* 1056 Bytes 32 bytes */
+# define SMC_CFG_PAGESIZE_64 BYTES (2 << SMC_CFG_PAGESIZE_SHIFT) /* 2112 Bytes 64 bytes */
+# define SMC_CFG_PAGESIZE_128 BYTES (3 << SMC_CFG_PAGESIZE_SHIFT) /* 4224 Bytes 128 bytes */
+#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)
+
+/* SMC NFC Control Register */
+
+#define SMC_CTRL_NFCEN (1 << 0) /* Bit 0: NAND Flash Controller Enable */
+#define SMC_CTRL_NFCDIS (1 << 1) /* Bit 1: NAND Flash Controller Disable */
+
+/* SMC NFC Status Register, SMC NFC Interrupt Enable Register, SMC NFC Interrupt
+ * Disable Register, and SMC NFC Interrupt Mask Register common bit-field definitions
+ */
+
+#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 (1 << 12) /* Bit 13: NFC Chip Select ID (SR only) */
+#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 */
+#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 */
+
+/* SMC NFC Address Cycle Zero Register */
+
+#define SMC_ADDR_ADDR_CYCLE0_SHIFT (3) /* Bits 0-7: NAND Flash Array Address cycle 0 */
+#define SMC_ADDR_ADDR_CYCLE0_SHIFT (3) /* Bits 0-7: NAND Flash Array Address cycle 0 */
+
+/* SMC NFC Bank Register */
+
+#define SMC_BANK_SHIFT (0) /* Bits 0-2: Bank identifier */
+#define SMC_BANK_MASK (7 << SMC_BANK_SHIFT)
+
+/* SMC ECC Control Register */
+
+#define SMC_ECCCTRL_RST (1 << 0) /* Bit 0: Reset ECC */
+#define SMC_ECCCTRL_SWRST (1 << 1) /* Bit 1: Software Reset */
+
+/* SMC ECC MODE Register */
+
+#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)
+# define SMC_ECCMD_ECC_PAGESIZE_1056 (1 << SMC_ECCMD_ECC_PAGESIZE_SHIFT)
+# define SMC_ECCMD_ECC_PAGESIZE_2112 (2 << SMC_ECCMD_ECC_PAGESIZE_SHIFT)
+# define SMC_ECCMD_ECC_PAGESIZE_4224 (3 << SMC_ECCMD_ECC_PAGESIZE_SHIFT)
+#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 */
+
+/* SMC ECC Status Register 1 */
+
+#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)
+
+/* SMC ECC Status Register 2 */
+
+#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)
+
+/* Registers for 1 ECC for a page of 512/1024/2048/4096 bytes */
+/* SMC_ECC_PR0 */
+
+#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)
+
+#define SMC_ECCPR1_NPARITY_SHIFT (0) /* Bits 0-15 */
+#define SMC_ECCPR1_NPARITY_MASK (0xffff << SMC_ECCPR1_NPARITY_SHIFT)
+
+/* Registers for 1 ECC per 512 bytes for a page of 512/2048/4096 bytes, 8-bit word */
+
+#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)
+
+/* Registers for 1 ECC per 256 bytes for a page of 512/2048/4096 bytes, 8-bit word */
+
+#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)
+
+/* 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_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_NRDSETUP_SHIFT (16) /* Bits 16-21: NRD Setup length */
+#define SMCCS_SETUP_NRDSETUP_MASK (63 << 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)
+
+/* SMC Pulse Register */
+
+#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_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_RDPULSE_SHIFT (16) /* Bits 16-21: NRD Pulse Length */
+#define SMCCS_PULSE_RDPULSE_MASK (63 << SMCCS_PULSE_RDPULSE_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)
+
+/* 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_NRDCYCLE_SHIFT (16) /* Bits 16-24: Total Read Cycle Length */
+#define SMCCS_CYCLE_NRDCYCLE_MASK (0x1ff << SMCCS_CYCLE_NRDCYCLE_SHIFT)
+
+/* SMC Timings Register */
+
+#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 */
+
+/* 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_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 */
+#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_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 Register */
+
+#define SMC_OCMS_SMSE (1 << 0) /* Bit 0: Static Memory Controller Scrambling Enable */
+#define SMC_OCMS_SRSE (1 << 1) /* Bit 1: SRAM Scrambling Enable */
+
+/* SMC Write Protection Control */
+
+#define SMC_WPCR_WPPEN (1 << 9) /* Bit 9: 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)
+
+/* SMC Write Protection Status */
+
+#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 */
+#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_SAM3U_SAM3U_SMC_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_spi.c b/nuttx/arch/arm/src/sam3u/sam3u_spi.c
new file mode 100644
index 000000000..8f3c2e28b
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_spi.c
@@ -0,0 +1,948 @@
+/****************************************************************************
+ * arch/arm/src/sam3u/sam3u_spi.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt <gnutt@nuttx.org>
+ * Diego Sanchez <dsanchez@nx-engineering.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+#include <nuttx/arch.h>
+#include <nuttx/spi.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "sam3u_internal.h"
+#include "sam3u_pmc.h"
+#include "sam3u_spi.h"
+
+#ifdef CONFIG_SAM3U_SPI
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* 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
+#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 one chip select */
+
+#ifndef CONFIG_SPI_OWNBUS
+struct sam3u_chipselect_s
+{
+ 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 */
+};
+#endif
+
+/* The overall state of the SPI interface */
+
+struct sam3u_spidev_s
+{
+ struct spi_dev_s spidev; /* Externally visible part of the SPI interface */
+#ifndef CONFIG_SPI_OWNBUS
+ sem_t exclsem; /* Held while chip is selected for mutual exclusion */
+ struct sam3u_chipselect_s csstate[4];
+#endif
+ uint8_t cs; /* Chip select number */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helpers */
+
+#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE)
+static void spi_dumpregs(FAR const char *msg);
+#else
+# define spi_dumpregs(msg)
+#endif
+
+static inline void spi_flush(void);
+static inline uint32_t spi_cs2pcs(FAR struct sam3u_spidev_s *priv);
+
+/* SPI methods */
+
+#ifndef CONFIG_SPI_OWNBUS
+static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
+#endif
+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_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
+ ****************************************************************************/
+
+/* SPI driver operations */
+
+static const struct spi_ops_s g_spiops =
+{
+#ifndef CONFIG_SPI_OWNBUS
+ .lock = spi_lock,
+#endif
+ .select = spi_select,
+ .setfrequency = spi_setfrequency,
+ .setmode = spi_setmode,
+ .setbits = spi_setbits,
+ .status = sam3u_spistatus,
+#ifdef CONFIG_SPI_CMDDATA
+ .cmddata = sam3u_spicmddata,
+#endif
+ .send = spi_send,
+#ifdef CONFIG_SPI_EXCHANGE
+ .exchange = spi_exchange,
+#else
+ .sndblock = spi_sndblock,
+ .recvblock = spi_recvblock,
+#endif
+ .registercallback = 0, /* Not implemented */
+};
+
+/* SPI device structure */
+
+static struct sam3u_spidev_s g_spidev =
+{
+ .spidev = { &g_spiops },
+};
+
+/* This array maps chip select numbers (0-3) to CSR register addresses */
+
+static const uint32_t g_csraddr[4] =
+{
+ SAM3U_SPI_CSR0, SAM3U_SPI_CSR1, SAM3U_SPI_CSR2, SAM3U_SPI_CSR3
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: spi_dumpregs
+ *
+ * Description:
+ * Dump the contents of all SPI registers
+ *
+ * Input Parameters:
+ * 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 const char *msg)
+{
+ spivdbg("%s:\n", msg);
+ spivdbg(" MR:%08x SR:%08x IMR:%08x\n",
+ getreg32(SAM3U_SPI_MR), getreg32(SAM3U_SPI_SR),
+ getreg32(SAM3U_SPI_IMR));
+ spivdbg(" CSR0:%08x CSR1:%08x CSR2:%08x CSR3:%08x\n",
+ getreg32(SAM3U_SPI_CSR0), getreg32(SAM3U_SPI_CSR1),
+ getreg32(SAM3U_SPI_CSR2), getreg32(SAM3U_SPI_CSR3));
+ spivdbg(" WPCR:%08x WPSR:%08x\n",
+ getreg32(SAM3U_SPI_WPCR), getreg32(SAM3U_SPI_WPSR));
+}
+#endif
+
+/****************************************************************************
+ * Name: spi_flush
+ *
+ * Description:
+ * Make sure that there are now dangling SPI transfer in progress
+ *
+ * Input Parameters:
+ * priv - Device-specific state data
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static inline void spi_flush(void)
+{
+ /* Make sure the no TX activity is in progress... waiting if necessary */
+
+ while ((getreg32(SAM3U_SPI_SR) & SPI_INT_TXEMPTY) == 0);
+
+ /* Then make sure that there is no pending RX data .. reading as
+ * discarding as necessary.
+ */
+
+ while ((getreg32(SAM3U_SPI_SR) & SPI_INT_RDRF) != 0)
+ {
+ (void)getreg32(SAM3U_SPI_RDR);
+ }
+}
+
+/****************************************************************************
+ * 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:
+ * priv - Device-specific state data
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static inline uint32_t spi_cs2pcs(FAR struct sam3u_spidev_s *priv)
+{
+ return ((uint32_t)1 << (priv->cs)) - 1;
+}
+
+/****************************************************************************
+ * 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
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_OWNBUS
+static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
+{
+ FAR struct sam3u_spidev_s *priv = (FAR struct sam3u_spidev_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;
+}
+#endif
+
+/****************************************************************************
+ * 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(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected)
+ {
+ FAR struct sam3u_spidev_s *priv = (FAR struct sam3u_spidev_s *)dev;
+ uint32_t regval;
+
+ /* Are we selecting or de-selecting the device? */
+
+ spivdbg("selected=%d\n", selected);
+ if (selected)
+ {
+ /* At this point, we expect no chip selected */
+
+ DEBUGASSERT(priv->cs == 0xff);
+
+ /* Get the chip select number used with this SPI device */
+
+ priv->cs = sam3u_spicsnumber(devid);
+ spivdbg("cs=%d\n", priv->cs);
+ DEBUGASSERT(priv->cs >= 0 && priv->cs <= 3);
+
+ /* Before writing the TDR, the PCS field in the SPI_MR register must be set
+ * in order to select a slave.
+ */
+
+ regval = getreg32(SAM3U_SPI_MR);
+ regval &= ~SPI_MR_PCS_MASK;
+ regval |= (spi_cs2pcs(priv) << SPI_MR_PCS_SHIFT);
+ putreg32(regval, SAM3U_SPI_MR);
+ }
+ else
+ {
+ /* At this point, we expect the chip to have already been selected */
+
+#ifdef CONFIG_DEBUG
+ int cs = sam3u_spicsnumber(devid);
+ DEBUGASSERT(priv->cs == cs);
+#endif
+
+ /* Mark no chip selected */
+
+ priv->cs = 0xff;
+ }
+
+ /* 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.
+ * This sam3u_spiselect 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 normal
+ * GPIO 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 GPIO output pin does *not* have to be the
+ * same as the NPCS pin normal associated with the chip select number.
+ */
+
+ sam3u_spiselect(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(FAR struct spi_dev_s *dev, uint32_t frequency)
+{
+ FAR struct sam3u_spidev_s *priv = (FAR struct sam3u_spidev_s *)dev;
+ uint32_t actual;
+ uint32_t scbr;
+ uint32_t dlybs;
+ uint32_t dlybct;
+ uint32_t regval;
+ uint32_t regaddr;
+
+ spivdbg("cs=%d frequency=%d\n", priv->cs, frequency);
+ DEBUGASSERT(priv->cs >= 0 && priv->cs <= 3);
+
+ /* Check if the requested frequency is the same as the frequency selection */
+
+#ifndef CONFIG_SPI_OWNBUS
+ if (priv->csstate[priv->cs].frequency == frequency)
+ {
+ /* We are already at this frequency. Return the actual. */
+
+ return priv->csstate[priv->cs].actual;
+ }
+#endif
+
+ /* Configure SPI to a frequency as close as possible to the requested frequency.
+ *
+ * SPCK frequency = MCK / SCBR, or SCBR = MCK / frequency
+ */
+
+ scbr = SAM3U_MCK_FREQUENCY / frequency;
+
+ if (scbr < 8)
+ {
+ scbr = 8;
+ }
+ else if (scbr > 254)
+ {
+ scbr = 254;
+ }
+
+ scbr = (scbr + 1) & ~1;
+
+ /* Save the new scbr value */
+
+ regaddr = g_csraddr[priv->cs];
+ regval = getreg32(regaddr);
+ 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 / MCK
+ *
+ * For a 2uS delay
+ *
+ * DLYBS = MCK * 0.000002 = MCK / 500000
+ */
+
+ dlybs = SAM3U_MCK_FREQUENCY / 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) / MCK
+ *
+ * For a 5uS delay:
+ *
+ * DLYBCT = MCK * 0.000005 / 32 = MCK / 200000 / 32
+ */
+
+ dlybct = SAM3U_MCK_FREQUENCY / 200000 / 32;
+ regval |= dlybct << SPI_CSR_DLYBCT_SHIFT;
+ putreg32(regval, regaddr);
+
+ /* Calculate the new actual frequency */
+
+ actual = SAM3U_MCK_FREQUENCY / scbr;
+ spivdbg("csr[%08x]=%08x actual=%d\n", regaddr, regval, actual);
+
+ /* Save the frequency setting */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->csstate[priv->cs].frequency = frequency;
+ priv->csstate[priv->cs].actual = actual;
+#endif
+
+ 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 sam3u_spidev_s *priv = (FAR struct sam3u_spidev_s *)dev;
+ uint32_t regval;
+ uint32_t regaddr;
+
+ spivdbg("cs=%d mode=%d\n", priv->cs, mode);
+ DEBUGASSERT(priv->cs >= 0 && priv->cs <= 3);
+
+ /* Has the mode changed? */
+
+#ifndef CONFIG_SPI_OWNBUS
+ if (mode != priv->csstate[priv->cs].mode)
+ {
+#endif
+ /* Yes... Set the mode appropriately */
+
+ regaddr = g_csraddr[priv->cs];
+ regval = getreg32(regaddr);
+ regval &= ~(SPI_CSR_CPOL|SPI_CSR_NCPHA);
+
+ switch (mode)
+ {
+ case SPIDEV_MODE0: /* CPOL=0; NCPHA=0 */
+ break;
+
+ case SPIDEV_MODE1: /* CPOL=0; NCPHA=1 */
+ regval |= SPI_CSR_NCPHA;
+ break;
+
+ case SPIDEV_MODE2: /* CPOL=1; NCPHA=0 */
+ regval |= SPI_CSR_CPOL;
+ break;
+
+ case SPIDEV_MODE3: /* CPOL=1; NCPHA=1 */
+ regval |= (SPI_CSR_CPOL|SPI_CSR_NCPHA);
+ break;
+
+ default:
+ DEBUGASSERT(FALSE);
+ return;
+ }
+
+ putreg32(regval, regaddr);
+ spivdbg("csr[%08x]=%08x\n", regaddr, regval);
+
+ /* Save the mode so that subsequent re-configurations will be faster */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->csstate[priv->cs].mode = mode;
+ }
+#endif
+}
+
+/****************************************************************************
+ * 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 sam3u_spidev_s *priv = (FAR struct sam3u_spidev_s *)dev;
+ uint32_t regaddr;
+ uint32_t regval;
+
+ spivdbg("cs=%d nbits=%d\n", priv->cs, nbits);
+ DEBUGASSERT(priv && nbits > 7 && nbits < 17);
+ DEBUGASSERT(priv->cs >= 0 && priv->cs <= 3);
+
+ /* 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? */
+
+#ifndef CONFIG_SPI_OWNBUS
+ if (nbits != priv->csstate[priv->cs].nbits)
+ {
+#endif
+ /* Yes... Set number of bits appropriately */
+
+ regaddr = g_csraddr[priv->cs];
+ regval = getreg32(regaddr);
+ regval &= ~SPI_CSR_BITS_MASK;
+ regval |= SPI_CSR_BITS(nbits);
+ putreg32(regval, regaddr);
+
+ spivdbg("csr[%08x]=%08x\n", regaddr, regval);
+
+ /* Save the selection so the subsequence re-configurations will be faster */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->csstate[priv->cs].nbits = nbits;
+ }
+#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(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;
+ spi_exchange(dev, &txbyte, &rxbyte, 1);
+
+ spivdbg("Sent %02x received %02x\n", txbyte, rxbyte);
+ return (uint16_t)rxbyte;
+}
+
+/****************************************************************************
+ * Name: spi_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 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 sam3u_spidev_s *priv = (FAR struct sam3u_spidev_s *)dev;
+ FAR uint8_t *rxptr = (FAR uint8_t*)rxbuffer;
+ FAR uint8_t *txptr = (FAR 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(priv) << SPI_TDR_PCS_SHIFT;
+
+ /* Make sure that any previous transfer is flushed from the hardware */
+
+ spi_flush();
+
+ /* 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 (rxptr)
+ {
+ 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 ((getreg32(SAM3U_SPI_SR) & SPI_INT_TDRE) == 0);
+
+ /* Write the data to transmitted to the Transmit Data Register (TDR) */
+
+ putreg32(data, SAM3U_SPI_TDR);
+
+ /* Wait for the read data to be available in the RDR */
+
+ while ((getreg32(SAM3U_SPI_SR) & SPI_INT_RDRF) == 0);
+
+ /* Read the received data from the SPI Data Register */
+
+ data = getreg32(SAM3U_SPI_RDR);
+ 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 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: up_spiinitialize
+ *
+ * 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 *up_spiinitialize(int port)
+{
+ FAR struct sam3u_spidev_s *priv = &g_spidev;
+ irqstate_t flags;
+ uint32_t regval;
+
+ /* The SAM3U has only a single SPI port */
+
+ spivdbg("port=%d\n", port);
+ DEBUGASSERT(port == 0);
+
+ /* Set up the initial state */
+
+ priv->cs = 0xff;
+
+ /* Apply power to the SPI block */
+
+ flags = irqsave();
+ regval = getreg32(SAM3U_PMC_PCER);
+ regval |= (1 << SAM3U_PID_SPI);
+#ifdef CONFIG_SAM3U_SPIINTERRUPT
+ regval |= (1 << SAM3U_IRQ_SPI);
+#endif
+ putreg32(regval, SAM3U_PMC_PCER);
+
+ /* Configure multiplexed pins as connected on the board. Chip select pins
+ * must be configured by board-specific logic.
+ */
+
+ sam3u_configgpio(GPIO_SPI0_MISO);
+ sam3u_configgpio(GPIO_SPI0_MOSI);
+ sam3u_configgpio(GPIO_SPI0_SPCK);
+
+ /* Disable SPI clocking */
+
+ putreg32(SPI_CR_SPIDIS, SAM3U_SPI_CR);
+
+ /* Execute a software reset of the SPI (twice) */
+
+ putreg32(SPI_CR_SWRST, SAM3U_SPI_CR);
+ putreg32(SPI_CR_SWRST, SAM3U_SPI_CR);
+ irqrestore(flags);
+
+ /* Configure the SPI mode register */
+
+ putreg32(SPI_MR_MSTR | SPI_MR_MODFDIS, SAM3U_SPI_MR);
+
+ /* And enable the SPI */
+
+ putreg32(SPI_CR_SPIEN, SAM3U_SPI_CR);
+ up_mdelay(20);
+
+ /* Flush any pending transfers */
+
+ (void)getreg32(SAM3U_SPI_SR);
+ (void)getreg32(SAM3U_SPI_RDR);
+
+ /* Initialize the SPI semaphore that enforces mutually exclusive access */
+
+#ifndef CONFIG_SPI_OWNBUS
+ sem_init(&priv->exclsem, 0, 1);
+#endif
+ spi_dumpregs("After initialization");
+ return &priv->spidev;
+}
+#endif /* CONFIG_SAM3U_SPI */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_spi.h b/nuttx/arch/arm/src/sam3u/sam3u_spi.h
new file mode 100644
index 000000000..bce613575
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_spi.h
@@ -0,0 +1,189 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_spi.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_SPI_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_SPI_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* SPI register offsets *****************************************************************/
+
+#define SAM3U_SPI_CR_OFFSET 0x00 /* Control Register */
+#define SAM3U_SPI_MR_OFFSET 0x04 /* Mode Register */
+#define SAM3U_SPI_RDR_OFFSET 0x08 /* Receive Data Register */
+#define SAM3U_SPI_TDR_OFFSET 0x0c /* Transmit Data Register */
+#define SAM3U_SPI_SR_OFFSET 0x10 /* Status Register */
+#define SAM3U_SPI_IER_OFFSET 0x14 /* Interrupt Enable Register */
+#define SAM3U_SPI_IDR_OFFSET 0x18 /* Interrupt Disable Register */
+#define SAM3U_SPI_IMR_OFFSET 0x1c /* Interrupt Mask Register */
+ /* 0x20-0x2c: Reserved */
+#define SAM3U_SPI_CSR0_OFFSET 0x30 /* Chip Select Register 0 */
+#define SAM3U_SPI_CSR1_OFFSET 0x34 /* Chip Select Register 1 */
+#define SAM3U_SPI_CSR2_OFFSET 0x38 /* Chip Select Register 2 */
+#define SAM3U_SPI_CSR3_OFFSET 0x3c /* Chip Select Register 3 */
+ /* 0x40-0xe0: Reserved */
+#define SAM3U_SPI_WPCR_OFFSET 0xe4 /* Write Protection Control Register */
+#define SAM3U_SPI_WPSR_OFFSET 0xe8 /* Write Protection Status Register */
+ /* 0xec-0xf8: Reserved*/
+
+/* SPI register adresses ****************************************************************/
+
+#define SAM3U_SPI_CR (SAM3U_SPI_BASE+SAM3U_SPI_CR_OFFSET) /* Control Register */
+#define SAM3U_SPI_MR (SAM3U_SPI_BASE+SAM3U_SPI_MR_OFFSET) /* Mode Register */
+#define SAM3U_SPI_RDR (SAM3U_SPI_BASE+SAM3U_SPI_RDR_OFFSET) /* Receive Data Register */
+#define SAM3U_SPI_TDR (SAM3U_SPI_BASE+SAM3U_SPI_TDR_OFFSET) /* Transmit Data Register */
+#define SAM3U_SPI_SR (SAM3U_SPI_BASE+SAM3U_SPI_SR_OFFSET) /* Status Register */
+#define SAM3U_SPI_IER (SAM3U_SPI_BASE+SAM3U_SPI_IER_OFFSET) /* Interrupt Enable Register */
+#define SAM3U_SPI_IDR (SAM3U_SPI_BASE+SAM3U_SPI_IDR_OFFSET) /* Interrupt Disable Register */
+#define SAM3U_SPI_IMR (SAM3U_SPI_BASE+SAM3U_SPI_IMR_OFFSET) /* Interrupt Mask Register */
+#define SAM3U_SPI_CSR0 (SAM3U_SPI_BASE+SAM3U_SPI_CSR0_OFFSET) /* Chip Select Register 0 */
+#define SAM3U_SPI_CSR1 (SAM3U_SPI_BASE+SAM3U_SPI_CSR1_OFFSET) /* Chip Select Register 1 */
+#define SAM3U_SPI_CSR2 (SAM3U_SPI_BASE+SAM3U_SPI_CSR2_OFFSET) /* Chip Select Register 2 */
+#define SAM3U_SPI_CSR3 (SAM3U_SPI_BASE+SAM3U_SPI_CSR3_OFFSET) /* Chip Select Register 3 */
+#define SAM3U_SPI_WPCR (SAM3U_SPI_BASE+SAM3U_SPI_WPCR_OFFSET) /* Write Protection Control Register */
+#define SAM3U_SPI_WPSR (SAM3U_SPI_BASE+SAM3U_SPI_WPSR_OFFSET) /* Write Protection Status Register */
+
+/* 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_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)
+
+/* 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_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_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)
+
+/* SPI Write Protection Control Register */
+
+#define SPI_WPCR_SPIWPEN (1 << 0) /* Bit 0: SPI Write Protection Enable */
+#define SPI_WPCR_SPIWPKEY_SHIFT (8) /* Bits 8-31: SPI Write Protection Key Password */
+#define SPI_WPCR_SPIWPKEY_MASK (0x00ffffff << SPI_WPCR_SPIWPKEY_SHIFT)
+
+/* SPI Write Protection Status Register */
+
+#define SPI_WPSR_SPIWPVS_SHIFT (0) /* Bits 0-2: SPI Write Protection Violation Status */
+#define SPI_WPSR_SPIWPVS_MASK (7 << SPI_WPSR_SPIWPVS_SHIFT)
+#define SPI_WPSR_SPIWPVSRC_SHIFT (8) /* Bits 8-15: SPI Write Protection Violation Source */
+#define SPI_WPSR_SPIWPVSRC_MASK (0xff << SPI_WPSR_SPIWPVSRC_SHIFT)
+
+/****************************************************************************************
+ * Public Types
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Data
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Functions
+ ****************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_SAM3U_SAM3U_SPI_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_ssc.h b/nuttx/arch/arm/src/sam3u/sam3u_ssc.h
new file mode 100644
index 000000000..5a5df824b
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_ssc.h
@@ -0,0 +1,292 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_ssc.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_SSC_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_SSC_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* SSC register offsets *****************************************************************/
+
+#define SAM3U_SSC_CR_OFFSET 0x000 /* Control Register */
+#define SAM3U_SSC_CMR_OFFSET 0x004 /* Clock Mode Register */
+ /* 0x008: Reserved */
+ /* 0x00c: Reserved */
+#define SAM3U_SSC_RCMR_OFFSET 0x010 /* Receive Clock Mode Register */
+#define SAM3U_SSC_RFMR_OFFSET 0x014 /* Receive Frame Mode Register */
+#define SAM3U_SSC_TCMR_OFFSET 0x018 /* Transmit Clock Mode Register */
+#define SAM3U_SSC_TFMR_OFFSET 0x01c /* Transmit Frame Mode Register */
+#define SAM3U_SSC_RHR_OFFSET 0x020 /* Receive Holding Register */
+#define SAM3U_SSC_THR_OFFSET 0x024 /* Transmit Holding Register */
+ /* 0x028: Reserved */
+ /* 0x02c: Reserved */
+#define SAM3U_SSC_RSHR_OFFSET 0x030 /* Receive Sync. Holding Register */
+#define SAM3U_SSC_TSHR_OFFSET 0x034 /* Transmit Sync. Holding Register */
+#define SAM3U_SSC_RC0R_OFFSET 0x038 /* Receive Compare 0 Register */
+#define SAM3U_SSC_RC1R_OFFSET 0x03c /* Receive Compare 1 Register */
+#define SAM3U_SSC_SR_OFFSET 0x040 /* Status Register */
+#define SAM3U_SSC_IER_OFFSET 0x044 /* Interrupt Enable Register */
+#define SAM3U_SSC_IDR_OFFSET 0x048 /* Interrupt Disable Register */
+#define SAM3U_SSC_IMR_OFFSET 0x04c /* Interrupt Mask Register */
+#define SAM3U_SSC_WPMR_OFFSET 0x0e4 /* Write Protect Mode Register */
+#define SAM3U_SSC_WPSR_OFFSET 0x0e8 /* Write Protect Status Register */
+ /* 0x050-0x0fc: Reserved */
+ /* 0x100-0x124: Reserved */
+
+/* SSC register adresses ****************************************************************/
+
+#define SAM3U_SSC_CR (SAM3U_SSC_BASE+SAM3U_SSC_CR_OFFSET)
+#define SAM3U_SSC_CMR (SAM3U_SSC_BASE+SAM3U_SSC_CMR_OFFSET)
+#define SAM3U_SSC_RCMR (SAM3U_SSC_BASE+SAM3U_SSC_RCMR_OFFSET)
+#define SAM3U_SSC_RFMR (SAM3U_SSC_BASE+SAM3U_SSC_RFMR_OFFSET)
+#define SAM3U_SSC_TCMR (SAM3U_SSC_BASE+SAM3U_SSC_TCMR_OFFSET)
+#define SAM3U_SSC_TFMR (SAM3U_SSC_BASE+SAM3U_SSC_TFMR_OFFSET)
+#define SAM3U_SSC_RHR (SAM3U_SSC_BASE+SAM3U_SSC_RHR_OFFSET)
+#define SAM3U_SSC_THR (SAM3U_SSC_BASE+SAM3U_SSC_THR_OFFSET)
+#define SAM3U_SSC_RSHR (SAM3U_SSC_BASE+SAM3U_SSC_RSHR_OFFSET)
+#define SAM3U_SSC_TSHR (SAM3U_SSC_BASE+SAM3U_SSC_TSHR_OFFSET)
+#define SAM3U_SSC_RC0R (SAM3U_SSC_BASE+SAM3U_SSC_RC0R_OFFSET)
+#define SAM3U_SSC_RC1R (SAM3U_SSC_BASE+SAM3U_SSC_RC1R_OFFSET)
+#define SAM3U_SSC_SR (SAM3U_SSC_BASE+SAM3U_SSC_SR_OFFSET)
+#define SAM3U_SSC_IER (SAM3U_SSC_BASE+SAM3U_SSC_IER_OFFSET)
+#define SAM3U_SSC_IDR (SAM3U_SSC_BASE+SAM3U_SSC_IDR_OFFSET)
+#define SAM3U_SSC_IMR (SAM3U_SSC_BASE+SAM3U_SSC_IMR_OFFSET)
+#define SAM3U_SSC_WPMR (SAM3U_SSC_BASE+SAM3U_SSC_WPMR_OFFSET)
+#define SAM3U_SSC_WPSR (SAM3U_SSC_BASE+SAM3U_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 (15) /* 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_POW (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_TK (1 << SSC_TCMR_CKS_SHIFT) /* TK Clock signal */
+# define SSC_TCMR_CKS_RK (2 << SSC_TCMR_CKS_SHIFT) /* RK 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_POW (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 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)
+
+/* 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_SAM3U_SAM3U_SSC_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_start.c b/nuttx/arch/arm/src/sam3u/sam3u_start.c
new file mode 100644
index 000000000..aceda2c46
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_start.c
@@ -0,0 +1,161 @@
+/****************************************************************************
+ * arch/arm/src/sam3u/sam3u_start.c
+ * arch/arm/src/chip/sam3u_start.c
+ *
+ * Copyright (C) 2009-2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/init.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "sam3u_internal.h"
+
+/****************************************************************************
+ * Private 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)
+{
+ const uint32_t *src;
+ uint32_t *dest;
+
+ /* Configure the uart so that we can get debug output as soon as possible */
+
+ sam3u_clockconfig();
+ sam3u_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 intialized 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
+ * segements.
+ */
+
+#ifdef CONFIG_NUTTX_KERNEL
+ sam3u_userspace();
+#endif
+
+ /* Initialize onboard resources */
+
+ sam3u_boardinitialize();
+ showprogress('E');
+
+ /* Then start NuttX */
+
+ showprogress('\r');
+ showprogress('\n');
+ os_start();
+
+ /* Shouldn't get here */
+
+ for(;;);
+}
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_supc.h b/nuttx/arch/arm/src/sam3u/sam3u_supc.h
new file mode 100644
index 000000000..5bd28de50
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_supc.h
@@ -0,0 +1,164 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_supc.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_SUPC_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_SUPC_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* SUPC register offsets ****************************************************************/
+
+#define SAM3U_SUPC_CR_OFFSET 0x00 /* Supply Controller Control Register */
+#define SAM3U_SUPC_SMMR_OFFSET 0x04 /* Supply Controller Supply Monitor Mode Register */
+#define SAM3U_SUPC_MR_OFFSET 0x08 /* Supply Controller Mode Register */
+#define SAM3U_SUPC_WUMR_OFFSET 0x0c /* Supply Controller Wake Up Mode Register */
+#define SAM3U_SUPC_WUIR_OFFSET 0x10 /* Supply Controller Wake Up Inputs Register */
+#define SAM3U_SUPC_SR_OFFSET 0x14 /* Supply Controller Status Register */
+
+/* SUPC register adresses ***************************************************************/
+
+#define SAM3U_SUPC_CR (SAM3U_SUPC_BASE+SAM3U_SUPC_CR_OFFSET)
+#define SAM3U_SUPC_SMMR (SAM3U_SUPC_BASE+SAM3U_SUPC_SMMR_OFFSET)
+#define SAM3U_SUPC_MR (SAM3U_SUPC_BASE+SAM3U_SUPC_MR_OFFSET)
+#define SAM3U_SUPC_WUMR (SAM3U_SUPC_BASE+SAM3U_SUPC_WUMR_OFFSET)
+#define SAM3U_SUPC_WUIR (SAM3U_SUPC_BASE+SAM3U_SUPC_WUIR_OFFSET)
+#define SAM3U_SUPC_SR (SAM3U_SUPC_BASE+SAM3U_SUPC_SR_OFFSET)
+
+/* SUPC register bit definitions ********************************************************/
+
+#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 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_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 */
+#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 */
+
+#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_VDDIORDY (1 << 14) /* Bit 14: VDDIO Ready */
+#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_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 */
+
+#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)
+
+#define SUPC_SR_FWUPS (1 << 0) /* Bit 0: FWUP Wake Up Status */
+#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_FWUPIS (1 << 12) /* Bit 12: FWUP Input 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_SAM3U_SAM3U_SUPC_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_tc.h b/nuttx/arch/arm/src/sam3u/sam3u_tc.h
new file mode 100644
index 000000000..0fb36da97
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_tc.h
@@ -0,0 +1,347 @@
+/************************************************************************************************
+ * arch/arm/src/sam3u/sam3u_tc.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_TC_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_TC_H
+
+/************************************************************************************************
+ * Included Files
+ ************************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/************************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************************/
+
+/* TC register offsets **************************************************************************/
+
+/* Timer channel offsets (with respect to timer base offset 0f 0x00, 0x40, or 0x80 */
+
+#define SAM3U_TCN_OFFSET(n) (0x00 + ((n)<<6)) /* 0x00, 0x40, 0x80 */
+#define SAM3U_TCN_CCR_OFFSET 0x00 /* Channel Control Register */
+#define SAM3U_TCN_CMR_OFFSET 0x04 /* Channel Mode Register */
+ /* 0x08 Reserved */
+ /* 0x0c Reserved */
+#define SAM3U_TCN_CV_OFFSET 0x10 /* Counter Value */
+#define SAM3U_TCN_RA_OFFSET 0x14 /* Register A */
+#define SAM3U_TCN_RB_OFFSET 0x18 /* Register B */
+#define SAM3U_TCN_RC_OFFSET 0x1c /* Register C */
+#define SAM3U_TCN_SR_OFFSET 0x20 /* Status Register */
+#define SAM3U_TCN_IER_OFFSET 0x24 /* Interrupt Enable Register */
+#define SAM3U_TCN_IDR_OFFSET 0x28 /* Interrupt Disable Register */
+#define SAM3U_TCN_IMR_OFFSET 0x2c /* Interrupt Mask Register */
+
+/* Timer common registers */
+
+#define SAM3U_TC_BCR_OFFSET 0xc0 /* Block Control Register */
+#define SAM3U_TC_BMR_OFFSET 0xc4 /* Block Mode Register */
+#define SAM3U_TC_QIER_OFFSET 0xc8 /* QDEC Interrupt Enable Register */
+#define SAM3U_TC_QIDR_OFFSET 0xcc /* QDEC Interrupt Disable Register */
+#define SAM3U_TC_QIMR_OFFSET 0xd0 /* QDEC Interrupt Mask Register */
+#define SAM3U_TC_QISR_OFFSET 0xd4 /* QDEC Interrupt Status Register */
+ /* 0xd8 Reserved */
+ /* 0xe4 Reserved */
+
+/* TC register adresses *************************************************************************/
+
+/* Timer channel offsets (with respect to timer base offset 0f 0x00, 0x40, or 0x80 */
+
+#define SAM3U_TC_CCR(n) (SAM3U_TCN_BASE(n)+SAM3U_TCN_CCR_OFFSET)
+#define SAM3U_TC_CMR(n) (SAM3U_TCN_BASE(n)+SAM3U_TCN_CMR_OFFSET)
+#define SAM3U_TC_CV(n) (SAM3U_TCN_BASE(n)+SAM3U_TCN_CV_OFFSET)
+#define SAM3U_TC_RA(n) (SAM3U_TCN_BASE(n)+SAM3U_TCN_RA_OFFSET)
+#define SAM3U_TC_RB(n) (SAM3U_TCN_BASE(n)+SAM3U_TCN_RB_OFFSET)
+#define SAM3U_TC_RC(n) (SAM3U_TCN_BASE(n)+SAM3U_TCN_RC_OFFSET)
+#define SAM3U_TC_SR(n) (SAM3U_TCN_BASE(n)+SAM3U_TCN_SR_OFFSET)
+#define SAM3U_TC_IER(n) (SAM3U_TCN_BASE(n)+SAM3U_TCN_IER_OFFSET)
+#define SAM3U_TC_IDR(n) (SAM3U_TCN_BASE(n)+SAM3U_TCN_IDR_OFFSET)
+#define SAM3U_TC_IMR(n) (SAM3U_TCN_BASE(n)+SAM3U_TCN_IMR_OFFSET)
+
+#define SAM3U_TC0_CCR (SAM3U_TC0_BASE+SAM3U_TCN_CCR_OFFSET)
+#define SAM3U_TC0_CMR (SAM3U_TC0_BASE+SAM3U_TCN_CMR_OFFSET)
+#define SAM3U_TC0_CV (SAM3U_TC0_BASE+SAM3U_TCN_CV_OFFSET)
+#define SAM3U_TC0_RA (SAM3U_TC0_BASE+SAM3U_TCN_RA_OFFSET)
+#define SAM3U_TC0_RB (SAM3U_TC0_BASE+SAM3U_TCN_RB_OFFSET)
+#define SAM3U_TC0_RC (SAM3U_TC0_BASE+SAM3U_TCN_RC_OFFSET)
+#define SAM3U_TC0_SR (SAM3U_TC0_BASE+SAM3U_TCN_SR_OFFSET)
+#define SAM3U_TC0_IER (SAM3U_TC0_BASE+SAM3U_TCN_IER_OFFSET)
+#define SAM3U_TC0_IDR (SAM3U_TC0_BASE+SAM3U_TCN_IDR_OFFSET)
+#define SAM3U_TC0_IMR (SAM3U_TC0_BASE+SAM3U_TCN_IMR_OFFSET)
+
+#define SAM3U_TC1_CCR (SAM3U_TC1_BASE+SAM3U_TCN_CCR_OFFSET)
+#define SAM3U_TC1_CMR (SAM3U_TC1_BASE+SAM3U_TCN_CMR_OFFSET)
+#define SAM3U_TC1_CV (SAM3U_TC1_BASE+SAM3U_TCN_CV_OFFSET)
+#define SAM3U_TC1_RA (SAM3U_TC1_BASE+SAM3U_TCN_RA_OFFSET)
+#define SAM3U_TC1_RB (SAM3U_TC1_BASE+SAM3U_TCN_RB_OFFSET)
+#define SAM3U_TC1_RC (SAM3U_TC1_BASE+SAM3U_TCN_RC_OFFSET)
+#define SAM3U_TC1_SR (SAM3U_TC1_BASE+SAM3U_TCN_SR_OFFSET)
+#define SAM3U_TC1_IER (SAM3U_TC1_BASE+SAM3U_TCN_IER_OFFSET)
+#define SAM3U_TC1_IDR (SAM3U_TC1_BASE+SAM3U_TCN_IDR_OFFSET)
+#define SAM3U_TC1_IMR (SAM3U_TC1_BASE+SAM3U_TCN_IMR_OFFSET)
+
+#define SAM3U_TC2_CCR (SAM3U_TC2_BASE+SAM3U_TCN_CCR_OFFSET)
+#define SAM3U_TC2_CMR (SAM3U_TC2_BASE+SAM3U_TCN_CMR_OFFSET)
+#define SAM3U_TC2_CV (SAM3U_TC2_BASE+SAM3U_TCN_CV_OFFSET)
+#define SAM3U_TC2_RA (SAM3U_TC2_BASE+SAM3U_TCN_RA_OFFSET)
+#define SAM3U_TC2_RB (SAM3U_TC2_BASE+SAM3U_TCN_RB_OFFSET)
+#define SAM3U_TC2_RC (SAM3U_TC2_BASE+SAM3U_TCN_RC_OFFSET)
+#define SAM3U_TC2_SR (SAM3U_TC2_BASE+SAM3U_TCN_SR_OFFSET)
+#define SAM3U_TC2_IER (SAM3U_TC2_BASE+SAM3U_TCN_IER_OFFSET)
+#define SAM3U_TC2_IDR (SAM3U_TC2_BASE+SAM3U_TCN_IDR_OFFSET)
+#define SAM3U_TC2_IMR (SAM3U_TC2_BASE+SAM3U_TCN_IMR_OFFSET)
+
+/* Timer common registers */
+
+#define SAM3U_TC_BCR (SAM3U_TC_BASE+SAM3U_TC_BCR_OFFSET)
+#define SAM3U_TC_BMR (SAM3U_TC_BASE+SAM3U_TC_BMR_OFFSET)
+#define SAM3U_TC_QIER (SAM3U_TC_BASE+SAM3U_TC_QIER_OFFSET)
+#define SAM3U_TC_QIDR (SAM3U_TC_BASE+SAM3U_TC_QIDR_OFFSET)
+#define SAM3U_TC_QIMR (SAM3U_TC_BASE+SAM3U_TC_QIMR_OFFSET)
+#define SAM3U_TC_QISR (SAM3U_TC_BASE+SAM3U_TC_QISR_OFFSET)
+
+/* TC register bit definitions ******************************************************************/
+
+/* 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)
+# 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)
+#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_SWAP (1 << 15) /* Bit 15: Swap PHA and PHB */
+#define TC_BMR_INVIDX (1 << 16) /* Bit 16: Inverted Index */
+#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)
+
+/* 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) */
+
+/* Timer Channel Registers */
+/* TC Channel Control Register */
+
+#define TCN_CCR_CLKEN (1 << 0) /* Bit 0: Counter Clock Enable Command */
+#define TCN_CCR_CLKDIS (1 << 1) /* Bit 1: Counter Clock Disable Command */
+#define TCN_CCR_SWTRG (1 << 2) /* Bit 2: Software Trigger Command */
+
+/* TC Channel Mode Register */
+
+#define TCN_CMR_TCCLKS_SHIFT (0) /* Bits 0-2: Clock Selection (Common) */
+#define TCN_CMR_TCCLKS_MASK (7 << TCN_CMR_TCCLKS_SHIFT)
+# define TCN_CMR_TCCLKS_TIMERCLOCK1 (0 << TCN_CMR_TCCLKS_SHIFT)
+# define TCN_CMR_TCCLKS_TIMERCLOCK2 (1 << TCN_CMR_TCCLKS_SHIFT)
+# define TCN_CMR_TCCLKS_TIMERCLOCK3 (2 << TCN_CMR_TCCLKS_SHIFT)
+# define TCN_CMR_TCCLKS_TIMERCLOCK4 (3 << TCN_CMR_TCCLKS_SHIFT)
+# define TCN_CMR_TCCLKS_TIMERCLOCK5 (4 << TCN_CMR_TCCLKS_SHIFT)
+# define TCN_CMR_TCCLKS_XC0 (5 << TCN_CMR_TCCLKS_SHIFT)
+# define TCN_CMR_TCCLKS_XC1 (6 << TCN_CMR_TCCLKS_SHIFT)
+# define TCN_CMR_TCCLKS_XC2 (7 << TCN_CMR_TCCLKS_SHIFT)
+#define TCN_CMR_CLKI (1 << 3) /* Bit 3: Clock Invert (Common) */
+#define TCN_CMR_BURST_SHIFT (4) /* Bits 4-5: Burst Signal Selection (Common) */
+#define TCN_CMR_BURST_MASK (3 << TCN_CMR_BURST_MASK)
+#define TCN_CMR_BURST_MASK (3 << TCN_CMR_BURST_MASK)
+# define TCN_CMR_BURST_NOTGATED (0 << TCN_CMR_BURST_MASK) /* Nott gated by external signal */
+# define TCN_CMR_BURST_XC0 (1 << TCN_CMR_BURST_MASK) /* XC0 ANDed with selected clock */
+# define TCN_CMR_BURST_XC1 (2 << TCN_CMR_BURST_MASK) /* XC1 ANDed with selected clock */
+# define TCN_CMR_BURST_XC2 (3 << TCN_CMR_BURST_MASK) /* XC2 ANDed with selected clock */
+#define TCN_CMR_WAVE (1 << 15) /* Bit 15: (Common) */
+
+#define TCN_CMR_LDBSTOP (1 << 6) /* Bit 6: Counter stopped with RB Loading (Capture mode) */
+#define TCN_CMR_LDBDIS (1 << 7) /* Bit 7: Counter disable with RB Loading (Capture mode) */
+#define TCN_CMR_ETRGEDG_SHIFT (8) /* Bits 8-9: External Trigger Edge Selection (Capture mode) */
+#define TCN_CMR_ETRGEDG_MASK (3 << TCN_CMR_ETRGEDG_SHIFT)
+# define TCN_CMR_ETRGEDG_NONE (0 << TCN_CMR_ETRGEDG_SHIFT) /* None */
+# define TCN_CMR_ETRGEDG_REDGE (1 << TCN_CMR_ETRGEDG_SHIFT) /* Rising edge */
+# define TCN_CMR_ETRGEDG_FEDGE (2 << TCN_CMR_ETRGEDG_SHIFT) /* Falling edge */
+# define TCN_CMR_ETRGEDG_EACH (3 << TCN_CMR_ETRGEDG_SHIFT) /* Each */
+#define TCN_CMR_ABETRG (1 << 10) /* Bit 10: TIOA or TIOB External Trigger Selection (Capture mode) */
+#define TCN_CMR_CPCTRG (1 << 14) /* Bit 14: RC Compare Trigger Enable (Capture mode) */
+#define TCN_CMR_LDRA_SHIFT (16) /* Bits 16-17: RA Loading Selection (Capture mode) */
+#define TCN_CMR_LDRA_MASK (3 << TCN_CMR_LDRA_SHIFT)
+# define TCN_CMR_LDRA_NONE (0 << TCN_CMR_LDRA_SHIFT) /* None */
+# define TCN_CMR_LDRA_REDGE (1 << TCN_CMR_LDRA_SHIFT) /* Rising edge of TIOA */
+# define TCN_CMR_LDRA_FEDGE (2 << TCN_CMR_LDRA_SHIFT) /* Falling edge of TIOA */
+# define TCN_CMR_LDRA_EACH (3 << TCN_CMR_LDRA_SHIFT) /* Each edge of TIOA */
+#define TCN_CMR_LDRB_SHIFT (18) /* Bits 18-19: RB Loading Selection (Capture mode) */
+#define TCN_CMR_LDRB_MASK (3 << TCN_CMR_LDRB_SHIFT)
+# define TCN_CMR_LDRB_NONE (0 << TCN_CMR_LDRB_SHIFT) /* None */
+# define TCN_CMR_LDRB_REDGE (1 << TCN_CMR_LDRB_SHIFT) /* Rising edge of TIOB */
+# define TCN_CMR_LDRB_FEDGE (2 << TCN_CMR_LDRB_SHIFT) /* Falling edge of TIOB */
+# define TCN_CMR_LDRB_EACH (3 << TCN_CMR_LDRB_SHIFT) /* Each edge of TIOB */
+
+#define TCN_CMR_CPCSTOP (1 << 6) /* Bit 6: Counter Clock Stopped with RC Compare (Waveform mode) */
+#define TCN_CMR_CPCDIS (1 << 7) /* Bit 7: Counter Clock Disable with RC Compare (Waveform mode) */
+#define TCN_CMR_EEVTEDG_SHIFT (8) /* Bits 8-9: External Event Edge Selection (Waveform mode) */
+#define TCN_CMR_EEVTEDG_MASK (3 << TCN_CMR_EEVTEDG_SHIFT)
+# define TCN_CMR_EEVTEDG_NONE (0 << TCN_CMR_EEVTEDG_SHIFT) /* None */
+# define TCN_CMR_EEVTEDG_REDGE (1 << TCN_CMR_EEVTEDG_SHIFT) /* Rising edge */
+# define TCN_CMR_EEVTEDG_FEDGE (2 << TCN_CMR_EEVTEDG_SHIFT) /* Falling edge */
+# define TCN_CMR_EEVTEDG_EACH (3 << TCN_CMR_EEVTEDG_SHIFT) /* Each edge */
+#define TCN_CMR_EEVT_SHIFT (10) /* Bits 10-11: External Event Selection (Waveform mode) */
+#define TCN_CMR_EEVT_MASK (3 << TCN_CMR_EEVT_SHIFT)
+# define TCN_CMR_EEVT_TIOB (0 << TCN_CMR_EEVT_SHIFT) /* TIOB input */
+# define TCN_CMR_EEVT_XC0 (1 << TCN_CMR_EEVT_SHIFT) /* XC0 output */
+# define TCN_CMR_EEVT_XC1 (2 << TCN_CMR_EEVT_SHIFT) /* XC1 output */
+# define TCN_CMR_EEVT_XC2 (3 << TCN_CMR_EEVT_SHIFT) /* XC2 output */
+#define TCN_CMR_ENETRG (1 << 12) /* Bit 12: External Event Trigger Enable (Waveform mode) */
+#define TCN_CMR_WAVSEL_SHIFT (13) /* Bits 13-14: Waveform Selection (Waveform mode) */
+#define TCN_CMR_WAVSEL_MASK (3 << TCN_CMR_WAVSEL_SHIFT)
+# define TCN_CMR_WAVSEL_UP (0 << TCN_CMR_WAVSEL_SHIFT) /* UP mode w/o auto trigger (Waveform mode) */
+# define TCN_CMR_WAVSEL_UPAUTO (1 << TCN_CMR_WAVSEL_SHIFT) /* UP mode with auto trigger (Waveform mode) */
+# define TCN_CMR_WAVSEL_UPDWN (2 << TCN_CMR_WAVSEL_SHIFT) /* UPDOWN mode w/o auto trigger (Waveform mode) */
+# define TCN_CMR_WAVSEL_UPDWNAUTO (3 << TCN_CMR_WAVSEL_SHIFT) /* UPDOWN mode with auto trigger (Waveform mode) */
+#define TCN_CMR_ACPA_SHIFT (16) /* Bits 16-17: RA Compare Effect on TIOA (Waveform mode) */
+#define TCN_CMR_ACPA_MASK (3 << TCN_CMR_ACPA_SHIFT)
+# define TCN_CMR_ACPA_NONE (0 << TCN_CMR_ACPA_SHIFT)
+# define TCN_CMR_ACPA_SET (1 << TCN_CMR_ACPA_SHIFT)
+# define TCN_CMR_ACPA_CLEAR (2 << TCN_CMR_ACPA_SHIFT)
+# define TCN_CMR_ACPA_TOGGLE (3 << TCN_CMR_ACPA_SHIFT)
+#define TCN_CMR_ACPC_SHIFT (18) /* Bits 18-19: RC Compare Effect on TIOA (Waveform mode) */
+#define TCN_CMR_ACPC_MASK (3 << TCN_CMR_ACPC_SHIFT)
+# define TCN_CMR_ACPC_NONE (0 << TCN_CMR_ACPC_SHIFT)
+# define TCN_CMR_ACPC_SET (1 << TCN_CMR_ACPC_SHIFT)
+# define TCN_CMR_ACPC_CLEAR (2 << TCN_CMR_ACPC_SHIFT)
+# define TCN_CMR_ACPC_TOGGLE (3 << TCN_CMR_ACPC_SHIFT)
+#define TCN_CMR_AEEVT_SHIFT (20) /* Bits 20-21: External Event Effect on TIOA (Waveform mode) */
+#define TCN_CMR_AEEVT_MASK (3 << TCN_CMR_AEEVT_SHIFT)
+# define TCN_CMR_AEEVT_NONE (0 << TCN_CMR_AEEVT_SHIFT)
+# define TCN_CMR_AEEVT_SET (1 << TCN_CMR_AEEVT_SHIFT)
+# define TCN_CMR_AEEVT_CLEAR (2 << TCN_CMR_AEEVT_SHIFT)
+# define TCN_CMR_AEEVT_TOGGLE (3 << TCN_CMR_AEEVT_SHIFT)
+#define TCN_CMR_ASWTRG_SHIFT (22) /* Bits 22-23: Software Trigger Effect on TIOA (Waveform mode) */
+#define TCN_CMR_ASWTRG_MASK (3 << TCN_CMR_ASWTRG_SHIFT)
+# define TCN_CMR_ASWTRG_NONE (0 << TCN_CMR_ASWTRG_SHIFT)
+# define TCN_CMR_ASWTRG_SET (1 << TCN_CMR_ASWTRG_SHIFT)
+# define TCN_CMR_ASWTRG_CLEAR (2 << TCN_CMR_ASWTRG_SHIFT)
+# define TCN_CMR_ASWTRG_TOGGLE (3 << TCN_CMR_ASWTRG_SHIFT)
+#define TCN_CMR_BCPB_SHIFT (24) /* Bits 24-25: RB Compare Effect on TIOB (Waveform mode) */
+#define TCN_CMR_BCPB_MASK (3 << TCN_CMR_BCPB_SHIFT)
+# define TCN_CMR_BCPB_NONE (0 << TCN_CMR_BCPB_SHIFT)
+# define TCN_CMR_BCPB_SET (1 << TCN_CMR_BCPB_SHIFT)
+# define TCN_CMR_BCPB_CLEAR (2 << TCN_CMR_BCPB_SHIFT)
+# define TCN_CMR_BCPB_TOGGLE (3 << TCN_CMR_BCPB_SHIFT)
+#define TCN_CMR_BCPC_SHIFT (26) /* Bits 26-27: RC Compare Effect on TIOB (Waveform mode) */
+#define TCN_CMR_BCPC_MASK (3 << TCN_CMR_BCPC_SHIFT)
+# define TCN_CMR_BCPC_NONE (0 << TCN_CMR_BCPC_SHIFT)
+# define TCN_CMR_BCPC_SET (1 << TCN_CMR_BCPC_SHIFT)
+# define TCN_CMR_BCPC_CLEAR (2 << TCN_CMR_BCPC_SHIFT)
+# define TCN_CMR_BCPC_TOGGLE (3 << TCN_CMR_BCPC_SHIFT)
+#define TCN_CMR_BEEVT_SHIFT (28) /* Bits 28-29: External Event Effect on TIOB (Waveform mode) */
+#define TCN_CMR_BEEVT_MASK (3 << TCN_CMR_BEEVT_SHIFT)
+# define TCN_CMR_BEEVT_NONE (0 << TCN_CMR_BEEVT_SHIFT)
+# define TCN_CMR_BEEVT_SET (1 << TCN_CMR_BEEVT_SHIFT)
+# define TCN_CMR_BEEVT_CLEAR (2 << TCN_CMR_BEEVT_SHIFT)
+# define TCN_CMR_BEEVT_TOGGLE (3 << TCN_CMR_BEEVT_SHIFT)
+#define TCN_CMR_BSWTRG_SHIFT (30) /* Bits 30-31: Software Trigger Effect on TIOB (Waveform mode) */
+#define TCN_CMR_BSWTRG_MASK (3 << TCN_CMR_BSWTRG_SHIFT)
+# define TCN_CMR_BSWTRG_NONE (0 << TCN_CMR_BSWTRG_SHIFT)
+# define TCN_CMR_BSWTRG_SET (1 << TCN_CMR_BSWTRG_SHIFT)
+# define TCN_CMR_BSWTRG_CLEAR (2 << TCN_CMR_BSWTRG_SHIFT)
+# define TCN_CMR_BSWTRG_TOGGLE (3 << TCN_CMR_BSWTRG_SHIFT)
+
+/* TC Counter Value Register */
+
+#define TCN_CV_SHIFT (0) /* Bits 0-15: Counter Value */
+#define TCN_CV_MASK (0xffff << TCN_CV_SHIFT)
+
+/* TC Register A, B, C */
+
+#define TCN_RVALUE_SHIFT (0) /* Bits 0-15: Register A, B, or C value */
+#define TCN_RVALUE_MASK (0xffff << TCN_RVALUE_SHIFT)
+
+/* TC Status Register, TC Interrupt Enable Register, TC Interrupt Disable Register, and TC Interrupt Mask Register common bit-field definitions */
+
+#define TCN_INT_COVFS (1 << 0) /* Bit 0: Counter Overflow */
+#define TCN_INT_LOVRS (1 << 1) /* Bit 1: Load Overrun */
+#define TCN_INT_CPAS (1 << 2) /* Bit 2: RA Compare */
+#define TCN_INT_CPBS (1 << 3) /* Bit 3: RB Compare */
+#define TCN_INT_CPCS (1 << 4) /* Bit 4: RC Compare */
+#define TCN_INT_LDRAS (1 << 5) /* Bit 5: RA Loading */
+#define TCN_INT_LDRBS (1 << 6) /* Bit 6: RB Loading */
+#define TCN_INT_ETRGS (1 << 7) /* Bit 7: External Trigger */
+#define TCN_INT_CLKSTA (1 << 16) /* Bit 16: Clock Enabling (SR only) */
+#define TCN_SR_MTIOA (1 << 17) /* Bit 17: TIOA Mirror (SR only) */
+#define TCN_SR_MTIOB (1 << 18) /* Bit 18: TIOB Mirror (SR only)*/
+
+/************************************************************************************************
+ * Public Types
+ ************************************************************************************************/
+
+/************************************************************************************************
+ * Public Data
+ ************************************************************************************************/
+
+/************************************************************************************************
+ * Public Functions
+ ************************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_SAM3U_SAM3U_TC_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_timerisr.c b/nuttx/arch/arm/src/sam3u/sam3u_timerisr.c
new file mode 100644
index 000000000..5ff6dea69
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_timerisr.c
@@ -0,0 +1,162 @@
+/****************************************************************************
+ * arch/arm/src/sam3u/sam3u_timerisr.c
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <time.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "nvic.h"
+#include "clock_internal.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "sam3u_internal.h"
+
+/****************************************************************************
+ * 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 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_SAM3U_SYSTICK_HCLKd8 /* Power up default is MCK, not MCK/8 */
+
+#if CONFIG_SAM3U_SYSTICK_HCLKd8
+# define SYSTICK_RELOAD ((SAM3U_MCK_FREQUENCY / 8 / CLK_TCK) - 1)
+#else
+# define SYSTICK_RELOAD ((SAM3U_MCK_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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize
+ * the timer interrupt.
+ *
+ ****************************************************************************/
+
+void up_timerinit(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);
+#if CONFIG_SAM3U_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(SAM3U_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(SAM3U_IRQ_SYSTICK);
+}
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_twi.h b/nuttx/arch/arm/src/sam3u/sam3u_twi.h
new file mode 100644
index 000000000..66d1f23b3
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_twi.h
@@ -0,0 +1,192 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_twi.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_TWI_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_TWI_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* TWI register offsets *****************************************************************/
+
+#define SAM3U_TWI_CR_OFFSET 0x00 /* Control Register */
+#define SAM3U_TWI_MMR_OFFSET 0x04 /* Master Mode Register */
+#define SAM3U_TWI_SMR_OFFSET 0x08 /* Slave Mode Register */
+#define SAM3U_TWI_IADR_OFFSET 0x0c /* Internal Address Register */
+#define SAM3U_TWI_CWGR_OFFSET 0x10 /* Clock Waveform Generator Register */
+#define SAM3U_TWI_SR_OFFSET 0x20 /* Status Register */
+#define SAM3U_TWI_IER_OFFSET 0x24 /* Interrupt Enable Register */
+#define SAM3U_TWI_IDR_OFFSET 0x28 /* Interrupt Disable Register */
+#define SAM3U_TWI_IMR_OFFSET 0x2c /* Interrupt Mask Register */
+#define SAM3U_TWI_RHR_OFFSET 0x30 /* Receive Holding Register */
+#define SAM3U_TWI_THR_OFFSET 0x34 /* Transmit Holding Register */
+ /* 0x38-0xfc: Reserved */
+ /* 0x100-0x124: Reserved for the PDC */
+
+/* TWI register adresses ****************************************************************/
+
+#define SAM3U_TWI_CR(n) (SAM3U_TWIN_BASE(n)+SAM3U_TWI_CR_OFFSET)
+#define SAM3U_TWI_MMR(n) (SAM3U_TWIN_BASE(n)+SAM3U_TWI_MMR_OFFSET)
+#define SAM3U_TWI_SMR(n) (SAM3U_TWIN_BASE(n)+SAM3U_TWI_SMR_OFFSET)
+#define SAM3U_TWI_IADR(n) (SAM3U_TWIN_BASE(n)+SAM3U_TWI_IADR_OFFSET)
+#define SAM3U_TWI_CWGR(n) (SAM3U_TWIN_BASE(n)+SAM3U_TWI_CWGR_OFFSET)
+#define SAM3U_TWI_SR(n) (SAM3U_TWIN_BASE(n)+SAM3U_TWI_SR_OFFSET)
+#define SAM3U_TWI_IER(n) (SAM3U_TWIN_BASE(n)+SAM3U_TWI_IER_OFFSET)
+#define SAM3U_TWI_IDR(n) (SAM3U_TWIN_BASE(n)+SAM3U_TWI_IDR_OFFSET)
+#define SAM3U_TWI_IMR(n) (SAM3U_TWIN_BASE(n)+SAM3U_TWI_IMR_OFFSET)
+#define SAM3U_TWI_RHR(n) (SAM3U_TWIN_BASE(n)+SAM3U_TWI_RHR_OFFSET)
+#define SAM3U_TWI_THR(n) (SAM3U_TWIN_BASE(n)+SAM3U_TWI_THR_OFFSET)
+
+#define SAM3U_TWI0_CR (SAM3U_TWI0_BASE+SAM3U_TWI_CR_OFFSET)
+#define SAM3U_TWI0_MMR (SAM3U_TWI0_BASE+SAM3U_TWI_MMR_OFFSET)
+#define SAM3U_TWI0_SMR (SAM3U_TWI0_BASE+SAM3U_TWI_SMR_OFFSET)
+#define SAM3U_TWI0_IADR (SAM3U_TWI0_BASE+SAM3U_TWI_IADR_OFFSET)
+#define SAM3U_TWI0_CWGR (SAM3U_TWI0_BASE+SAM3U_TWI_CWGR_OFFSET)
+#define SAM3U_TWI0_SR (SAM3U_TWI0_BASE+SAM3U_TWI_SR_OFFSET)
+#define SAM3U_TWI0_IER (SAM3U_TWI0_BASE+SAM3U_TWI_IER_OFFSET)
+#define SAM3U_TWI0_IDR (SAM3U_TWI0_BASE+SAM3U_TWI_IDR_OFFSET)
+#define SAM3U_TWI0_IMR (SAM3U_TWI0_BASE+SAM3U_TWI_IMR_OFFSET)
+#define SAM3U_TWI0_RHR (SAM3U_TWI0_BASE+SAM3U_TWI_RHR_OFFSET)
+#define SAM3U_TWI0_THR (SAM3U_TWI0_BASE+SAM3U_TWI_THR_OFFSET)
+
+#define SAM3U_TWI1_CR (SAM3U_TWI1_BASE+SAM3U_TWI_CR_OFFSET)
+#define SAM3U_TWI1_MMR (SAM3U_TWI1_BASE+SAM3U_TWI_MMR_OFFSET)
+#define SAM3U_TWI1_SMR (SAM3U_TWI1_BASE+SAM3U_TWI_SMR_OFFSET)
+#define SAM3U_TWI1_IADR (SAM3U_TWI1_BASE+SAM3U_TWI_IADR_OFFSET)
+#define SAM3U_TWI1_CWGR (SAM3U_TWI1_BASE+SAM3U_TWI_CWGR_OFFSET)
+#define SAM3U_TWI1_SR (SAM3U_TWI1_BASE+SAM3U_TWI_SR_OFFSET)
+#define SAM3U_TWI1_IER (SAM3U_TWI1_BASE+SAM3U_TWI_IER_OFFSET)
+#define SAM3U_TWI1_IDR (SAM3U_TWI1_BASE+SAM3U_TWI_IDR_OFFSET)
+#define SAM3U_TWI1_IMR (SAM3U_TWI1_BASE+SAM3U_TWI_IMR_OFFSET)
+#define SAM3U_TWI1_RHR (SAM3U_TWI1_BASE+SAM3U_TWI_RHR_OFFSET)
+#define SAM3U_TWI1_THR (SAM3U_TWI1_BASE+SAM3U_TWI_THR_OFFSET)
+
+/* 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_3BYTE (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-23: Device Address */
+#define TWI_MMR_DADR_MASK (0xff << TWI_MMR_DADR_SHIFT)
+
+/* TWI Slave Mode Register */
+
+#define TWI_SMR_SADR_SHIFT (16) /* Bits 16-23: Slave Address */
+#define TWI_SMR_SADR_MASK (0xff << 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_CHDIV_SHIFT (8) /* Bits 8-15: Clock High Divider */
+#define TWI_CWGR_CHDIV_MASK (0xff << 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)
+
+/* 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)
+
+/****************************************************************************************
+ * Public Types
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Data
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Functions
+ ****************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_SAM3U_SAM3U_TWI_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_uart.h b/nuttx/arch/arm/src/sam3u/sam3u_uart.h
new file mode 100644
index 000000000..1103cbfad
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_uart.h
@@ -0,0 +1,391 @@
+/************************************************************************************************
+ * arch/arm/src/sam3u/sam3u_uart.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_UART_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_UART_H
+
+/************************************************************************************************
+ * Included Files
+ ************************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/************************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************************/
+
+/* UART register offsets ************************************************************************/
+
+#define SAM3U_UART_CR_OFFSET 0x0000 /* Control Register (Common) */
+#define SAM3U_UART_MR_OFFSET 0x0004 /* Mode Register (Common) */
+#define SAM3U_UART_IER_OFFSET 0x0008 /* Interrupt Enable Register (Common) */
+#define SAM3U_UART_IDR_OFFSET 0x000c /* Interrupt Disable Register (Common) */
+#define SAM3U_UART_IMR_OFFSET 0x0010 /* Interrupt Mask Register (Common) */
+#define SAM3U_UART_SR_OFFSET 0x0014 /* Status Register (Common) */
+#define SAM3U_UART_RHR_OFFSET 0x0018 /* Receive Holding Register (Common) */
+#define SAM3U_UART_THR_OFFSET 0x001c /* Transmit Holding Register (Common) */
+#define SAM3U_UART_BRGR_OFFSET 0x0020 /* Baud Rate Generator Register (Common) */
+ /* 0x0024-0x003c: Reserved (UART) */
+#define SAM3U_USART_RTOR_OFFSET 0x0024 /* Receiver Time-out Register (USART only) */
+#define SAM3U_USART_TTGR_OFFSET 0x0028 /* Transmitter Timeguard Register (USART only) */
+ /* 0x002c-0x003c: Reserved (UART) */
+#define SAM3U_USART_FIDI_OFFSET 0x0040 /* FI DI Ratio Register (USART only) */
+#define SAM3U_USART_NER_OFFSET 0x0044 /* Number of Errors Register ((USART only) */
+ /* 0x0048: Reserved (USART) */
+#define SAM3U_USART_IF_OFFSET 0x004c /* IrDA Filter Register (USART only) */
+#define SAM3U_USART_MAN_OFFSET 0x0050 /* Manchester Encoder Decoder Register (USART only) */
+#define SAM3U_USART_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register (USART only) */
+#define SAM3U_USART_WPSR_OFFSET 0x00e8 /* Write Protect Status Register (USART only) */
+ /* 0x005c-0xf008: Reserved (USART) */
+#define SAM3U_USART_VERSION_OFFSET 0x00fc /* Version Register (USART only) */
+ /* 0x0100-0x0124: PDC Area (Common) */
+
+/* UART register adresses ***********************************************************************/
+
+#define SAM3U_UART_CR (SAM3U_UART_BASE+SAM3U_UART_CR_OFFSET)
+#define SAM3U_UART_MR (SAM3U_UART_BASE+SAM3U_UART_MR_OFFSET)
+#define SAM3U_UART_IER (SAM3U_UART_BASE+SAM3U_UART_IER_OFFSET)
+#define SAM3U_UART_IDR (SAM3U_UART_BASE+SAM3U_UART_IDR_OFFSET)
+#define SAM3U_UART_IMR (SAM3U_UART_BASE+SAM3U_UART_IMR_OFFSET)
+#define SAM3U_UART_SR (SAM3U_UART_BASE+SAM3U_UART_SR_OFFSET)
+#define SAM3U_UART_RHR (SAM3U_UART_BASE+SAM3U_UART_RHR_OFFSET)
+#define SAM3U_UART_THR (SAM3U_UART_BASE+SAM3U_UART_THR_OFFSET)
+#define SAM3U_UART_BRGR (SAM3U_UART_BASE+SAM3U_UART_BRGR_OFFSET)
+
+#define SAM3U_USART_CR(n) (SAM3U_USARTN_BASE(n)+SAM3U_UART_CR_OFFSET)
+#define SAM3U_USART_MR(n) (SAM3U_USARTN_BASE(n)+SAM3U_UART_MR_OFFSET)
+#define SAM3U_USART_IER(n) (SAM3U_USARTN_BASE(n)+SAM3U_UART_IER_OFFSET)
+#define SAM3U_USART_IDR(n) (SAM3U_USARTN_BASE(n)+SAM3U_UART_IDR_OFFSET)
+#define SAM3U_USART_IMR(n) (SAM3U_USARTN_BASE(n)+SAM3U_UART_IMR_OFFSET)
+#define SAM3U_USART_SR(n) (SAM3U_USARTN_BASE(n)+SAM3U_UART_SR_OFFSET)
+#define SAM3U_USART_RHR(n) (SAM3U_USARTN_BASE(n)+SAM3U_UART_RHR_OFFSET)
+#define SAM3U_USART_THR(n) (SAM3U_USARTN_BASE(n)+SAM3U_UART_THR_OFFSET)
+#define SAM3U_USART_BRGR(n) (SAM3U_USARTN_BASE(n)+SAM3U_UART_BRGR_OFFSET)
+#define SAM3U_USART_RTOR(n) (SAM3U_USARTN_BASE(n)+SAM3U_USART_RTOR_OFFSET)
+#define SAM3U_USART_TTGR(n) (SAM3U_USARTN_BASE(n)+SAM3U_USART_TTGR_OFFSET)
+#define SAM3U_USART_FIDI(n) (SAM3U_USARTN_BASE(n)+SAM3U_USART_FIDI_OFFSET)
+#define SAM3U_USART_NER(n) (SAM3U_USARTN_BASE(n)+SAM3U_USART_NER_OFFSET)
+#define SAM3U_USART_IF(n) (SAM3U_USARTN_BASE(n)+SAM3U_USART_IF_OFFSET)
+#define SAM3U_USART_MAN(n) (SAM3U_USARTN_BASE(n)+SAM3U_USART_MAN_OFFSET)
+#define SAM3U_USART_WPMR(n) (SAM3U_USARTN_BASE(n)+SAM3U_USART_WPMR_OFFSET)
+#define SAM3U_USART_WPSR(n) (SAM3U_USARTN_BASE(n)+SAM3U_USART_WPSR_OFFSET)
+#define SAM3U_USART_VERSION(n) (SAM3U_USARTN_BASE(n)+SAM3U_USART_VERSION_OFFSET)
+
+#define SAM3U_USART0_CR (SAM3U_USART0_BASE+SAM3U_UART_CR_OFFSET)
+#define SAM3U_USART0_MR_ (SAM3U_USART0_BASE+SAM3U_UART_MR_OFFSET)
+#define SAM3U_USART0_IER (SAM3U_USART0_BASE+SAM3U_UART_IER_OFFSET)
+#define SAM3U_USART0_IDR (SAM3U_USART0_BASE+SAM3U_UART_IDR_OFFSET)
+#define SAM3U_USART0_IMR (SAM3U_USART0_BASE+SAM3U_UART_IMR_OFFSET)
+#define SAM3U_USART0_SR (SAM3U_USART0_BASE+SAM3U_UART_SR_OFFSET)
+#define SAM3U_USART0_RHR (SAM3U_USART0_BASE+SAM3U_UART_RHR_OFFSET)
+#define SAM3U_USART0_THR (SAM3U_USART0_BASE+SAM3U_UART_THR_OFFSET)
+#define SAM3U_USART0_BRGR (SAM3U_USART0_BASE+SAM3U_UART_BRGR_OFFSET)
+#define SAM3U_USART0_RTOR (SAM3U_USART0_BASE+SAM3U_USART_RTOR_OFFSET)
+#define SAM3U_USART0_TTGR (SAM3U_USART0_BASE+SAM3U_USART_TTGR_OFFSET)
+#define SAM3U_USART0_FIDI (SAM3U_USART0_BASE+SAM3U_USART_FIDI_OFFSET)
+#define SAM3U_USART0_NER (SAM3U_USART0_BASE+SAM3U_USART_NER_OFFSET)
+#define SAM3U_USART0_IF (SAM3U_USART0_BASE+SAM3U_USART_IF_OFFSET)
+#define SAM3U_USART0_MAN (SAM3U_USART0_BASE+SAM3U_USART_MAN_OFFSET)
+#define SAM3U_USART0_WPMR (SAM3U_USART0_BASE+SAM3U_USART_WPMR_OFFSET)
+#define SAM3U_USART0_WPSR (SAM3U_USART0_BASE+SAM3U_USART_WPSR_OFFSET)
+#define SAM3U_USART0_VERSION (SAM3U_USART0_BASE+SAM3U_USART_VERSION_OFFSET)
+
+#define SAM3U_USART1_CR (SAM3U_USART1_BASE+SAM3U_UART_CR_OFFSET)
+#define SAM3U_USART1_MR_ (SAM3U_USART1_BASE+SAM3U_UART_MR_OFFSET)
+#define SAM3U_USART1_IER (SAM3U_USART1_BASE+SAM3U_UART_IER_OFFSET)
+#define SAM3U_USART1_IDR (SAM3U_USART1_BASE+SAM3U_UART_IDR_OFFSET)
+#define SAM3U_USART1_IMR (SAM3U_USART1_BASE+SAM3U_UART_IMR_OFFSET)
+#define SAM3U_USART1_SR (SAM3U_USART1_BASE+SAM3U_UART_SR_OFFSET)
+#define SAM3U_USART1_RHR (SAM3U_USART1_BASE+SAM3U_UART_RHR_OFFSET)
+#define SAM3U_USART1_THR (SAM3U_USART1_BASE+SAM3U_UART_THR_OFFSET)
+#define SAM3U_USART1_BRGR (SAM3U_USART1_BASE+SAM3U_UART_BRGR_OFFSET)
+#define SAM3U_USART1_RTOR (SAM3U_USART1_BASE+SAM3U_USART_RTOR_OFFSET)
+#define SAM3U_USART1_TTGR (SAM3U_USART1_BASE+SAM3U_USART_TTGR_OFFSET)
+#define SAM3U_USART1_FIDI (SAM3U_USART1_BASE+SAM3U_USART_FIDI_OFFSET)
+#define SAM3U_USART1_NER (SAM3U_USART1_BASE+SAM3U_USART_NER_OFFSET)
+#define SAM3U_USART1_IF (SAM3U_USART1_BASE+SAM3U_USART_IF_OFFSET)
+#define SAM3U_USART1_MAN (SAM3U_USART1_BASE+SAM3U_USART_MAN_OFFSET)
+#define SAM3U_USART1_WPMR (SAM3U_USART1_BASE+SAM3U_USART_WPMR_OFFSET)
+#define SAM3U_USART1_WPSR (SAM3U_USART1_BASE+SAM3U_USART_WPSR_OFFSET)
+#define SAM3U_USART1_VERSION (SAM3U_USART1_BASE+SAM3U_USART_VERSION_OFFSET)
+
+#define SAM3U_USART2_CR (SAM3U_USART2_BASE+SAM3U_UART_CR_OFFSET)
+#define SAM3U_USART2_MR_ (SAM3U_USART2_BASE+SAM3U_UART_MR_OFFSET)
+#define SAM3U_USART2_IER (SAM3U_USART2_BASE+SAM3U_UART_IER_OFFSET)
+#define SAM3U_USART2_IDR (SAM3U_USART2_BASE+SAM3U_UART_IDR_OFFSET)
+#define SAM3U_USART2_IMR (SAM3U_USART2_BASE+SAM3U_UART_IMR_OFFSET)
+#define SAM3U_USART2_SR (SAM3U_USART2_BASE+SAM3U_UART_SR_OFFSET)
+#define SAM3U_USART2_RHR (SAM3U_USART2_BASE+SAM3U_UART_RHR_OFFSET)
+#define SAM3U_USART2_THR (SAM3U_USART2_BASE+SAM3U_UART_THR_OFFSET)
+#define SAM3U_USART2_BRGR (SAM3U_USART2_BASE+SAM3U_UART_BRGR_OFFSET)
+#define SAM3U_USART2_RTOR (SAM3U_USART2_BASE+SAM3U_USART_RTOR_OFFSET)
+#define SAM3U_USART2_TTGR (SAM3U_USART2_BASE+SAM3U_USART_TTGR_OFFSET)
+#define SAM3U_USART2_FIDI (SAM3U_USART2_BASE+SAM3U_USART_FIDI_OFFSET)
+#define SAM3U_USART2_NER (SAM3U_USART2_BASE+SAM3U_USART_NER_OFFSET)
+#define SAM3U_USART2_IF (SAM3U_USART2_BASE+SAM3U_USART_IF_OFFSET)
+#define SAM3U_USART2_MAN (SAM3U_USART2_BASE+SAM3U_USART_MAN_OFFSET)
+#define SAM3U_USART2_WPMR (SAM3U_USART2_BASE+SAM3U_USART_WPMR_OFFSET)
+#define SAM3U_USART2_WPSR (SAM3U_USART2_BASE+SAM3U_USART_WPSR_OFFSET)
+#define SAM3U_USART2_VERSION (SAM3U_USART2_BASE+SAM3U_USART_VERSION_OFFSET)
+
+#define SAM3U_USART3_CR (SAM3U_USART3_BASE+SAM3U_UART_CR_OFFSET)
+#define SAM3U_USART3_MR_ (SAM3U_USART3_BASE+SAM3U_UART_MR_OFFSET)
+#define SAM3U_USART3_IER (SAM3U_USART3_BASE+SAM3U_UART_IER_OFFSET)
+#define SAM3U_USART3_IDR (SAM3U_USART3_BASE+SAM3U_UART_IDR_OFFSET)
+#define SAM3U_USART3_IMR (SAM3U_USART3_BASE+SAM3U_UART_IMR_OFFSET)
+#define SAM3U_USART3_SR (SAM3U_USART3_BASE+SAM3U_UART_SR_OFFSET)
+#define SAM3U_USART3_RHR (SAM3U_USART3_BASE+SAM3U_UART_RHR_OFFSET)
+#define SAM3U_USART3_THR (SAM3U_USART3_BASE+SAM3U_UART_THR_OFFSET)
+#define SAM3U_USART3_BRGR (SAM3U_USART3_BASE+SAM3U_UART_BRGR_OFFSET)
+#define SAM3U_USART3_RTOR (SAM3U_USART3_BASE+SAM3U_USART_RTOR_OFFSET)
+#define SAM3U_USART3_TTGR (SAM3U_USART3_BASE+SAM3U_USART_TTGR_OFFSET)
+#define SAM3U_USART3_FIDI (SAM3U_USART3_BASE+SAM3U_USART_FIDI_OFFSET)
+#define SAM3U_USART3_NER (SAM3U_USART3_BASE+SAM3U_USART_NER_OFFSET)
+#define SAM3U_USART3_IF (SAM3U_USART3_BASE+SAM3U_USART_IF_OFFSET)
+#define SAM3U_USART3_MAN (SAM3U_USART3_BASE+SAM3U_USART_MAN_OFFSET)
+#define SAM3U_USART3_WPMR (SAM3U_USART3_BASE+SAM3U_USART_WPMR_OFFSET)
+#define SAM3U_USART3_WPSR (SAM3U_USART3_BASE+SAM3U_USART_WPSR_OFFSET)
+#define SAM3U_USART3_VERSION (SAM3U_USART3_BASE+SAM3U_USART_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 USART_CR_STTBRK (1 << 9) /* Bit 9: Start Break (USART only) */
+#define USART_CR_STPBRK (1 << 10) /* Bit 10: Stop Break (USART only) */
+#define USART_CR_STTTO (1 << 11) /* Bit 11: Start Time-out (USART only) */
+#define USART_CR_SENDA (1 << 12) /* Bit 12: Send Address (USART only) */
+#define USART_CR_RSTIT (1 << 13) /* Bit 13: Reset Iterations (USART only) */
+#define USART_CR_RSTNACK (1 << 14) /* Bit 14: Reset Non Acknowledge (USART only) */
+#define USART_CR_RETTO (1 << 15) /* Bit 15: Rearm Time-out (USART only) */
+#define USART_CR_RTSEN (1 << 18) /* Bit 18: Request to Send Enable (USART only) */
+#define USART_CR_FCS (1 << 18) /* Bit 18: Force SPI Chip Select (USART only) */
+#define USART_CR_RTSDIS (1 << 19) /* Bit 19: Request to Send Disable (USART only) */
+#define USART_CR_RCS (1 << 19) /* Bit 19: Release SPI Chip Select (USART only) */
+
+/* UART Mode Register */
+
+#define USART_MR_MODE_SHIFT (0) /* Bits 0-3: (USART only) */
+#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_HWHS (2 << USART_MR_MODE_SHIFT) /* Hardware Handshaking */
+# define USART_MR_MODE_ISO7816_0 (4 << USART_MR_MODE_SHIFT) /* IS07816 Protocol: T = 0 */
+# define USART_MR_MODE_ISO7816_1 (6 << USART_MR_MODE_SHIFT) /* IS07816 Protocol: T = 1 */
+# define USART_MR_MODE_IRDA (8 << USART_MR_MODE_SHIFT) /* IrDA */
+# define USART_MR_MODE_SPIMSTR (14 << USART_MR_MODE_SHIFT) /* SPI Master */
+# define USART_MR_MODE_SPISLV (15 << USART_MR_MODE_SHIFT) /* SPI Slave */
+#define USART_MR_USCLKS_SHIFT (4) /* Bits 4-5: Clock Selection (USART only) */
+#define USART_MR_USCLKS_MASK (3 << USART_MR_USCLKS_SHIFT)
+# define USART_MR_USCLKS_MCK (0 << USART_MR_USCLKS_SHIFT) /* MCK */
+# define USART_MR_USCLKS_MCKDIV (1 << USART_MR_USCLKS_SHIFT) /* MCK/DIV (DIV = 8) */
+# define USART_MR_USCLKS_SCK (3 << USART_MR_USCLKS_SHIFT) /* SCK */
+#define USART_MR_CHRL_SHIFT (6) /* Bits 6-7: Character Length (USART only) */
+#define USART_MR_CHRL_MASK (3 << 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_YNC (1 << 8) /* Bit 8: Synchronous Mode Select (USART only) */
+#define USART_MR_CPHA (1 << 8) /* Bit 8: SPI Clock Phase (USART 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 USART_MR_NBSTOP_SHIFT (12) /* Bits 12-13: Number of Stop Bits (USART only) */
+#define USART_MR_NBSTOP_MASK (3 << USART_MR_NBSTOP_SHIFT)
+# define USART_MR_NBSTOP_1 (0 << USART_MR_NBSTOP_SHIFT) /* 1 stop bit 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 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 */
+#define USART_MR_MSBF (1 << 16) /* Bit 16: Bit Order or SPI Clock Polarity (USART only) */
+#define USART_MR_CPOL (1 << 16)
+#define USART_MR_MODE9 (1 << 17) /* Bit 17: 9-bit Character Length (USART only) */
+#define USART_MR_CLKO (1 << 18) /* Bit 18: Clock Output Select (USART only) */
+#define USART_MR_OVER (1 << 19) /* Bit 19: Oversampling Mode (USART only) */
+#define USART_MR_INACK (1 << 20) /* Bit 20: Inhibit Non Acknowledge (USART only) */
+#define USART_MR_DSNACK (1 << 21) /* Bit 21: Disable Successive NACK (USART only) */
+#define USART_MR_VARSYNC (1 << 22) /* Bit 22: Variable Synchronization of Command/Data Sync Start Frame Delimiter (USART only) */
+#define USART_MR_INVDATA (1 << 23) /* Bit 23: INverted Data (USART only) */
+#define USART_MR_MAXITER_SHIFT (24) /* Bits 24-26: Max iterations (ISO7816 T=0 (USART only) */
+#define USART_MR_MAXITER_MASK (7 << USART_MR_MAXITER_SHIFT)
+#define USART_MR_FILTER (1 << 28) /* Bit 28: Infrared Receive Line Filter (USART only) */
+#define USART_MR_MAN (1 << 29) /* Bit 29: Manchester Encoder/Decoder Enable (USART only) */
+#define USART_MR_MODSYNC (1 << 30) /* Bit 30: Manchester Synchronization Mode (USART only) */
+#define USART_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 USART_INT_TIMEOUT (1 << 8) /* Bit 8: Time-out Interrupt (USART only) */
+#define UART_INT_TXEMPTY (1 << 9) /* Bit 9: TXEMPTY Interrupt (Common) */
+#define USART_INT_ITER (1 << 10) /* Bit 10: Iteration Interrupt (USART only) */
+#define USART_INT_UNRE (1 << 10) /* Bit 10: SPI Underrun Error Interrupt (USART 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 USART_INT_NACK (1 << 13) /* Bit 13: Non Acknowledge Interrupt (USART only) */
+#define USART_INT_CTSIC (1 << 19) /* Bit 19: Clear to Send Input Change Interrupt (USART only) */
+#define USART_INT_MANE (1 << 24) /* Bit 24: Manchester Error Interrupt (USART only) */
+
+/* UART Receiver Holding Register */
+
+#define UART_RHR_RXCHR_SHIFT (0) /* Bits 0-7: Received Character (UART only) */
+#define UART_RHR_RXCHR_MASK (0xff << UART_RHR_RXCHR_SHIFT)
+#define USART_RHR_RXCHR_SHIFT (0) /* Bits 0-8: Received Character (USART only) */
+#define USART_RHR_RXCHR_MASK (0x1ff << UART_RHR_RXCHR_SHIFT)
+#define USART_RHR_RXSYNH (1 << 15) /* Bit 15: Received Sync (USART only) */
+
+/* UART Transmit Holding Register */
+
+#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)
+#define USART_THR_TXCHR_SHIFT (0) /* Bits 0-8: Character to be Transmitted (USART only) */
+#define USART_THR_TXCHR_MASK (0x1ff << USART_THR_TXCHR_SHIFT)
+#define USART_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 USART_RTOR_TO_SHIFT (0) /* Bits 0-15: Time-out Value (USART only) */
+#define USART_RTOR_TO_MASK (0xffff << USART_RTOR_TO_SHIFT)
+
+/* USART Transmitter Timeguard Register (USART only) */
+
+#define USART_TTGR_TG_SHIFT (0) /* Bits 0-7: Timeguard Value (USART only) */
+#define USART_TTGR_TG_MASK (0xff << USART_TTGR_TG_SHIFT)
+
+/* USART FI DI RATIO Register (USART only) */
+
+#define USART_FIDI_RATIO_SHIFT (0) /* Bits 0-10: FI Over DI Ratio Value (USART only) */
+#define USART_FIDI_RATIO_MASK (0x7ff << USART_FIDI_RATIO_SHIFT)
+
+/* USART Number of Errors Register (USART only) */
+
+#define USART_NER_NBERRORS_SHIFT (0) /* Bits 0-7: Number of Errrors (USART only) */
+#define USART_NER_NBERRORS_MASK (0xff << USART_NER_NBERRORS_SHIFT)
+
+/* USART IrDA FILTER Register (USART only) */
+
+#define USART_IF_IRDAFILTER_SHIFT (0) /* Bits 0-7: IrDA Filter (USART only) */
+#define USART_IF_IRDAFILTER_MASK (0xff << USART_IF_IRDAFILTER_SHIFT)
+
+/* USART Manchester Configuration Register (USART only) */
+
+#define USART_MAN_TXPL_SHIFT (0) /* Bits 0-3: Transmitter Preamble Length (USART only) */
+#define USART_MAN_TXPL_MASK (15 << USART_MAN_TXPL_SHIFT)
+#define USART_MAN_TXPP_SHIFT (8) /* Bits 8-9: Transmitter Preamble Pattern (USART only) */
+#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_ZEROONE (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 (USART only) */
+#define USART_MAN_RXPL_SHIFT (16) /* Bits 16-19: Receiver Preamble Length (USART only) */
+#define USART_MAN_RXPL_MASK (15 << USART_MAN_RXPL_SHIFT)
+#define USART_MAN_RXPP_SHIFT (24) /* Bits 24-25: Receiver Preamble Pattern detected (USART only) */
+#define USART_MAN_RXPP_MASK (3 << USART_MAN_RXPP_SHIFT)
+# define USART_MAN_RXPP_ALLONE (0 << USART_MAN_RXPP_SHIFT) /* ALL_ONE */
+# define USART_MAN_RXPP_ALLZERO (1 << USART_MAN_RXPP_SHIFT) /* ALL_ZERO */
+# define USART_MAN_RXPP_ZEROONE (2 << USART_MAN_RXPP_SHIFT) /* ZERO_ONE */
+# define USART_MAN_RXPP_ONEZERO (3 << USART_MAN_RXPP_SHIFT) /* ONE_ZERO */
+#define USART_MAN_RXMPOL (1 << 28) /* Bit 28: Receiver Manchester Polarity (USART only) */
+#define USART_MAN_DRIFT (1 << 30) /* Bit 30: Drift compensation (USART only) */
+
+/* USART Write Protect Mode Register (USART only) */
+
+#define USART_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable (USART only) */
+#define USART_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY (USART only) */
+#define USART_WPMR_WPKEY_MASK (0x00ffffff << USART_WPMR_WPKEY_SHIFT)
+
+/* USART Write Protect Status Register (USART only) */
+
+#define USART_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status (USART only) */
+#define USART_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source (USART only) */
+#define USART_WPSR_WPVSRC_MASK (0xffff << USART_WPSR_WPVSRC_SHIFT)
+
+/* USART Version Register */
+
+#define USART_VERSION_VERSION_SHIFT (0) /* Bits 0-11: Macrocell version number (USART only) */
+#define USART_VERSION_VERSION_MASK (0xfff << USART_VERSION_VERSION_SHIFT)
+#define USART_VERSION_MFN_SHIFT (16) /* Bits 16-18: Reserved (USART only) */
+#define USART_VERSION_MFN_MASK (7 << USART_VERSION_MFN_SHIFT)
+
+/************************************************************************************************
+ * Public Types
+ ************************************************************************************************/
+
+/************************************************************************************************
+ * Public Data
+ ************************************************************************************************/
+
+/************************************************************************************************
+ * Public Functions
+ ************************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_SAM3U_SAM3U_UART_H */
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_udphs.h b/nuttx/arch/arm/src/sam3u/sam3u_udphs.h
new file mode 100644
index 000000000..e6eb88c77
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_udphs.h
@@ -0,0 +1,371 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_udphs.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_UDPHS_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_UDPHS_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* UDPHS register offsets ***************************************************************/
+
+#define SAM3U_UDPHS_CTRL_OFFSET 0x00 /* UDPHS Control Register */
+#define SAM3U_UDPHS_FNUM_OFFSET 0x04 /* UDPHS Frame Number Register */
+ /* 0x08-0x0C: Reserved */
+#define SAM3U_UDPHS_IEN_OFFSET 0x10 /* UDPHS Interrupt Enable Register */
+#define SAM3U_UDPHS_INTSTA_OFFSET 0x14 /* UDPHS Interrupt Status Register */
+#define SAM3U_UDPHS_CLRINT_OFFSET 0x18 /* UDPHS Clear Interrupt Register */
+#define SAM3U_UDPHS_EPTRST_OFFSET 0x1c /* UDPHS Endpoints Reset Register */
+ /* 0x20-0xcc: Reserved */
+#define SAM3U_UDPHS_TST_OFFSET 0xe0 /* UDPHS Test Register */
+ /* 0xE4-0xE8: Reserved */
+#define SAM3U_UDPHS_IPNAME1_OFFSET 0xf0 /* UDPHS Name1 Register */
+#define SAM3U_UDPHS_IPNAME2_OFFSET 0xf4 /* UDPHS Name2 Register */
+#define SAM3U_UDPHS_IPFEATURES_OFFSET 0xf8 /* UDPHS Features Register */
+
+/* Endpoint registers: Offsets for Endpoints 0-6: 0x100, 0x120, 0x140, 0x160, 0x180,
+ * 0x1a0, and 0x1c0
+ */
+
+#define SAM3U_UDPHSEP_OFFSET(n) (0x100+((n)<<5))
+#define SAM3U_UDPHSEP_CFG_OFFSET 0x00 /* UDPHS Endpoint Configuration Register */
+#define SAM3U_UDPHSEP_CTLENB_OFFSET 0x04 /* UDPHS Endpoint Control Enable Register */
+#define SAM3U_UDPHSEP_CTLDIS_OFFSET 0x08 /* UDPHS Endpoint Control Disable Register */
+#define SAM3U_UDPHSEP_CTL_OFFSET 0x0c /* UDPHS Endpoint Control Register */
+ /* 0x10: Reserved */
+#define SAM3U_UDPHSEP_SETSTA_OFFSET 0x14 /* UDPHS Endpoint Set Status Register */
+#define SAM3U_UDPHSEP_CLRSTA_OFFSET 0x18 /* UDPHS Endpoint Clear Status Register */
+#define SAM3U_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 SAM3U_UDPHSDMA_OFFSET(n) (0x310+((n)<<4))
+#define SAM3U_UDPHSDMA_NXTDSC_OFFSET 0x00 /* UDPHS DMA Next Descriptor Address Register */
+#define SAM3U_UDPHSDMA_ADDRESS_OFFSET 0x04 /* UDPHS DMA Channel Address Register */
+#define SAM3U_UDPHSDMA_CONTROL_OFFSET 0x08 /* UDPHS DMA Channel Control Register */
+#define SAM3U_UDPHSDMA_STATUS_OFFSET) 0x0c /* UDPHS DMA Channel Status Register */
+
+/* UDPHS register adresses **************************************************************/
+
+#define SAM3U_UDPHS_CTRL (SAM3U_UDPHS_BASE+SAM3U_UDPHS_CTRL_OFFSET)
+#define SAM3U_UDPHS_FNUM (SAM3U_UDPHS_BASE+SAM3U_UDPHS_FNUM_OFFSET)
+#define SAM3U_UDPHS_IEN (SAM3U_UDPHS_BASE+SAM3U_UDPHS_IEN_OFFSET)
+#define SAM3U_UDPHS_INTSTA (SAM3U_UDPHS_BASE+SAM3U_UDPHS_INTSTA_OFFSET)
+#define SAM3U_UDPHS_CLRINT (SAM3U_UDPHS_BASE+ SAM3U_UDPHS_CLRINT_OFFSET)
+#define SAM3U_UDPHS_EPTRST (SAM3U_UDPHS_BASE+SAM3U_UDPHS_EPTRST_OFFSET)
+#define SAM3U_UDPHS_TST (SAM3U_UDPHS_BASE+SAM3U_UDPHS_TST_OFFSET)
+#define SAM3U_UDPHS_IPNAME1 (SAM3U_UDPHS_BASE+SAM3U_UDPHS_IPNAME1_OFFSET)
+#define SAM3U_UDPHS_IPNAME2 (SAM3U_UDPHS_BASE+SAM3U_UDPHS_IPNAME2_OFFSET)
+#define SAM3U_UDPHS_IPFEATURES (SAM3U_UDPHS_BASE+SAM3U_UDPHS_IPFEATURES_OFFSET)
+
+/* Endpoint registers */
+
+#define SAM3U_UDPHSEP_BASE(n)) (SAM3U_UDPHS_BASE+SAM3U_UDPHSEP_OFFSET(n))
+#define SAM3U_UDPHSEP_CFG(n) (SAM3U_UDPHSEP_BASE(n)+SAM3U_UDPHSEP_CFG_OFFSET)
+#define SAM3U_UDPHSEP_CTLENB(n) (SAM3U_UDPHSEP_BASE(n)+SAM3U_UDPHSEP_CTLENB_OFFSET)
+#define SAM3U_UDPHSEP_CTLDIS(n) (SAM3U_UDPHSEP_BASE(n)+SAM3U_UDPHSEP_CTLDIS_OFFSET)
+#define SAM3U_UDPHSEP_CTL(n) (SAM3U_UDPHSEP_BASE(n)+SAM3U_UDPHSEP_CTL_OFFSET)
+#define SAM3U_UDPHSEP_SETSTA(n) (SAM3U_UDPHSEP_BASE(n)+SAM3U_UDPHSEP_SETSTA_OFFSET)
+#define SAM3U_UDPHSEP_CLRSTA(n) (SAM3U_UDPHSEP_BASE(n)+SAM3U_UDPHSEP_CLRSTA_OFFSET)
+#define SAM3U_UDPHSEP_STA(n) (SAM3U_UDPHSEP_BASE(n)+SAM3U_UDPHSEP_STA_OFFSET)
+
+/* DMA Channel Registers*/
+
+#define SAM3U_UDPHSDMA_BASE(n) (SAM3U_UDPHS_BASE+SAM3U_UDPHSDMA_OFFSET(n))
+#define SAM3U_UDPHSDMA_NXTDSC(n) (SAM3U_UDPHSDMA_BASE(n)+SAM3U_UDPHSDMA_NXTDSC_OFFSET)
+#define SAM3U_UDPHSDMA_ADDRESS(n) (SAM3U_UDPHSDMA_BASE(n)+SAM3U_UDPHSDMA_ADDRESS_OFFSET)
+#define SAM3U_UDPHSDMA_CONTROL(n) (SAM3U_UDPHSDMA_BASE(n)+SAM3U_UDPHSDMA_CONTROL_OFFSET)
+#define SAM3U_UDPHSDMA_STATUS(n) (SAM3U_UDPHSDMA_BASE(n)+SAM3U_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_ISOEPT0 (1 << 26) /* Bit 26: EP10 High B/W Isoc Capability */
+#define UDPHS_IPFEATURES_ISOEPT1 (1 << 27) /* Bit 27: EP11 High B/W Isoc Capability */
+#define UDPHS_IPFEATURES_ISOEPT2 (1 << 28) /* Bit 28: EP12 High B/W Isoc Capability */
+#define UDPHS_IPFEATURES_ISOEPT3 (1 << 29) /* Bit 29: EP13 High B/W Isoc Capability */
+#define UDPHS_IPFEATURES_ISOEPT4 (1 << 30) /* Bit 30: EP14 High B/W Isoc Capability */
+#define UDPHS_IPFEATURES_ISOEPT5 (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_16b (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_SAM3U_SAM3U_UDPHS_H */
+
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_userspace.c b/nuttx/arch/arm/src/sam3u/sam3u_userspace.c
new file mode 100644
index 000000000..e59cc5619
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_userspace.c
@@ -0,0 +1,105 @@
+/****************************************************************************
+ * arch/arm/src/common/sam3u_userspace.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <arch/board/user_map.h>
+
+#ifdef CONFIG_NUTTX_KERNEL
+
+/****************************************************************************
+ * Private Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam3u_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
+ * segements.
+ *
+ ****************************************************************************/
+
+void sam3u_userspace(void)
+{
+ uint8_t *src;
+ uint8_t *dest;
+ uint8_t *end;
+
+ /* Clear all of user-space .bss */
+
+ DEBUGASSERT((uintptr_t)CONFIG_USER_DATADESTSTART <= CONFIG_USER_DATADESTEND);
+
+ dest = (uint8_t*)CONFIG_USER_BSSSTART;
+ end = (uint8_t*)CONFIG_USER_BSSEND;
+
+ while (dest != end)
+ {
+ *dest++ = 0;
+ }
+
+ /* Initialize all of user-space .data */
+
+ DEBUGASSERT((uintptr_t)CONFIG_USER_DATADESTSTART <= CONFIG_USER_DATADESTEND);
+
+ src = (uint8_t*)CONFIG_USER_DATASOURCE;
+ dest = (uint8_t*)CONFIG_USER_DATADESTSTART;
+ end = (uint8_t*)CONFIG_USER_DATADESTEND;
+
+ while (dest != end)
+ {
+ *dest++ = *src++;
+ }
+}
+
+#endif /* CONFIG_NUTTX_KERNEL */
+
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_vectors.S b/nuttx/arch/arm/src/sam3u/sam3u_vectors.S
new file mode 100644
index 000000000..3ed17f767
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_vectors.S
@@ -0,0 +1,385 @@
+/************************************************************************************************
+ * arch/arm/src/sam3u/sam3u_vectors.S
+ * arch/arm/src/chip/sam3u_vectors.S
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <arch/irq.h>
+
+/************************************************************************************************
+ * Preprocessor Definitions
+ ************************************************************************************************/
+
+/* 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)
+#define HEAP_BASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE)
+
+/* The Cortex-M3 return from interrupt is unusual. We provide the following special
+ * address to the BX instruction. The particular value also forces a return to
+ * thread mode and covers state from the main stack point, the MSP (vs. the MSP).
+ */
+
+#define EXC_RETURN 0xfffffff9
+
+/************************************************************************************************
+ * Global Symbols
+ ************************************************************************************************/
+
+ .globl __start
+
+ .syntax unified
+ .thumb
+ .file "sam3u_vectors.S"
+
+/************************************************************************************************
+ * 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 sam3u_common
+ .endm
+
+/************************************************************************************************
+ * Vectors
+ ************************************************************************************************/
+
+ .section .vectors, "ax"
+ .code 16
+ .align 2
+ .globl sam3u_vectors
+ .type sam3u_vectors, function
+
+sam3u_vectors:
+
+/* Processor Exceptions */
+
+ .word IDLE_STACK /* Vector 0: Reset stack pointer */
+ .word __start /* Vector 1: Reset vector */
+ .word sam3u_nmi /* Vector 2: Non-Maskable Interrupt (NMI) */
+ .word sam3u_hardfault /* Vector 3: Hard fault */
+ .word sam3u_mpu /* Vector 4: Memory management (MPU) */
+ .word sam3u_busfault /* Vector 5: Bus fault */
+ .word sam3u_usagefault /* Vector 6: Usage fault */
+ .word sam3u_reserved /* Vector 7: Reserved */
+ .word sam3u_reserved /* Vector 8: Reserved */
+ .word sam3u_reserved /* Vector 9: Reserved */
+ .word sam3u_reserved /* Vector 10: Reserved */
+ .word sam3u_svcall /* Vector 11: SVC call */
+ .word sam3u_dbgmonitor /* Vector 12: Debug monitor */
+ .word sam3u_reserved /* Vector 13: Reserved */
+ .word sam3u_pendsv /* Vector 14: Pendable system service request */
+ .word sam3u_systick /* Vector 15: System tick */
+
+/* External Interrupts */
+
+ .word sam3u_supc /* Vector 16+0: Supply Controller */
+ .word sam3u_rstc /* Vector 16+1: Reset Controller */
+ .word sam3u_rtc /* Vector 16+2: Real Time Clock */
+ .word sam3u_rtt /* Vector 16+3: Real Time Timer */
+ .word sam3u_wdt /* Vector 16+4: Watchdog Timer */
+ .word sam3u_pmc /* Vector 16+5: Power Management Controller */
+ .word sam3u_eefc0 /* Vector 16+6: Enhanced Embedded Flash Controller 0 */
+ .word sam3u_eefc1 /* Vector 16+7: Enhanced Embedded Flash Controller 1 */
+ .word sam3u_uart /* Vector 16+8: Universal Asynchronous Receiver Transmitter */
+ .word sam3u_smc /* Vector 16+9: Static Memory Controller */
+ .word sam3u_pioa /* Vector 16+10: Parallel I/O Controller A */
+ .word sam3u_piob /* Vector 16+11: Parallel I/O Controller B */
+ .word sam3u_pioc /* Vector 16+12: Parallel I/O Controller C */
+ .word sam3u_usart0 /* Vector 16+13: USART 0 */
+ .word sam3u_usart1 /* Vector 16+14: USART 1 */
+ .word sam3u_usart2 /* Vector 16+15: USART 2 */
+ .word sam3u_usart3 /* Vector 16+16: USART 3 */
+ .word sam3u_hsmci /* Vector 16+17: High Speed Multimedia Card Interface */
+ .word sam3u_twi0 /* Vector 16+18: Two-Wire Interface 0 */
+ .word sam3u_twi1 /* Vector 16+19: Two-Wire Interface 1 */
+ .word sam3u_spi /* Vector 16+20: Serial Peripheral Interface */
+ .word sam3u_ssc /* Vector 16+21: Synchronous Serial Controller */
+ .word sam3u_tc0 /* Vector 16+22: Timer Counter 0 */
+ .word sam3u_tc1 /* Vector 16+23: Timer Counter 1 */
+ .word sam3u_tc2 /* Vector 16+24: Timer Counter 2 */
+ .word sam3u_pwm /* Vector 16+25: Pulse Width Modulation Controller */
+ .word sam3u_adc12b /* Vector 16+26: 12-bit ADC Controller */
+ .word sam3u_adc /* Vector 16+27: 10-bit ADC Controller */
+ .word sam3u_dmac /* Vector 16+28: DMA Controller */
+ .word sam3u_udphs /* Vector 16+29: USB Device High Speed */
+ .size sam3u_vectors, .-sam3u_vectors
+
+/************************************************************************************************
+ * .text
+ ************************************************************************************************/
+
+ .text
+ .type handlers, function
+ .thumb_func
+handlers:
+ HANDLER sam3u_reserved, SAM3U_IRQ_RESERVED /* Unexpected/reserved vector */
+ HANDLER sam3u_nmi, SAM3U_IRQ_NMI /* Vector 2: Non-Maskable Interrupt (NMI) */
+ HANDLER sam3u_hardfault, SAM3U_IRQ_HARDFAULT /* Vector 3: Hard fault */
+ HANDLER sam3u_mpu, SAM3U_IRQ_MEMFAULT /* Vector 4: Memory management (MPU) */
+ HANDLER sam3u_busfault, SAM3U_IRQ_BUSFAULT /* Vector 5: Bus fault */
+ HANDLER sam3u_usagefault, SAM3U_IRQ_USAGEFAULT /* Vector 6: Usage fault */
+ HANDLER sam3u_svcall, SAM3U_IRQ_SVCALL /* Vector 11: SVC call */
+ HANDLER sam3u_dbgmonitor, SAM3U_IRQ_DBGMONITOR /* Vector 12: Debug Monitor */
+ HANDLER sam3u_pendsv, SAM3U_IRQ_PENDSV /* Vector 14: Penable system service request */
+ HANDLER sam3u_systick, SAM3U_IRQ_SYSTICK /* Vector 15: System tick */
+
+ HANDLER sam3u_supc, SAM3U_IRQ_SUPC /* Vector 16+0: Supply Controller */
+ HANDLER sam3u_rstc, SAM3U_IRQ_RSTC /* Vector 16+1: Reset Controller */
+ HANDLER sam3u_rtc, SAM3U_IRQ_RTC /* Vector 16+2: Real Time Clock */
+ HANDLER sam3u_rtt, SAM3U_IRQ_RTT /* Vector 16+3: Real Time Timer */
+ HANDLER sam3u_wdt, SAM3U_IRQ_WDT /* Vector 16+4: Watchdog Timer */
+ HANDLER sam3u_pmc, SAM3U_IRQ_PMC /* Vector 16+5: Power Management Controller */
+ HANDLER sam3u_eefc0, SAM3U_IRQ_EEFC0 /* Vector 16+6: Enhanced Embedded Flash Controller 0 */
+ HANDLER sam3u_eefc1, SAM3U_IRQ_EEFC1 /* Vector 16+7: Enhanced Embedded Flash Controller 1 */
+ HANDLER sam3u_uart, SAM3U_IRQ_UART /* Vector 16+8: Universal Asynchronous Receiver Transmitter */
+ HANDLER sam3u_smc, SAM3U_IRQ_SMC /* Vector 16+9: Static Memory Controller */
+ HANDLER sam3u_pioa, SAM3U_IRQ_PIOA /* Vector 16+10: Parallel I/O Controller A */
+ HANDLER sam3u_piob, SAM3U_IRQ_PIOB /* Vector 16+11: Parallel I/O Controller B */
+ HANDLER sam3u_pioc, SAM3U_IRQ_PIOC /* Vector 16+12: Parallel I/O Controller C */
+ HANDLER sam3u_usart0, SAM3U_IRQ_USART0 /* Vector 16+13: USART 0 */
+ HANDLER sam3u_usart1, SAM3U_IRQ_USART1 /* Vector 16+14: USART 1 */
+ HANDLER sam3u_usart2, SAM3U_IRQ_USART2 /* Vector 16+15: USART 2 */
+ HANDLER sam3u_usart3, SAM3U_IRQ_USART3 /* Vector 16+16: USART 3 */
+ HANDLER sam3u_hsmci, SAM3U_IRQ_HSMCI /* Vector 16+17: High Speed Multimedia Card Interface */
+ HANDLER sam3u_twi0, SAM3U_IRQ_TWI0 /* Vector 16+18: Two-Wire Interface 0 */
+ HANDLER sam3u_twi1, SAM3U_IRQ_TWI1 /* Vector 16+19: Two-Wire Interface 1 */
+ HANDLER sam3u_spi, SAM3U_IRQ_SPI /* Vector 16+20: Serial Peripheral Interface */
+ HANDLER sam3u_ssc, SAM3U_IRQ_SSC /* Vector 16+21: Synchronous Serial Controller */
+ HANDLER sam3u_tc0, SAM3U_IRQ_TC0 /* Vector 16+22: Timer Counter 0 */
+ HANDLER sam3u_tc1, SAM3U_IRQ_TC1 /* Vector 16+23: Timer Counter 1 */
+ HANDLER sam3u_tc2, SAM3U_IRQ_TC2 /* Vector 16+24: Timer Counter 2 */
+ HANDLER sam3u_pwm, SAM3U_IRQ_PWM /* Vector 16+25: Pulse Width Modulation Controller */
+ HANDLER sam3u_adc12b, SAM3U_IRQ_ADC12B /* Vector 16+26: 12-bit ADC Controller */
+ HANDLER sam3u_adc, SAM3U_IRQ_ADC /* Vector 16+27: 10-bit ADC Controller */
+ HANDLER sam3u_dmac, SAM3U_IRQ_DMAC /* Vector 16+28: DMA Controller */
+ HANDLER sam3u_udphs, SAM3U_IRQ_UDPHS /* Vector 16+29: USB Device High Speed */
+
+/* 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
+ */
+
+sam3u_common:
+
+ /* Complete the context save */
+
+#ifdef CONFIG_NUTTX_KERNEL
+ /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
+ * (handler mode) if the state is on the MSP. It can only be on the PSP if
+ * EXC_RETURN is 0xfffffffd (unprivileged thread)
+ */
+
+ adds r2, r14, #3 /* If R14=0xfffffffd, then r2 == 0 */
+ ite ne /* Next two instructions are condition */
+ mrsne r1, msp /* R1=The main stack pointer */
+ mrseq r1, psp /* R1=The process stack pointer */
+#else
+ mrs r1, msp /* R1=The main stack pointer */
+#endif
+
+ mov r2, r1 /* R2=Copy of the main/process stack pointer */
+ add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
+ mrs r3, primask /* R3=Current PRIMASK setting */
+#ifdef CONFIG_NUTTX_KERNEL
+ stmdb r1!, {r2-r11,r14} /* Save the remaining registers plus the SP value */
+#else
+ stmdb r1!, {r2-r11} /* Save the remaining registers plus the SP value */
+#endif
+
+ /* 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 re-use the main stack for interrupt level processing.
+ */
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ ldr sp, =g_intstackbase
+ str r1, [sp, #-4]! /* Save the MSP on the interrupt stack */
+ bl up_doirq /* R0=IRQ, R1=register save (msp) */
+ ldr r1, [sp, #+4]! /* Recover R1=main stack pointer */
+#else
+ mov sp, r1 /* We are using the main stack pointer */
+ bl up_doirq /* R0=IRQ, R1=register save (msp) */
+ mov r1, sp /* 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 1f /* 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, are 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_NUTTX_KERNEL
+ 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 2f /* Re-join common logic */
+
+ /* We are returning with no context switch. We simply need to "unwind"
+ * the same stack frame that we created
+ */
+1:
+#ifdef CONFIG_NUTTX_KERNEL
+ ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
+#else
+ ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */
+#endif
+2:
+#ifdef CONFIG_NUTTX_KERNEL
+ /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
+ * (handler mode) if the state is on the MSP. It can only be on the PSP if
+ * EXC_RETURN is 0xfffffffd (unprivileged thread)
+ */
+
+ adds r0, r14, #3 /* If R14=0xfffffffd, then r0 == 0 */
+ ite ne /* Next two instructions are condition */
+ msrne msp, r1 /* R1=The main stack pointer */
+ msreq psp, r1 /* R1=The process stack pointer */
+#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 /* Load the special value */
+#endif
+
+ /* Restore the interrupt state */
+
+ msr primask, r3 /* Restore interrupts */
+
+ /* 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: up_interruptstack/g_intstackbase
+ *
+ * Description:
+ * Shouldn't happen
+ *
+ ************************************************************************************************/
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ .bss
+ .global g_intstackbase
+ .align 4
+up_interruptstack:
+ .skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
+g_intstackbase:
+ .size up_interruptstack, .-up_interruptstack
+#endif
+
+/************************************************************************************************
+ * .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_heapbase below.
+ */
+
+ .globl g_heapbase
+ .type g_heapbase, object
+g_heapbase:
+ .word HEAP_BASE
+ .size g_heapbase, .-g_heapbase
+
+ .end
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_wdt.h b/nuttx/arch/arm/src/sam3u/sam3u_wdt.h
new file mode 100644
index 000000000..50b16d2a8
--- /dev/null
+++ b/nuttx/arch/arm/src/sam3u/sam3u_wdt.h
@@ -0,0 +1,96 @@
+/****************************************************************************************
+ * arch/arm/src/sam3u/sam3u_wdt.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM3U_SAM3U_WDT_H
+#define __ARCH_ARM_SRC_SAM3U_SAM3U_WDT_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "sam3u_memorymap.h"
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* WDT register offsets ****************************************************************/
+
+#define SAM3U_WDT_CR_OFFSET 0x00 /* Control Register */
+#define SAM3U_WDT_MR_OFFSET 0x04 /* Mode Register */
+#define SAM3U_WDT_SR_OFFSET 0x08 /* Status Register */
+
+/* WDT register adresses ***************************************************************/
+
+#define SAM3U_WDT_CR (SAM3U_WDT_BASE+SAM3U_WDT_CR_OFFSET)
+#define SAM3U_WDT_MR (SAM3U_WDT_BASE+SAM3U_WDT_MR_OFFSET)
+#define SAM3U_WDT_SR (SAM3U_WDT_BASE+SAM3U_WDT_SR_OFFSET)
+
+/* WDT register bit definitions ********************************************************/
+
+#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_MR_WDV_SHIFT (0) /* Bits 0-11: Watchdog Counter Value */
+#define WDT_MR_WDV_MASK (0xfff << 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-17: Watchdog Delta Value */
+#define WDT_MR_WDD_MASK (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 */
+
+#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_SAM3U_SAM3U_WDT_H */
diff --git a/nuttx/arch/arm/src/stm32/Kconfig b/nuttx/arch/arm/src/stm32/Kconfig
new file mode 100644
index 000000000..b5d0306da
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/Kconfig
@@ -0,0 +1,1838 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+comment "STM32 Configuration Options"
+
+choice
+ prompt "STM32 Chip Selection"
+ default ARCH_CHIP_STM32F103ZET6
+ depends on ARCH_CHIP_STM32
+
+config ARCH_CHIP_STM32F100C8
+ bool "STM32F100C8"
+ select ARCH_CORTEXM3
+ select STM32_STM32F10XX
+ select STM32_VALUELINE
+
+config ARCH_CHIP_STM32F100CB
+ bool "STM32F100CB"
+ select ARCH_CORTEXM3
+ select STM32_STM32F10XX
+ select STM32_VALUELINE
+
+config ARCH_CHIP_STM32F100R8
+ bool "STM32F100R8"
+ select ARCH_CORTEXM3
+ select STM32_STM32F10XX
+ select STM32_VALUELINE
+
+config ARCH_CHIP_STM32F100RB
+ bool "STM32F100RB"
+ select ARCH_CORTEXM3
+ select STM32_STM32F10XX
+ select STM32_VALUELINE
+
+config ARCH_CHIP_STM32F100V8
+ bool "STM32F100V8"
+ select ARCH_CORTEXM3
+ select STM32_STM32F10XX
+ select STM32_VALUELINE
+
+config ARCH_CHIP_STM32F100VB
+ bool "STM32F100VB"
+ select ARCH_CORTEXM3
+ select STM32_STM32F10XX
+ select STM32_VALUELINE
+
+config ARCH_CHIP_STM32F103RET6
+ bool "STM32F103RET6"
+ select ARCH_CORTEXM3
+ select STM32_STM32F10XX
+ select STM32_HIGHDENSITY
+
+config ARCH_CHIP_STM32F103VCT6
+ bool "STM32F103VCT6"
+ select ARCH_CORTEXM3
+ select STM32_STM32F10XX
+ select STM32_HIGHDENSITY
+
+config ARCH_CHIP_STM32F103VET6
+ bool "STM32F103VET6"
+ select ARCH_CORTEXM3
+ select STM32_STM32F10XX
+ select STM32_HIGHDENSITY
+
+config ARCH_CHIP_STM32F103ZET6
+ bool "STM32F103ZET6"
+ select ARCH_CORTEXM3
+ select STM32_STM32F10XX
+
+config ARCH_CHIP_STM32F105VBT7
+ bool "STM32F105VBT7"
+ select ARCH_CORTEXM3
+ select STM32_STM32F10XX
+ select STM32_CONNECTIVITYLINE
+
+config ARCH_CHIP_STM32F107VC
+ bool "STM32F107VC"
+ select ARCH_CORTEXM3
+ select STM32_STM32F10XX
+ select STM32_CONNECTIVITYLINE
+
+config ARCH_CHIP_STM32F207IG
+ bool "STM32F207IG"
+ select ARCH_CORTEXM3
+ select STM32_STM32F20XX
+
+config ARCH_CHIP_STM32F405RG
+ bool "STM32F405RG"
+ select ARCH_CORTEXM4
+ select STM32_STM32F40XX
+
+config ARCH_CHIP_STM32F405VG
+ bool "STM32F405VG"
+ select ARCH_CORTEXM4
+ select STM32_STM32F40XX
+
+config ARCH_CHIP_STM32F405ZG
+ bool "STM32F405ZG"
+ select ARCH_CORTEXM4
+ select STM32_STM32F40XX
+
+config ARCH_CHIP_STM32F407VE
+ bool "STM32F407VE"
+ select ARCH_CORTEXM4
+ select STM32_STM32F40XX
+
+config ARCH_CHIP_STM32F407VG
+ bool "STM32F407VG"
+ select ARCH_CORTEXM3
+ select STM32_STM32F40XX
+
+config ARCH_CHIP_STM32F407ZE
+ bool "STM32F407ZE"
+ select ARCH_CORTEXM4
+ select STM32_STM32F40XX
+
+config ARCH_CHIP_STM32F407ZG
+ bool "STM32F407ZG"
+ select ARCH_CORTEXM4
+ select STM32_STM32F40XX
+
+config ARCH_CHIP_STM32F407IE
+ bool "STM32F407IE"
+ select ARCH_CORTEXM4
+ select STM32_STM32F40XX
+
+config ARCH_CHIP_STM32F407IG
+ bool "STM32F407IG"
+ select ARCH_CORTEXM4
+ select STM32_STM32F40XX
+
+endchoice
+
+config STM32_STM32F10XX
+ bool
+
+config STM32_VALUELINE
+ bool
+
+config STM32_HIGHDENSITY
+ bool
+
+config STM32_CONNECTIVITYLINE
+ bool
+
+config STM32_STM32F20XX
+ bool
+
+config STM32_STM32F40XX
+ bool
+
+choice
+ prompt "Toolchain Selection"
+ default STM32_CODESOURCERYW
+ depends on ARCH_CHIP_STM32
+
+config STM32_CODESOURCERYW
+ bool "CodeSourcery for Windows"
+
+config STM32_CODESOURCERYL
+ bool "CodeSourcery for Linux"
+
+config STM32_ATOLLIC_LITE
+ bool "Atollic Lite for Windows"
+
+config STM32_ATOLLIC_PRO
+ bool "Atollic Pro for Windows"
+
+config STM32_DEVKITARM
+ bool "DevkitARM (Windows)"
+
+config STM32_RAISONANCE
+ bool "STMicro Raisonance for Windows"
+
+config STM32_BUILDROOT
+ bool "NuttX buildroot (Cygwin or Linux)"
+
+endchoice
+
+config STM32_DFU
+ bool "DFU bootloader"
+ default n
+ ---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"
+
+config STM32_ADC1
+ bool "ADC1"
+ default n
+
+config STM32_ADC2
+ bool "ADC2"
+ default n
+
+config STM32_ADC3
+ bool "ADC3"
+ default n
+
+config STM32_CRC
+ bool "CRC"
+ default n
+
+config STM32_DMA1
+ bool "DMA1"
+ default n
+ select ARCH_DMA
+
+config STM32_DMA2
+ bool "DMA2"
+ default n
+ select ARCH_DMA
+
+config STM32_BKP
+ bool "BKP"
+ default n
+ depends on STM32_STM32F10XX
+
+config STM32_BKPSRAM
+ bool "BKP RAM"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_CAN1
+ bool "CAN1"
+ default n
+ select CAN
+
+config STM32_CAN2
+ bool "CAN2"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+ select CAN
+
+config STM32_CCMDATARAM
+ bool "CMD/DATA RAM"
+ default n
+ depends on STM32_STM32F40XX
+
+config STM32_CRYP
+ bool "CRYP"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_DAC1
+ bool "DAC1"
+ default n
+
+config STM32_DAC2
+ bool "DAC2"
+ default n
+
+config STM32_DCMI
+ bool "DCMI"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_ETHMAC
+ bool "Ethernet MAC"
+ default n
+ depends on STM32_CONNECTIVITYLINE || STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_FSMC
+ bool "FSMC"
+ default n
+ depends on !STM32_CONNECTIVITYLINE
+
+config STM32_HASH
+ bool "HASH"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_I2C1
+ bool "I2C1"
+ default n
+
+config STM32_I2C2
+ bool "I2C2"
+ default n
+
+config STM32_I2C3
+ bool "I2C3"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_IWDG
+ bool "IWDG"
+ default n
+ select WATCHDOG
+
+config STM32_OTGFS
+ bool "OTG FS"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_OTGHS
+ bool "OTG HS"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_PWR
+ bool "PWR"
+ default n
+
+config STM32_RNG
+ bool "RNG"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_SDIO
+ bool "SDIO"
+ default n
+ depends on !STM32_CONNECTIVITYLINE
+
+config STM32_SPI1
+ bool "SPI1"
+ default n
+ select SPI
+
+config STM32_SPI2
+ bool "SPI2"
+ default n
+ select SPI
+
+config STM32_SPI3
+ bool "SPI3"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+ select SPI
+
+config STM32_SPI4
+ bool "SPI4"
+ default n
+ depends on STM32_STM32F10XX
+ select SPI
+
+config STM32_SYSCFG
+ bool "SYSCFG"
+ default y
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_TIM1
+ bool "TIM1"
+ default n
+
+config STM32_TIM2
+ bool "TIM2"
+ default n
+
+config STM32_TIM3
+ bool "TIM3"
+ default n
+
+config STM32_TIM4
+ bool "TIM4"
+ default n
+
+config STM32_TIM5
+ bool "TIM5"
+ default n
+
+config STM32_TIM6
+ bool "TIM6"
+ default n
+
+config STM32_TIM7
+ bool "TIM7"
+ default n
+
+config STM32_TIM8
+ bool "TIM8"
+ default n
+
+config STM32_TIM9
+ bool "TIM9"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_TIM10
+ bool "TIM10"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_TIM11
+ bool "TIM11"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_TIM12
+ bool "TIM12"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_TIM13
+ bool "TIM13"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_TIM14
+ bool "TIM14"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+
+config STM32_USART1
+ bool "USART1"
+ default n
+ select ARCH_HAVE_USART1
+
+config STM32_USART2
+ bool "USART2"
+ default n
+ select ARCH_HAVE_USART2
+
+config STM32_USART3
+ bool "USART3"
+ default n
+ select ARCH_HAVE_USART3
+
+config STM32_UART4
+ bool "UART4"
+ default n
+ select ARCH_HAVE_UART4
+
+config STM32_UART5
+ bool "UART5"
+ default n
+ select ARCH_HAVE_UART5
+
+config STM32_USART6
+ bool "USART6"
+ default n
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+ select ARCH_HAVE_USART6
+
+config STM32_USB
+ bool "USB Device"
+ default n
+ depends on STM32_STM32F10XX
+ select USBDEV
+
+config STM32_WWDG
+ bool "WWDG"
+ default n
+ select WATCHDOG
+
+endmenu
+
+config STM32_ADC
+ bool
+ default y if STM32_ADC1 || STM32_ADC2 || STM32_ADC3
+
+config STM32_DAC
+ bool
+ default y if STM32_DAC1 || STM32_ADC2
+
+config STM32_SPI
+ bool
+ default y if STM32_SPI1 || STM32_SPI2 || STM32_SPI3 || STM32_SPI4
+
+config STM32_CAN
+ bool
+ default y if STM32_CAN1 || STM32_CAN2
+
+menu "Alternate Pin Mapping"
+
+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_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
+
+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
+
+config STM32_I2C1_REMAP
+ bool "I2C1 Alternate Pin Mapping"
+ default n
+ depends on STM32_STM32F10XX && STM32_I2C1
+
+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 CONFIG_STM32_CAN1_REMAP1
+ bool "CAN1 alternate pin remapping #1"
+
+config 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_ETH_REMAP
+ bool "Ethernet Alternate Pin Mapping"
+ default n
+ depends on STM32_CONNECTIVITYLINE && STM32_ETHMAC
+
+endmenu
+
+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_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_CCMEXCLUDE
+ bool "Exclude CCM SRAM from the heap"
+ depends on STM32_STM32F20XX || STM32_STM32F40XX
+ default y if ARCH_DMA
+ ---help---
+ Exclude CCM SRAM from the HEAP because it cannot be used for DMA.
+
+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
+ ---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.
+
+config STM32_TIM1_CHANNEL
+ int "TIM1 PWM Output Channel"
+ default 1
+ depends on STM32_TIM1_PWM
+ ---help---
+ If TIM1 is enabled for PWM usage, you also need specifies the timer output
+ channel {1,..,4}
+
+config STM32_TIM2_PWM
+ bool "TIM2 PWM"
+ default n
+ depends on STM32_TIM2
+ ---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_TIM2
+ is defined then THIS following may also be defined to indicate that
+ the timer is intended to be used for pulsed output modulation.
+
+config STM32_TIM2_CHANNEL
+ int "TIM2 PWM Output Channel"
+ default 1
+ depends on STM32_TIM2_PWM
+ ---help---
+ If TIM2 is enabled for PWM usage, you also need specifies the timer output
+ channel {1,..,4}
+
+config STM32_TIM3_PWM
+ bool "TIM3 PWM"
+ default n
+ depends on STM32_TIM3
+ ---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_TIM3
+ is defined then THIS following may also be defined to indicate that
+ the timer is intended to be used for pulsed output modulation.
+
+config STM32_TIM3_CHANNEL
+ int "TIM3 PWM Output Channel"
+ default 1
+ depends on STM32_TIM3_PWM
+ ---help---
+ If TIM3 is enabled for PWM usage, you also need specifies the timer output
+ channel {1,..,4}
+
+config STM32_TIM4_PWM
+ bool "TIM4 PWM"
+ default n
+ depends on STM32_TIM4
+ ---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_TIM4
+ is defined then THIS following may also be defined to indicate that
+ the timer is intended to be used for pulsed output modulation.
+
+config STM32_TIM4_CHANNEL
+ int "TIM4 PWM Output Channel"
+ default 1
+ depends on STM32_TIM4_PWM
+ ---help---
+ If TIM4 is enabled for PWM usage, you also need specifies the timer output
+ channel {1,..,4}
+
+config STM32_TIM5_PWM
+ bool "TIM5 PWM"
+ default n
+ depends on STM32_TIM5
+ ---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_TIM5
+ is defined then THIS following may also be defined to indicate that
+ the timer is intended to be used for pulsed output modulation.
+
+config STM32_TIM5_CHANNEL
+ int "TIM5 PWM Output Channel"
+ default 1
+ depends on STM32_TIM5_PWM
+ ---help---
+ If TIM5 is enabled for PWM usage, you also need specifies the timer output
+ channel {1,..,4}
+
+config STM32_TIM8_PWM
+ bool "TIM8 PWM"
+ default n
+ depends on STM32_TIM8
+ ---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_TIM8
+ is defined then THIS following may also be defined to indicate that
+ the timer is intended to be used for pulsed output modulation.
+
+config STM32_TIM8_CHANNEL
+ int "TIM8 PWM Output Channel"
+ default 1
+ depends on STM32_TIM8_PWM
+ ---help---
+ If TIM8 is enabled for PWM usage, you also need specifies the timer output
+ channel {1,..,4}
+
+config STM32_TIM9_PWM
+ bool "TIM9 PWM"
+ default n
+ depends on STM32_TIM9
+ ---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_TIM9
+ is defined then THIS following may also be defined to indicate that
+ the timer is intended to be used for pulsed output modulation.
+
+config STM32_TIM9_CHANNEL
+ int "TIM9 PWM Output Channel"
+ default 1
+ depends on STM32_TIM9_PWM
+ ---help---
+ If TIM9 is enabled for PWM usage, you also need specifies the timer output
+ channel {1,..,4}
+
+config STM32_TIM10_PWM
+ bool "TIM10 PWM"
+ default n
+ depends on STM32_TIM10
+ ---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_TIM10
+ is defined then THIS following may also be defined to indicate that
+ the timer is intended to be used for pulsed output modulation.
+
+config STM32_TIM10_CHANNEL
+ int "TIM10 PWM Output Channel"
+ default 1
+ depends on STM32_TIM10_PWM
+ ---help---
+ If TIM10 is enabled for PWM usage, you also need specifies the timer output
+ channel {1,..,4}
+
+config STM32_TIM11_PWM
+ bool "TIM11 PWM"
+ default n
+ depends on STM32_TIM11
+ ---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_TIM11
+ is defined then THIS following may also be defined to indicate that
+ the timer is intended to be used for pulsed output modulation.
+
+config STM32_TIM11_CHANNEL
+ int "TIM11 PWM Output Channel"
+ default 1
+ depends on STM32_TIM11_PWM
+ ---help---
+ If TIM11 is enabled for PWM usage, you also need specifies the timer output
+ channel {1,..,4}
+
+config STM32_TIM12_PWM
+ bool "TIM12 PWM"
+ default n
+ depends on STM32_TIM12
+ ---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_TIM12
+ is defined then THIS following may also be defined to indicate that
+ the timer is intended to be used for pulsed output modulation.
+
+config STM32_TIM12_CHANNEL
+ int "TIM12 PWM Output Channel"
+ default 1
+ depends on STM32_TIM12_PWM
+ ---help---
+ If TIM12 is enabled for PWM usage, you also need specifies the timer output
+ channel {1,..,4}
+
+config STM32_TIM13_PWM
+ bool "TIM13 PWM"
+ default n
+ depends on STM32_TIM13
+ ---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_TIM13
+ is defined then THIS following may also be defined to indicate that
+ the timer is intended to be used for pulsed output modulation.
+
+config STM32_TIM13_CHANNEL
+ int "TIM13 PWM Output Channel"
+ default 1
+ depends on STM32_TIM13_PWM
+ ---help---
+ If TIM13 is enabled for PWM usage, you also need specifies the timer output
+ channel {1,..,4}
+
+config STM32_TIM14_PWM
+ bool "TIM14 PWM"
+ default n
+ depends on STM32_TIM14
+ ---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_TIM14
+ is defined then THIS following may also be defined to indicate that
+ the timer is intended to be used for pulsed output modulation.
+
+config STM32_TIM14_CHANNEL
+ int "TIM14 PWM Output Channel"
+ default 1
+ depends on STM32_TIM14_PWM
+ ---help---
+ If TIM14 is enabled for PWM usage, you also need specifies the timer output
+ channel {1,..,4}
+
+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"
+ ---help---
+ Reserve TIM1 to trigger ADC1
+
+config STM32_TIM1_ADC2
+ bool "TIM1 ADC channel 2"
+ ---help---
+ Reserve TIM1 to trigger ADC2
+
+config STM32_TIM1_ADC3
+ bool "TIM1 ADC channel 3"
+ ---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"
+ ---help---
+ Reserve TIM2 to trigger ADC1
+
+config STM32_TIM2_ADC2
+ bool "TIM2 ADC channel 2"
+ ---help---
+ Reserve TIM2 to trigger ADC2
+
+config STM32_TIM2_ADC3
+ bool "TIM2 ADC channel 3"
+ ---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"
+ ---help---
+ Reserve TIM3 to trigger ADC1
+
+config STM32_TIM3_ADC2
+ bool "TIM3 ADC channel 2"
+ ---help---
+ Reserve TIM3 to trigger ADC2
+
+config STM32_TIM3_ADC3
+ bool "TIM3 ADC channel 3"
+ ---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"
+ ---help---
+ Reserve TIM4 to trigger ADC1
+
+config STM32_TIM4_ADC2
+ bool "TIM4 ADC channel 2"
+ ---help---
+ Reserve TIM4 to trigger ADC2
+
+config STM32_TIM4_ADC3
+ bool "TIM4 ADC channel 3"
+ ---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"
+ ---help---
+ Reserve TIM5 to trigger ADC1
+
+config STM32_TIM5_ADC2
+ bool "TIM5 ADC channel 2"
+ ---help---
+ Reserve TIM5 to trigger ADC2
+
+config STM32_TIM5_ADC3
+ bool "TIM5 ADC channel 3"
+ ---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"
+ ---help---
+ Reserve TIM8 to trigger ADC1
+
+config STM32_TIM8_ADC2
+ bool "TIM8 ADC channel 2"
+ ---help---
+ Reserve TIM8 to trigger ADC2
+
+config STM32_TIM8_ADC3
+ bool "TIM8 ADC channel 3"
+ ---help---
+ Reserve TIM8 to trigger ADC3
+
+endchoice
+
+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 1 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 1 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 1 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 1 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 1 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 1 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 1 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 1 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 1 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 1 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 1 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 1 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 1 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 USART1_RXDMA
+ bool "USART1 Rx DMA"
+ default n
+ depends on STM32_STM32F40XX && STM32_DMA2
+ ---help---
+ In high data rate usage, Rx DMA may eliminate Rx overrun errors
+
+config USART2_RXDMA
+ bool "USART2 Rx DMA"
+ default n
+ depends on STM32_STM32F40XX && STM32_DMA1
+ ---help---
+ In high data rate usage, Rx DMA may eliminate Rx overrun errors
+
+config USART3_RXDMA
+ bool "USART3 Rx DMA"
+ default n
+ depends on STM32_STM32F40XX && STM32_DMA1
+ ---help---
+ In high data rate usage, Rx DMA may eliminate Rx overrun errors
+
+config UART4_RXDMA
+ bool "UART4 Rx DMA"
+ default n
+ depends on STM32_STM32F40XX && STM32_DMA1
+ ---help---
+ In high data rate usage, Rx DMA may eliminate Rx overrun errors
+
+config UART5_RXDMA
+ bool "UART5 Rx DMA"
+ default n
+ depends on STM32_STM32F40XX && STM32_DMA1
+ ---help---
+ In high data rate usage, Rx DMA may eliminate Rx overrun errors
+
+config USART6_RXDMA
+ bool "USART6 Rx DMA"
+ default n
+ depends on STM32_STM32F40XX && STM32_DMA2
+ ---help---
+ In high data rate usage, Rx DMA may eliminate Rx overrun errors
+
+config SERIAL_TERMIOS
+ bool "Serial driver TERMIOS supported"
+ depends on STM32_USART1 || STM32_USART2 || STM32_USART3 || STM32_UART4 || STM32_UART5 || STM32_USART6
+ 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..
+
+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 "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
+ ---help---
+ Select SDIO interrupt prority. Default: 128.
+
+config SDIO_DMAPRIO
+ hex "SDIO DMA priority"
+ default 0x00001000
+ ---help---
+ Select SDIO DMA prority. Options: 0x00000000 low, 0x00001000 medium,
+ 0x00002000 high, 0x00003000 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
+
+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_MII
+ bool "Use MII interface"
+ default n
+ depends on STM32_ETHMAC
+ ---help---
+ Support Ethernet MII interface.
+
+choice
+ prompt "MII clock configuration"
+ default STM32_MII_MCO if STM32_STM32F10XX
+ default STM32_MII_MCO1 if STM32_STM32F20XX || 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_STM32F20XX || 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_STM32F20XX || 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 autonegtiation"
+ default y
+ depends on STM32_ETHMAC
+ ---help---
+ Use PHY autonegotion to determine speed and mode
+
+config STM32_ETHFD
+ bool "Full duplex"
+ default n
+ depends on STM32_ETHMAC && !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_ETHMAC && !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
+ hex "PHY status register address"
+ 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_SPEED
+ hex "PHY speed mask"
+ depends on STM32_AUTONEG
+ ---help---
+ This must be provided if STM32_AUTONEG is defined. This provides bit mask
+ indicating 10 or 100MBps speed.
+
+config STM32_PHYSR_100MBPS
+ hex "PHY 100Mbps speed value"
+ depends on STM32_AUTONEG
+ ---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
+ ---help---
+ This must be provided if STM32_AUTONEG is defined. This provide bit mask
+ indicating full or half duplex modes.
+
+config STM32_PHYSR_FULLDUPLEX
+ hex "PHY full duplex mode value"
+ depends on STM32_AUTONEG
+ ---help---
+ This must be provided if STM32_AUTONEG is defined. This provides the
+ value of the mode bits indicating full duplex mode.
+
+config STM32_ETH_PTP
+ bool "Precision Time Protocol (PTP)"
+ default n
+ depends on STM32_ETHMAC
+ ---help---
+ Precision Time Protocol (PTP). Not supported but some hooks are indicated
+ with this condition.
+
+endmenu
+
+config STM32_RMII
+ bool
+ default y if !STM32_MII
+ depends on STM32_ETHMAC
+
+choice
+ prompt "RMII clock configuration"
+ default STM32_RMII_MCO if STM32_STM32F10XX
+ default STM32_RMII_MCO1 if STM32_STM32F20XX || 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_STM32F20XX || 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_STM32F20XX || 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
+
+menu "USB 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?
+
+config STM32_USBHOST_REGDEBUG
+ bool "Register-Level Debug"
+ default n
+ depends on USBHOST && STM32_OTGFS
+ ---help---
+ Enable very low-level register access debug. Depends on CONFIG_DEBUG.
+
+config STM32_USBHOST_PKTDUMP
+ bool "Packet Dump Debug"
+ default n
+ depends on USBHOST && STM32_OTGFS
+ ---help---
+ Dump all incoming and outgoing USB packets. Depends on CONFIG_DEBUG.
+
+endmenu
diff --git a/nuttx/arch/arm/src/stm32/Make.defs b/nuttx/arch/arm/src/stm32/Make.defs
new file mode 100644
index 000000000..24af16c95
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/Make.defs
@@ -0,0 +1,144 @@
+############################################################################
+# arch/arm/src/stm32/Make.defs
+#
+# Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (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_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
+CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.c \
+ up_createstack.c up_mdelay.c up_udelay.c up_exit.c \
+ up_initialize.c up_initialstate.c up_interruptcontext.c \
+ up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c \
+ up_releasepending.c up_releasestack.c up_reprioritizertr.c \
+ up_schedulesigaction.c up_sigdeliver.c up_unblocktask.c \
+ up_usestack.c up_doirq.c up_hardfault.c up_svcall.c
+
+ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
+CMN_ASRCS += up_exception.S
+CMN_CSRCS += up_vectors.c
+endif
+
+ifeq ($(CONFIG_DEBUG_STACK),y)
+CMN_CSRCS += up_checkstack.c
+endif
+
+ifeq ($(CONFIG_ARCH_FPU),y)
+CMN_ASRCS += up_fpu.S
+endif
+
+CHIP_ASRCS =
+CHIP_CSRCS = stm32_allocateheap.c stm32_start.c stm32_rcc.c stm32_lse.c \
+ stm32_lsi.c stm32_gpio.c stm32_exti_gpio.c stm32_flash.c stm32_irq.c \
+ stm32_timerisr.c stm32_dma.c stm32_lowputc.c stm32_serial.c \
+ stm32_spi.c stm32_sdio.c stm32_tim.c stm32_i2c.c stm32_waste.c
+
+ifeq ($(CONFIG_USBDEV),y)
+ifeq ($(CONFIG_STM32_USB),y)
+CMN_CSRCS += stm32_usbdev.c
+endif
+ifeq ($(CONFIG_STM32_OTGFS),y)
+CMN_CSRCS += stm32_otgfsdev.c
+endif
+endif
+
+ifeq ($(CONFIG_USBHOST),y)
+ifeq ($(CONFIG_STM32_OTGFS),y)
+CMN_CSRCS += stm32_otgfshost.c
+endif
+endif
+
+ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
+CHIP_ASRCS += stm32_vectors.S
+endif
+
+ifneq ($(CONFIG_IDLE_CUSTOM),y)
+CHIP_CSRCS += stm32_idle.c
+endif
+
+CHIP_CSRCS += stm32_pmstop.c stm32_pmstandby.c stm32_pmsleep.c
+
+ifneq ($(CONFIG_PM_CUSTOMINIT),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
+endif
+
+ifeq ($(CONFIG_RTC),y)
+CHIP_CSRCS += stm32_rtc.c
+ifeq ($(CONFIG_RTC_ALARM),y)
+CHIP_CSRCS += stm32_exti_alarm.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_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
diff --git a/nuttx/arch/arm/src/stm32/chip.h b/nuttx/arch/arm/src/stm32/chip.h
new file mode 100644
index 000000000..3fac597ef
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip.h
@@ -0,0 +1,127 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/* Include the chip capabilities file */
+
+#include <arch/stm32/chip.h>
+
+/* Include the chip pin configuration file */
+
+/* STM32 F1 Family ******************************************************************/
+#if defined(CONFIG_STM32_STM32F10XX)
+
+/* STM32F100 Value Line */
+
+# if defined(CONFIG_STM32_VALUELINE)
+# include "chip/stm32f100_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_STM32F103RET6)
+# include "chip/stm32f103re_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_STM32F103VCT6) || defined(CONFIG_ARCH_CHIP_STM32F103VET6)
+# include "chip/stm32f103vc_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_STM32F103ZET6)
+# include "chip/stm32f103ze_pinmap.h"
+
+/* STM32 F105/F107 Connectivity Line */
+
+# elif defined(CONFIG_ARCH_CHIP_STM32F105VBT7)
+# include "chip/stm32f105vb_pinmap.h"
+
+# elif defined(CONFIG_ARCH_CHIP_STM32F107VC)
+# include "chip/stm32f107vc_pinmap.h"
+# else
+# error "Unsupported STM32F10XXX chip"
+# endif
+
+/* STM32 F2 Family ******************************************************************/
+#elif defined(CONFIG_STM32_STM32F20XX)
+# include "chip/stm32f20xxx_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_STM32F10XX)
+# include "chip/stm32f10xxx_vectors.h"
+# elif defined(CONFIG_STM32_STM32F20XX)
+# include "chip/stm32f20xxx_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/nuttx/arch/arm/src/stm32/chip/stm32_adc.h b/nuttx/arch/arm/src/stm32/chip/stm32_adc.h
new file mode 100644
index 000000000..218b11aa5
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_adc.h
@@ -0,0 +1,564 @@
+/****************************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_adc.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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) */
+#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) */
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# define STM32_ADC_CSR_OFFSET 0x0000 /* Common status register */
+# define STM32_ADC_CCR_OFFSET 0x0004 /* Common control register */
+# define STM32_ADC_CDR_OFFSET 0x0008 /* Data register for dual and triple modes */
+#endif
+
+/* Register Addresses *******************************************************************************/
+
+#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)
+# 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)
+# 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)
+#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)
+# define STM32_ADC_CSR (STM32_ADCCMN_BASE+STM32_ADC_CSR_OFFSET)
+# define STM32_ADC_CCR (STM32_ADCCMN_BASE+STM32_ADC_CCR_OFFSET)
+# define STM32_ADC_CDR (STM32_ADCCMN_BASE+STM32_ADC_CDR_OFFSET)
+#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)
+# define ADC_SR_OVR (1 << 5) /* Bit 5 : Overrun */
+#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)
+
+#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)
+# define ACD_CR1_RES_SHIFT (24) /* Bits 24-25: Resolution */
+# define ACD_CR1_RES_MASK (3 << ACD_CR1_RES_SHIFT)
+# define ACD_CR1_RES_12BIT (0 << ACD_CR1_RES_SHIFT) /* 15 ADCCLK clyes */
+# define ACD_CR1_RES_10BIT (1 << ACD_CR1_RES_SHIFT) /* 13 ADCCLK clyes */
+# define ACD_CR1_RES_8BIT (2 << ACD_CR1_RES_SHIFT) /* 11 ADCCLK clyes */
+# define ACD_CR1_RES_6BIT (3 << ACD_CR1_RES_SHIFT) /* 9 ADCCLK clyes */
+# 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 */
+#endif
+
+#define ADC_CR2_RSTCAL (1 << 3) /* Bit 3: Reset Calibration */
+#define ADC_CR2_DMA (1 << 8) /* Bit 8: Direct Memory access mode */
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# 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)
+ /* Bits 12-15: Reserved */
+# define ADC_CR2_JEXTSEL_SHIFT (16) /* Bits 16-19: External event select for injected group */
+# define ADC_CR2_JEXTSEL_MASK (15 << ADC_CR2_JEXTSEL_SHIFT)
+# define ADC_CR2_JEXTSEL_T1CC4 (0 << ADC_CR2_JEXTSEL_SHIFT) /* 0000: Timer 1 CC4 event */
+# define ADC_CR2_JEXTSEL_T1TRGO (1 << ADC_CR2_JEXTSEL_SHIFT) /* 0001: Timer 1 TRGO event */
+# define ADC_CR2_JEXTSEL_T2CC1 (2 << ADC_CR2_JEXTSEL_SHIFT) /* 0010: Timer 2 CC1 event */
+# define ADC_CR2_JEXTSEL_T2TRGO (3 << ADC_CR2_JEXTSEL_SHIFT) /* 0011: Timer 2 TRGO event */
+# define ADC_CR2_JEXTSEL_T3CC2 (4 << ADC_CR2_JEXTSEL_SHIFT) /* 0100: Timer 3 CC2 event */
+# define ADC_CR2_JEXTSEL_T3CC4 (5 << ADC_CR2_JEXTSEL_SHIFT) /* 0101: Timer 3 CC4 event */
+# define ADC_CR2_JEXTSEL_T4CC1 (6 << ADC_CR2_JEXTSEL_SHIFT) /* 0110: Timer 4 CC1 event */
+# define ADC_CR2_JEXTSEL_T4CC2 (7 << ADC_CR2_JEXTSEL_SHIFT) /* 0111: Timer 4 CC2 event */
+# define ADC_CR2_JEXTSEL_T4CC3 (8 << ADC_CR2_JEXTSEL_SHIFT) /* 1000: Timer 4 CC3 event */
+# define ADC_CR2_JEXTSEL_T4TRGO (9 << ADC_CR2_JEXTSEL_SHIFT) /* 1001: Timer 4 TRGO event */
+# define ADC_CR2_JEXTSEL_T5CC4 (10 << ADC_CR2_JEXTSEL_SHIFT) /* 1010: Timer 5 CC4 event */
+# define ADC_CR2_JEXTSEL_T5TRGO (11 << ADC_CR2_JEXTSEL_SHIFT) /* 1011: Timer 5 TRGO event */
+# define ADC_CR2_JEXTSEL_T8CC2 (12 << ADC_CR2_JEXTSEL_SHIFT) /* 1100: Timer 8 CC2 event */
+# define ADC_CR2_JEXTSEL_T8CC3 (13 << ADC_CR2_JEXTSEL_SHIFT) /* 1101: Timer 8 CC3 event */
+# define ADC_CR2_JEXTSEL_T8CC4 (14 << ADC_CR2_JEXTSEL_SHIFT) /* 1110: Timer 8 CC4 event */
+# define ADC_CR2_JEXTSEL_EXTI (15 << ADC_CR2_JEXTSEL_SHIFT) /* 1111: EXTI line15 */
+
+# define ACD_CR2_JEXTEN_SHIFT (20) /* Bits 20-21: External trigger enable for injected channels */
+# define ACD_CR2_JEXTEN_MASK (3 << ACD_CR2_JEXTEN_SHIFT)
+# define ACD_CR2_JEXTEN_NONE (0 << ACD_CR2_JEXTEN_SHIFT) /* 00: Trigger detection disabled */
+# define ACD_CR2_JEXTEN_RISING (1 << ACD_CR2_JEXTEN_SHIFT) /* 01: Trigger detection on the rising edge */
+# define ACD_CR2_JEXTEN_FALLING (2 << ACD_CR2_JEXTEN_SHIFT) /* 10: Trigger detection on the falling edge */
+# define ACD_CR2_JEXTEN_BOTH (3 << ACD_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 (15 << ADC_CR2_EXTSEL_SHIFT)
+# define ADC_CR2_EXTSEL_T1CC1 (0 << ADC_CR2_EXTSEL_SHIFT) /* 0000: Timer 1 CC1 event */
+# define ADC_CR2_EXTSEL_T1CC2 (1 << ADC_CR2_EXTSEL_SHIFT) /* 0001: Timer 1 CC2 event */
+# define ADC_CR2_EXTSEL_T1CC3 (2 << ADC_CR2_EXTSEL_SHIFT) /* 0010: Timer 1 CC3 event */
+# define ADC_CR2_EXTSEL_T2CC2 (3 << ADC_CR2_EXTSEL_SHIFT) /* 0011: Timer 2 CC2 event */
+# define ADC_CR2_EXTSEL_T2CC3 (4 << ADC_CR2_EXTSEL_SHIFT) /* 0100: Timer 2 CC3 event */
+# define ADC_CR2_EXTSEL_T2CC4 (5 << ADC_CR2_EXTSEL_SHIFT) /* 0101: Timer 2 CC4 event */
+# define ADC_CR2_EXTSEL_T2TRGO (6 << ADC_CR2_EXTSEL_SHIFT) /* 0110: Timer 2 TRGO event */
+# define ADC_CR2_EXTSEL_T3CC1 (7 << ADC_CR2_EXTSEL_SHIFT) /* 0111: Timer 3 CC1 event */
+# define ADC_CR2_EXTSEL_T3TRGO (8 << ADC_CR2_EXTSEL_SHIFT) /* 1000: Timer 3 TRGO event */
+# define ADC_CR2_EXTSEL_T4CC4 (9 << ADC_CR2_EXTSEL_SHIFT) /* 1001: Timer 4 CC4 event */
+# define ADC_CR2_EXTSEL_T5CC1 (10 << ADC_CR2_EXTSEL_SHIFT) /* 1010: Timer 5 CC1 event */
+# define ADC_CR2_EXTSEL_T5CC2 (11 << ADC_CR2_EXTSEL_SHIFT) /* 1011: Timer 5 CC2 event */
+# define ADC_CR2_EXTSEL_T5CC3 (12 << ADC_CR2_EXTSEL_SHIFT) /* 1100: Timer 5 CC3 event */
+# define ADC_CR2_EXTSEL_T8CC1 (13 << ADC_CR2_EXTSEL_SHIFT) /* 1101: Timer 8 CC1 event */
+# define ADC_CR2_EXTSEL_T8TRGO (14 << ADC_CR2_EXTSEL_SHIFT) /* 1110: Timer 8 TRGO event */
+# define ADC_CR2_EXTSEL_EXTI (15 << ADC_CR2_EXTSEL_SHIFT) /* 1111: EXTI line11 */
+
+# define ACD_CR2_EXTEN_SHIFT (28) /* Bits 28-29: External trigger enable for regular channels */
+# define ACD_CR2_EXTEN_MASK (3 << ACD_CR2_EXTEN_SHIFT)
+# define ACD_CR2_EXTEN_NONE (0 << ACD_CR2_EXTEN_SHIFT) /* 00: Trigger detection disabled */
+# define ACD_CR2_EXTEN_RISING (1 << ACD_CR2_EXTEN_SHIFT) /* 01: Trigger detection on the rising edge */
+# define ACD_CR2_EXTEN_FALLING (2 << ACD_CR2_EXTEN_SHIFT) /* 10: Trigger detection on the falling edge */
+# define ACD_CR2_EXTEN_BOTH (3 << ACD_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 line15 */
+# 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 line11 */
+# 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 */
+
+#else
+
+# 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 */
+
+#endif
+
+#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
+
+/* ADC sample time register 2 */
+
+#define ADC_SMPR2_SMP0_SHIFT (0) /* Bits 2-0: Channel 0 Sample time selection */
+#define ADC_SMPR2_SMP0_MASK (7 << ADC_SMPR1_SMP0_SHIFT)
+#define ADC_SMPR2_SMP1_SHIFT (3) /* Bits 5-3: Channel 1 Sample time selection */
+#define ADC_SMPR2_SMP1_MASK (7 << ADC_SMPR1_SMP1_SHIFT)
+#define ADC_SMPR2_SMP2_SHIFT (6) /* Bits 8-6: Channel 2 Sample time selection */
+#define ADC_SMPR2_SMP2_MASK (7 << ADC_SMPR1_SMP2_SHIFT)
+#define ADC_SMPR2_SMP3_SHIFT (9) /* Bits 11-9: Channel 3 Sample time selection */
+#define ADC_SMPR2_SMP3_MASK (7 << ADC_SMPR1_SMP3_SHIFT)
+#define ADC_SMPR2_SMP4_SHIFT (12) /* Bits 14-12: Channel 4 Sample time selection */
+#define ADC_SMPR2_SMP4_MASK (7 << ADC_SMPR1_SMP4_SHIFT)
+#define ADC_SMPR2_SMP5_SHIFT (15) /* Bits 17-15: Channel 5 Sample time selection */
+#define ADC_SMPR2_SMP5_MASK (7 << ADC_SMPR1_SMP5_SHIFT)
+#define ADC_SMPR2_SMP6_SHIFT (18) /* Bits 20-18: Channel 6 Sample time selection */
+#define ADC_SMPR2_SMP6_MASK (7 << ADC_SMPR1_SMP6_SHIFT)
+#define ADC_SMPR2_SMP7_SHIFT (21) /* Bits 23-21: Channel 7 Sample time selection */
+#define ADC_SMPR2_SMP7_MASK (7 << ADC_SMPR1_SMP7_SHIFT)
+#define ADC_SMPR2_SMP8_SHIFT (24) /* Bits 26-24: Channel 8 Sample time selection */
+#define ADC_SMPR2_SMP8_MASK (7 << ADC_SMPR1_SMP8_SHIFT)
+#define ADC_SMPR2_SMP9_SHIFT (27) /* Bits 29-27: Channel 9 Sample time selection */
+#define ADC_SMPR2_SMP9_MASK (7 << ADC_SMPR1_SMP9_SHIFT)
+
+/* 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 */
+
+#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)
+
+/* ADC regular sequence register 2 */
+
+#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)
+
+/* ADC regular sequence register 3 */
+
+#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)
+
+/* 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_MASK)
+#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_SHIFT (0) /* Bits 15-0: Injected data */
+#define ADC_JDR_MASK (0xffff << ADC_JDR_SHIFT)
+
+/* ADC regular data register */
+
+#define ADC_DR_DATA_SHIFT (0) /* Bits 15-0 Regular data */
+#define ADC_DR_DATA_MASK (0xffff << ADC_DR_DATA_SHIFT)
+#define ADC_DR_ADC2DATA_SHIFT (16) /* Bits 31-16: ADC2 data */
+#define ADC_DR_ADC2DATA_MASK (0xffff << ADC_DR_ADC2DATA_SHIFT)
+
+/* Common status register */
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# 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. */
+# 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
+
+/* 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) (((5)-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. */
+#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/nuttx/arch/arm/src/stm32/chip/stm32_bkp.h b/nuttx/arch/arm/src/stm32/chip/stm32_bkp.h
new file mode 100644
index 000000000..5bda839a8
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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/nuttx/arch/arm/src/stm32/chip/stm32_can.h b/nuttx/arch/arm/src/stm32/chip/stm32_can.h
new file mode 100644
index 000000000..253bf68fc
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_can.h
@@ -0,0 +1,505 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_can.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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_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_FR_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 << 20) /* 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/nuttx/arch/arm/src/stm32/chip/stm32_dac.h b/nuttx/arch/arm/src/stm32/chip/stm32_dac.h
new file mode 100644
index 000000000..1498c8c93
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_dac.h
@@ -0,0 +1,256 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_dac.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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_DHR12L_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_DHR12L (STM32_DAC_BASE+STM32_DAC_DHR12L_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 channel1 enable */
+#define DAC_CR_BOFF (1 << 1) /* Bit 1: DAC channel1 output buffer disable */
+#define DAC_CR_TSEL_SHIFT (3) /* Bits 3-5: DAC channel1 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 channel1 noise/triangle wave generation */enable
+#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 channel1 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 channel1 DMA enable */
+#define DAC_CR_DMAUDRIE (1 << 13) /* Bit 13: DAC channel1 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_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/nuttx/arch/arm/src/stm32/chip/stm32_dbgmcu.h b/nuttx/arch/arm/src/stm32/chip/stm32_dbgmcu.h
new file mode 100644
index 000000000..ff1661313
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_dbgmcu.h
@@ -0,0 +1,144 @@
+/****************************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_dbgmcu.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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_STM32F40XX)
+# 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_CR_RTCSTOP (1 << 10) /* Bit 11: RTC stopped when Core is halted */
+# define DBGMCU_CR_WWDGSTOP (1 << 11) /* Bit 11: Window Watchdog stopped when core is halted */
+# define DBGMCU_CR_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 */
+#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 */
+#endif
+
+/****************************************************************************************************
+ * Public Types
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Public Data
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Public Functions
+ ****************************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_DBGMCU_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_eth.h b/nuttx/arch/arm/src/stm32/chip/stm32_eth.h
new file mode 100644
index 000000000..431144009
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_eth.h
@@ -0,0 +1,829 @@
+/****************************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_eth.h
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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 */
+#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 */
+#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)
+#define STM32_ETH_MACDBGR (STM32_ETHERNET_BASE+STM32_ETH_MACDBGR_OFFSET)
+#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 */
+#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)
+#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_168 (4 << ETH_MACMIIAR_CR_SHIFT) /* 100 150-168 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 */
+
+#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 */
+
+/* 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 */
+#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 */
+
+/* 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 */
+#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 (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 */
+#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_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_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
+ ****************************************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* STM32_NETHERNET > 0 */
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_ETH_H */
+
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_exti.h b/nuttx/arch/arm/src/stm32/chip/stm32_exti.h
new file mode 100644
index 000000000..5386a260f
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_exti.h
@@ -0,0 +1,141 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_exti.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# define STM32_NEXTI 23
+# define STM32_EXTI_MASK 0x007fffff
+#endif
+
+#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 lines > 15 are associated with internal devices: */
+
+#if defined(CONFIG_STM32_STM32F10XX)
+# 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_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 << 22) /* EXTI line 21 is connected to the RTC Tamper and TimeStamp events */
+# define EXTI_RTC_WAKEUP (1 << 23) /* EXTI line 22 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
+
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_EXTI_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_flash.h b/nuttx/arch/arm/src/stm32/chip/stm32_flash.h
new file mode 100644
index 000000000..c2e440923
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_flash.h
@@ -0,0 +1,190 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_flash.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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
+ ************************************************************************************/
+
+#if 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_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# define STM32_FLASH_NPAGES 8
+# define STM32_FLASH_PAGESIZE (128*1024)
+#endif
+
+#define STM32_FLASH_SIZE (STM32_FLASH_NPAGES * 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)
+# 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
+
+/* 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)
+# 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
+
+/* 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 */
+# 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)
+# define FLASH_ACR_HLFCYA (1 << 3) /* FLASH half cycle access */
+# define FLASH_ACR_PRTFBE (1 << 4) /* FLASH prefetch enable */
+#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# 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
+
+/* Flash Status Register (SR) */
+
+#if defined(CONFIG_STM32_STM32F10XX)
+# 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)
+# define FLASH_CR_PG (1 << 0) /* Program Page */
+# define FLASH_CR_PER (1 << 1) /* Page Erase */
+# define FLASH_CR_MER (1 << 2) /* Mass Erase */
+# define FLASH_CR_OPTPG (1 << 4) /* Option Byte Programming */
+# define FLASH_CR_OPTER (1 << 5) /* Option Byte Erase */
+# define FLASH_CR_STRT (1 << 6) /* Start Erase */
+# define FLASH_CR_LOCK (1 << 7) /* Page Locked or Lock Page */
+# define FLASH_CR_OPTWRE (1 << 9) /* Option Bytes Write Enable */
+# define FLASH_CR_ERRIE (1 << 10) /* Error Interrupt Enable */
+# define FLASH_CR_EOPIE (1 << 12) /* End of Program Interrupt Enable */
+#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 */
+# 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) ((n) << FLASH_CR_SNB_SHIFT) /* Sector n, n=0..11 */
+# 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_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
+
+/* 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
+
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_FLASH_H */
+
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h b/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h
new file mode 100644
index 000000000..f481245e0
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h
@@ -0,0 +1,192 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_i2c.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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) */
+
+/* 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)
+#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)
+#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)
+#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 (1) /* 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)
+
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_I2C_H */
+
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_memorymap.h b/nuttx/arch/arm/src/stm32/chip/stm32_memorymap.h
new file mode 100644
index 000000000..36813b565
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_memorymap.h
@@ -0,0 +1,57 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_memorymap.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include "chip.h"
+
+#if defined(CONFIG_STM32_STM32F10XX)
+# include "chip/stm32f10xxx_memorymap.h"
+#elif defined(CONFIG_STM32_STM32F20XX)
+# include "chip/stm32f20xxx_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/nuttx/arch/arm/src/stm32/chip/stm32_otgfs.h b/nuttx/arch/arm/src/stm32/chip/stm32_otgfs.h
new file mode 100644
index 000000000..ee34172cf
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_otgfs.h
@@ -0,0 +1,1017 @@
+/****************************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_otgfs.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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 (10) /* 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 */
+ /* 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/nuttx/arch/arm/src/stm32/chip/stm32_pwr.h b/nuttx/arch/arm/src/stm32/chip/stm32_pwr.h
new file mode 100644
index 000000000..2ece6a357
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_pwr.h
@@ -0,0 +1,103 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_pwr.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#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 */
+#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)
+# 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 */
+#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 */
+# define PWR_CR_VOS (1 << 14) /* Bit 14: Regulator voltage scaling output selection */
+#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 */
+#endif
+
+#define PWR_CSR_EWUP (1 << 8) /* Bit 8: Enable WKUP pin */
+
+#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
+
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_PWR_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_sdio.h b/nuttx/arch/arm/src/stm32/chip/stm32_sdio.h
new file mode 100644
index 000000000..d2af8a32c
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_sdio.h
@@ -0,0 +1,291 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_sdio.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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/nuttx/arch/arm/src/stm32/chip/stm32_spi.h b/nuttx/arch/arm/src/stm32/chip/stm32_spi.h
new file mode 100644
index 000000000..d80c447bb
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_spi.h
@@ -0,0 +1,205 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_spi.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <nuttx/config.h>
+#include "chip.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+#define STM32_SPI_CLK_MAX 18000000UL /* Maximum allowed speed as per specifications for all SPIs */
+
+/* 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_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_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_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_STM32F40XX)
+# define STM32_SPI3_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 */
+
+/* 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_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_STM32F40XX)
+# define SPI_SR_TIFRFE (1 << 8) /* Bit 8: TI frame format error */
+#endif
+
+/* I2S configuration register */
+
+#if defined(CONFIG_STM32_STM32F20XX) || 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_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/nuttx/arch/arm/src/stm32/chip/stm32_syscfg.h b/nuttx/arch/arm/src/stm32/chip/stm32_syscfg.h
new file mode 100644
index 000000000..6642b1305
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_syscfg.h
@@ -0,0 +1,151 @@
+/****************************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_syscfg.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_SYSCFG_H
+#define __ARCH_ARM_SRC_STM32_CHIP_STM32_SYSCFG_H
+
+/****************************************************************************************************
+ * Included Files
+ ****************************************************************************************************/
+
+#include <nuttx/config.h>
+#include "chip.h"
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(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 */
+
+/* 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 || CONFIG_STM32_STM32F40XX */
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_SYSCFG_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_tim.h b/nuttx/arch/arm/src/stm32/chip/stm32_tim.h
new file mode 100644
index 000000000..3713f8b79
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_tim.h
@@ -0,0 +1,1029 @@
+/****************************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_tim.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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
+ */
+
+#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 STM3240 TIM2/5 only) */
+#define STM32_GTIM_CCR3_OFFSET 0x003c /* Capture/compare register 3 (16-bit TIM2-5 only or 32-bit STM3240 TIM2/5 only) */
+#define STM32_GTIM_CCR4_OFFSET 0x0040 /* Capture/compare register 4 (16-bit TIM2-5 only or 32-bit STM3240 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) */
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# define STM32_GTIM_OR_OFFSET 0x0050 /* Timer 2/5/11 option register */
+#endif
+
+/* 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) */
+
+/* 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)
+#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)
+#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
+
+/* 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 */
+
+/* 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_OC1REF (4 << ATIM_CR2_MMS_SHIFT) /* 100: Compare OC1REF is TRGO */
+#define ATIM_CR2_OC2REF (5 << ATIM_CR2_MMS_SHIFT) /* 101: Compare OC2REF is TRGO */
+#define ATIM_CR2_OC3REF (6 << ATIM_CR2_MMS_SHIFT) /* 110: Compare OC3REF is TRGO */
+#define ATIM_CR2_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) */
+
+/* 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 */
+#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 */
+
+/* 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 */
+
+#ifdef CONFIG_STM32_STM32F10XX
+# define ATIM_DIER_COMIE (1 << 5) /* Bit 5: COM interrupt enable */
+#endif
+
+#define ATIM_DIER_TIE (1 << 6) /* Bit 6: Trigger interrupt enable */
+
+#ifdef CONFIG_STM32_STM32F10XX
+# 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 */
+
+#ifdef CONFIG_STM32_STM32F10XX
+# 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 */
+
+#ifdef CONFIG_STM32_STM32F10XX
+# define ATIM_SR_BIF (1 << 7) /* Bit 7: Break 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 */
+
+/* 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 */
+
+#ifdef CONFIG_STM32_STM32F10XX
+# define ATIM_EGR_COMG (1 << 5) /* Bit 5: Capture/Compare Control Update Generation */
+#endif
+
+#define ATIM_EGR_TG (1 << 6) /* Bit 6: Trigger Generation */
+
+#ifdef CONFIG_STM32_STM32F10XX
+# define ATIM_EGR_BG (1 << 7) /* Bit 7: Break 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 */
+
+/* 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 */
+
+/* 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 */
+
+/* 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 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)
+# define ATIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 output Polarity */
+#endif
+
+/* Repetition counter register */
+
+#define ATIM_RCR_REP_SHIFT (0) /* Bits 7-0: Repetition Counter Value */
+#define ATIM_RCR_REP_MASK (0xff << ATIM_RCR_REP_SHIFT)
+
+#define ATIM_RCR_REP_MAX 128
+
+/* 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 */
+
+/* DMA control register */
+
+#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 */
+#define ATIM_DCR_DBA_SHIFT (0) /* Bits 4-0: DMA Base Address */
+#define ATIM_DCR_DBA_MASK (0x1f << ATIM_DCR_DBA_SHIFT)
+
+/* 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 */
+
+/* Control register 2 (TIM2-5 and TIM9/12 only) */
+
+#define GTIM_CR2_CCDS (1 << 3) /* Bit 3: Capture/Compare DMA Selection (TIM2-5 only) */
+#define GTIM_CR2_MMS_SHIFT (4) /* Bits 6-4: Master Mode Selection */
+#define GTIM_CR2_MMS_MASK (7 << GTIM_CR2_MMS_SHIFT)
+# define GTIM_CR2_RESET (0 << GTIM_CR2_MMS_SHIFT) /* 000: Reset */
+# define GTIM_CR2_ENAB (1 << GTIM_CR2_MMS_SHIFT) /* 001: Enable */
+# define GTIM_CR2_UPDT (2 << GTIM_CR2_MMS_SHIFT) /* 010: Update */
+# define GTIM_CR2_CMPP (3 << GTIM_CR2_MMS_SHIFT) /* 011: Compare Pulse */
+# define GTIM_CR2_CMP1 (4 << GTIM_CR2_MMS_SHIFT) /* 100: Compare - OC1REF signal is used as trigger output (TRGO) */
+# define GTIM_CR2_CMP2 (5 << GTIM_CR2_MMS_SHIFT) /* 101: Compare - OC2REF signal is used as trigger output (TRGO) */
+# define GTIM_CR2_CMP3 (6 << GTIM_CR2_MMS_SHIFT) /* 110: Compare - OC3REF signal is used as trigger output (TRGO, TIM2-5 only) */
+# define GTIM_CR2_CMP4 (7 << GTIM_CR2_MMS_SHIFT) /* 111: Compare - OC4REF signal is used as trigger output (TRGO, TIM2-5 only) */
+#define GTIM_CR2_TI1S (1 << 7) /* Bit 7: TI1 Selection */
+
+/* Slave mode control register (TIM2-5 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 */
+#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 */
+#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 */
+
+/* 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 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_TIE (1 << 6) /* Bit 6: Trigger interrupt enable (TIM2-5,9,&12 only) */
+#define GTIM_DIER_UDE (1 << 8) /* Bit 8: Update DMA request enable (TIM2-5 only) */
+#define GTIM_DIER_CC1DE (1 << 9) /* Bit 9: Capture/Compare 1 DMA request enable (TIM2-5 only) */
+#define GTIM_DIER_CC2DE (1 << 10) /* Bit 10: Capture/Compare 2 DMA request enable (TIM2-5 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_TDE (1 << 14) /* Bit 14: Trigger DMA request enable (TIM2-5 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 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_TIF (1 << 6) /* Bit 6: Trigger interrupt Flag (TIM2-5,9,&12 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 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 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_TG (1 << 6) /* Bit 6: Trigger generation (TIM2-5,9,&12 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 */
+
+/* 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 (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 */
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# define GTIM_CCER_CC1NP (1 << 3) /* Bit 3: Capture/Compare 1 output Polarity */
+#endif
+
+#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) */
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# define GTIM_CCER_CC2NP (1 << 7) /* Bit 7: Capture/Compare 2 output Polarity (TIM2-5,9&12 only) */
+#endif
+
+#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) */
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# define GTIM_CCER_CC3NP (1 << 11) /* Bit 11: Capture/Compare 3 output Polarity (TIM2-5 only) */
+#endif
+
+#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) */
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# define GTIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 output Polarity (TIM2-5 only) */
+#endif
+
+/* DMA control register */
+
+#define GTIM_DCR_DBL_SHIFT (8) /* Bits 12-8: DMA Burst Length */
+#define GTIM_DCR_DBL_MASK (0x1f << GTIM_DCR_DBL_SHIFT)
+#define GTIM_DCR_DBA_SHIFT (0) /* Bits 4-0: DMA Base Address */
+#define GTIM_DCR_DBA_MASK (0x1f << GTIM_DCR_DBA_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
+
+/* 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/nuttx/arch/arm/src/stm32/chip/stm32_uart.h b/nuttx/arch/arm/src/stm32/chip/stm32_uart.h
new file mode 100644
index 000000000..d3c1e137e
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_uart.h
@@ -0,0 +1,229 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_uart.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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_UART_H
+#define __ARCH_ARM_STC_STM32_CHIP_STM32_UART_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#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 */
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# define USART_CR1_OVER8 (1 << 15) /* Bit 15: Oversampling mode */
+#endif
+
+#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 */
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# define USART_CR1_ONEBIT (1 << 11) /* Bit 11: One sample bit method enable */
+#endif
+
+/* 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)
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_STC_STM32_CHIP_STM32_UART_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_usbdev.h b/nuttx/arch/arm/src/stm32/chip/stm32_usbdev.h
new file mode 100644
index 000000000..daa9a926e
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_usbdev.h
@@ -0,0 +1,236 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_usbdev.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <chip.h>
+
+#ifdef CONFIG_STM32_STM32F10XX
+
+/************************************************************************************
+ * 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_USBCANRAM_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 */
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_USBDEV_H */
+
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_wdg.h b/nuttx/arch/arm/src/stm32/chip/stm32_wdg.h
new file mode 100644
index 000000000..5abb5bc6d
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_wdg.h
@@ -0,0 +1,145 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_wdg.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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) */
+
+#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)
+
+#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 */
+
+/* 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/nuttx/arch/arm/src/stm32/chip/stm32f100_pinmap.h b/nuttx/arch/arm/src/stm32/chip/stm32f100_pinmap.h
new file mode 100644
index 000000000..01d6e1ce0
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f100_pinmap.h
@@ -0,0 +1,267 @@
+/************************************************************************************
+ * 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 <gnutt@nuttx.org>
+ * Uros Platise <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* 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
+
+/* 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
+
+/* 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)
+
+/* 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)
+
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F100_PINMAP_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f103re_pinmap.h b/nuttx/arch/arm/src/stm32/chip/stm32f103re_pinmap.h
new file mode 100644
index 000000000..042f57f74
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f103re_pinmap.h
@@ -0,0 +1,332 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f103re_pinmap.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ * Uros Platise <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_STM32F103RE_PINMAP_H
+#define __ARCH_ARM_SRC_STM32_CHIP_STM32F103RE_PINMAP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* 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_STM32F103RE_PINMAP_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f103vc_pinmap.h b/nuttx/arch/arm/src/stm32/chip/stm32f103vc_pinmap.h
new file mode 100644
index 000000000..160676802
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f103vc_pinmap.h
@@ -0,0 +1,423 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f103vc_pinmap.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ * Laurent Latil <laurent@latil.nom.fr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_STM32F103VC_PINMAP_H
+#define __ARCH_ARM_SRC_STM32_CHIP_STM32F103VC_PINMAP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.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_INPUTz|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)
+
+#if 0 /* Needs further investigation */
+#define GPIO_MCO (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8)
+#endif
+
+#if 0 /* Needs further investigation */
+#define GPIO_OTG_FSDM (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11)
+#define GPIO_OTG_FSDP (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12)
+#define GPIO_OTG_FSID (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10)
+#define GPIO_OTG_FSSOF (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8)
+#define GPIO_OTG_FSVBUS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9)
+#endif
+
+#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 (GGPIO_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_STM32F103VC_PINMAP_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f103ze_pinmap.h b/nuttx/arch/arm/src/stm32/chip/stm32f103ze_pinmap.h
new file mode 100644
index 000000000..9bcee49f5
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f103ze_pinmap.h
@@ -0,0 +1,583 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f103ze_pinmap.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_STM32F103ZE_PINMAP_H
+#define __ARCH_ARM_SRC_STM32_CHIP_STM32F103ZE_PINMAP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Alternate Pin Functions: */
+
+/* ADC */
+
+#define GPIO_ADC1_IN0 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0)
+#define GPIO_ADC1_IN1 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1)
+#define GPIO_ADC1_IN2 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2)
+#define GPIO_ADC1_IN3 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3)
+#define GPIO_ADC1_IN4 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4)
+#define GPIO_ADC1_IN5 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5)
+#define GPIO_ADC1_IN6 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6)
+#define GPIO_ADC1_IN7 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7)
+#define GPIO_ADC1_IN8 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0)
+#define GPIO_ADC1_IN9 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1)
+#define GPIO_ADC1_IN10 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0)
+#define GPIO_ADC1_IN11 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1)
+#define GPIO_ADC1_IN12 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2)
+#define GPIO_ADC1_IN13 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3)
+#define GPIO_ADC1_IN14 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN4)
+#define GPIO_ADC1_IN15 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN5)
+
+#define GPIO_ADC2_IN0 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0)
+#define GPIO_ADC2_IN1 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1)
+#define GPIO_ADC2_IN2 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2)
+#define GPIO_ADC2_IN3 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3)
+#define GPIO_ADC2_IN4 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4)
+#define GPIO_ADC2_IN5 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5)
+#define GPIO_ADC2_IN6 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6)
+#define GPIO_ADC2_IN7 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7)
+#define GPIO_ADC2_IN8 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0)
+#define GPIO_ADC2_IN9 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1)
+#define GPIO_ADC2_IN10 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0)
+#define GPIO_ADC2_IN11 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1)
+#define GPIO_ADC2_IN12 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2)
+#define GPIO_ADC2_IN13 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3)
+#define GPIO_ADC2_IN14 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN4)
+#define GPIO_ADC2_IN15 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN5)
+
+#define GPIO_ADC3_IN0 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0)
+#define GPIO_ADC3_IN1 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1)
+#define GPIO_ADC3_IN2 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2)
+#define GPIO_ADC3_IN3 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3)
+#define GPIO_ADC3_IN4 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN6)
+#define GPIO_ADC3_IN5 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN7)
+#define GPIO_ADC3_IN6 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN8)
+#define GPIO_ADC3_IN7 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN9)
+#define GPIO_ADC3_IN8 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN10)
+#define GPIO_ADC3_IN10 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0)
+#define GPIO_ADC3_IN11 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1)
+#define GPIO_ADC3_IN12 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2)
+#define GPIO_ADC3_IN13 (GPIO_ALT|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_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN10)
+#define GPIO_DAC_OUT2 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PIN10)
+
+/* 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
+
+#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_STM32F103ZE_PINMAP_H */
+
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f105vb_pinmap.h b/nuttx/arch/arm/src/stm32/chip/stm32f105vb_pinmap.h
new file mode 100644
index 000000000..7a5ec3381
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f105vb_pinmap.h
@@ -0,0 +1,416 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f105vb_pinmap.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_STM32F105VB_PINMAP_H
+#define __ARCH_ARM_SRC_STM32_CHIP_STM32F105VB_PINMAP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.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_INPUTz|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)
+
+#if 0 /* Needs further investigation */
+#define GPIO_MCO (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8)
+#endif
+
+#if 0 /* Needs further investigation */
+#define GPIO_OTG_FSDM (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11)
+#define GPIO_OTG_FSDP (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12)
+#define GPIO_OTG_FSID (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10)
+#define GPIO_OTG_FSSOF (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8)
+#define GPIO_OTG_FSVBUS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9)
+#endif
+
+#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 (GGPIO_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_STM32F105VB_PINMAP_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f107vc_pinmap.h b/nuttx/arch/arm/src/stm32/chip/stm32f107vc_pinmap.h
new file mode 100644
index 000000000..9bbc21479
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f107vc_pinmap.h
@@ -0,0 +1,420 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f107vc_pinmap.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_STM32F107VC_PINMAP_H
+#define __ARCH_ARM_SRC_STM32_CHIP_STM32F107VC_PINMAP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.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_INPUTz|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)
+
+#if 0 /* Needs further investigation */
+#define GPIO_OTG_FSDM (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11)
+#define GPIO_OTG_FSDP (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12)
+#define GPIO_OTG_FSID (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10)
+#define GPIO_OTG_FSSOF (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8)
+#define GPIO_OTG_FSVBUS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9)
+#endif
+
+#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 (GGPIO_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_STM32F107VC_PINMAP_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_dma.h b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_dma.h
new file mode 100644
index 000000000..a8241bc72
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_dma.h
@@ -0,0 +1,350 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f10xxx_dma.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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
+ ************************************************************************************/
+
+/* 7 DMA Channels */
+
+#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_DMACHAN_CCR_OFFSET 0x0008
+#define STM32_DMACHAN_CNDTR_OFFSET 0x000c
+#define STM32_DMACHAN_CPAR_OFFSET 0x0010
+#define STM32_DMACHAN_CMAR_OFFSET 0x0014
+
+#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.
+ */
+
+#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 (1)
+#define STM32_DMA2_CHAN4 (10)
+#define STM32_DMA2_CHAN5 (11)
+
+#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_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
+
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_DMA_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_gpio.h b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_gpio.h
new file mode 100644
index 000000000..feeeda6dd
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_gpio.h
@@ -0,0 +1,367 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f10xxx_gpio.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 */
+
+/* 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_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 */
+#ifdef CONFIG_STM32_CONNECTIVITYLINE
+# define AFIO_MAPR_MII_RMII_SEL (1 << 23) /* MII or RMII selection */
+#endif
+#define AFIO_MAPR_PD01_REMAP (1 << 15) /* Bit 15 : Port D0/Port D1 mapping on OSC_IN/OSC_OUT */
+#define AFIO_MAPR_CAN_REMAP_SHIFT (13) /* Bits 14-13: CAN Alternate function remapping */
+#define AFIO_MAPR_CAN_REMAP_MASK (3 << AFIO_MAPR_CAN_REMAP_SHIFT)
+# define AFIO_MAPR_PA1112 (0 << AFIO_MAPR_CAN_REMAP_SHIFT) /* 00: CANRX mapped to PA11, CANTX mapped to PA12 */
+# define AFIO_MAPR_PB89 (2 << AFIO_MAPR_CAN_REMAP_SHIFT) /* 10: CANRX mapped to PB8, CANTX mapped to PB9 */
+# define AFIO_MAPR_PD01 (3 << AFIO_MAPR_CAN_REMAP_SHIFT) /* 11: CANRX mapped to PD0, CANTX mapped to PD1 */
+#define AFIO_MAPR_TIM4_REMAP (1 << 12) /* Bit 12: TIM4 remapping */
+#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 (CH1/PA6, CH2/PA7, CH3/PB0, CH4/PB1) */
+# define AFIO_MAPR_TIM3_PARTREMAP (2 << AFIO_MAPR_TIM3_REMAP_SHIFT) /* 10: Partial remap (CH1/PB4, CH2/PB5, CH3/PB0, CH4/PB1) */
+# define AFIO_MAPR_TIM3_FULLREMAP (3 << AFIO_MAPR_TIM3_REMAP_SHIFT) /* 11: Full remap (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9) */
+#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 (CH1/ETR/PA0, CH2/PA1, CH3/PA2, CH4/PA3) */
+# define AFIO_MAPR_TIM2_PARTREMAP1 (1 << AFIO_MAPR_TIM2_REMAP_SHIFT) /* 01: Partial remap (CH1/ETR/PA15, CH2/PB3, CH3/PA2, CH4/PA3) */
+# define AFIO_MAPR_TIM2_PARTREMAP2 (2 << AFIO_MAPR_TIM2_REMAP_SHIFT) /* 10: Partial remap (CH1/ETR/PA0, CH2/PA1, CH3/PB10, CH4/PB11) */
+# define AFIO_MAPR_TIM2_FULLREMAP (3 << AFIO_MAPR_TIM2_REMAP_SHIFT) /* 11: Full remap (CH1/ETR/PA15, CH2/PB3, CH3/PB10, CH4/PB11) */
+#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 (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PB12, CH1N/PB13, CH2N/PB14, CH3N/PB15) */
+# define AFIO_MAPR_TIM1_PARTREMAP (1 << AFIO_MAPR_TIM1_REMAP_SHIFT) /* 01: Partial remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PA6, CH1N/PA7, CH2N/PB0, CH3N/PB1) */
+# define AFIO_MAPR_TIM1_FULLREMAP (3 << AFIO_MAPR_TIM1_REMAP_SHIFT) /* 11: Full remap (ETR/PE7, CH1/PE9, CH2/PE11, CH3/PE13, CH4/PE14, BKIN/PE15, CH1N/PE8, CH2N/PE10, CH3N/PE12) */
+#define AFIO_MAPR_USART3_REMAP_SHIFT (6) /* 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 (TX/PB10, RX/PB11, CK/PB12, CTS/PB13, RTS/PB14) */
+# define AFIO_MAPR_USART3_PARTREMAP (1 << AFIO_MAPR_USART3_REMAP_SHIFT) /* 01: Partial remap (TX/PC10, RX/PC11, CK/PC12, CTS/PB13, RTS/PB14) */
+# define AFIO_MAPR_USART3_FULLREMAP (3 << AFIO_MAPR_USART3_REMAP_SHIFT) /* 11: Full remap (TX/PD8, RX/PD9, CK/PD10, CTS/PD11, RTS/PD12) */
+#define AFIO_MAPR_USART2_REMAP (1 << 3) /* Bit 3: USART2 remapping */
+#define AFIO_MAPR_USART1_REMAP (1 << 2) /* Bit 2: USART1 remapping */
+#define AFIO_MAPR_I2C1_REMAP (1 << 1) /* Bit 1: I2C1 remapping */
+#define AFIO_MAPR_SPI1_REMAP (1 << 0) /* Bit 0: SPI1 remapping */
+
+/* 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)
+
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_GPIO_H */
+
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_memorymap.h b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_memorymap.h
new file mode 100644
index 000000000..ed1bc2625
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_memorymap.h
@@ -0,0 +1,145 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f10xxx_memorymap.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_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)
+
+/* 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 */
+ /* 0x40001800 - 0x40000fff: Reserved */
+#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_USBCANRAM_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 */
+ /* 0x40007800 - 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 - 0x40013fff: ADC3 */
+ /* 0x40014000 - 0x40017fff: 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/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_rcc.h b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_rcc.h
new file mode 100644
index 000000000..60365b921
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_rcc.h
@@ -0,0 +1,416 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f10xx_rcc.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 */
+#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 (0x0f << RCC_CFGR_MCO_SHIFT)
+# define RCC_CFGR_NOCLK (0 << RCC_CFGR_MCO_SHIFT) /* 0xx: No clock */
+# define RCC_CFGR_SYSCLK (4 << RCC_CFGR_MCO_SHIFT) /* 100: System clock selected */
+# define RCC_CFGR_INTCLK (5 << RCC_CFGR_MCO_SHIFT) /* 101: Internal 8 MHz RC oscillator clock selected */
+# define RCC_CFGR_EXTCLK (6 << RCC_CFGR_MCO_SHIFT) /* 110: External 1-25 MHz oscillator clock selected */
+# define RCC_CFGR_PLLCLKd2 (7 << RCC_CFGR_MCO_SHIFT) /* 111: 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 TCC_APB2RSTR_IOPFRST (1 << 7) /* Bit 7: IO port F reset */
+#define TCC_APB2RSTR_IOPGRST (1 << 8) /* Bit 8: IO port G reset */
+#define RCC_APB2RSTR_ADC1RST (1 << 9) /* Bit 9: ADC 1 interface reset */
+#define RCC_APB2RSTR_ADC2RST (1 << 10) /* Bit 10: ADC 2 interface 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_ADC3RST (1 << 15) /* Bit 15: ADC3 interface 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 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 */
+#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 18: 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_CAN2RST (1 << 26) /* Bit 26: CAN2 reset */
+#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 */
+
+/* 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 */
+#define RCC_AHBENR_SDIOEN (1 << 10) /* Bit 10: SDIO clock enable */
+#ifdef CONFIG_STM32_CONNECTIVITYLINE
+# 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 */
+#define RCC_APB2ENR_ADC2EN (1 << 10) /* Bit 10: ADC 2 interface 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_ADC3EN (1 << 15) /* Bit 14: ADC3 interface 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 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 */
+#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_CAN2EN (1 << 26) /* Bit 25: CAN2 clock enable */
+#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 */
+
+/* Backup domain control register */
+
+#define RCC_BDCR_BDRST (1 << 16) /* Bit 16: Backup domain software reset */
+#define RCC_BDCR_RTCEN (1 << 15) /* Bit 15: RTC clock enable */
+#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_LSEBYP (1 << 2) /* Bit 2: External Low Speed oscillator Bypass */
+#define RCC_BDCR_LSERDY (1 << 1) /* Bit 1: External Low Speed oscillator Ready */
+#define RCC_BDCR_LSEON (1 << 0) /* Bit 0: External Low Speed oscillator enable */
+
+/* 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 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)
+
+#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/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_rtc.h b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_rtc.h
new file mode 100644
index 000000000..a0778f4e6
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_rtc.h
@@ -0,0 +1,96 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f10xxx_rtc.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_RTC_H
+#define __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_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_STM32F10XXX_RTC_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_vectors.h b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_vectors.h
new file mode 100644
index 000000000..b8d71799f
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_vectors.h
@@ -0,0 +1,222 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f10xxx_vectors.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 60 interrupt table entries for I/O interrupts. */
+
+# define ARMV7M_PERIPHERAL_INTERRUPTS 60
+
+#else
+# error This target requires CONFIG_ARMV7M_CMNVECTOR
+#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/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_dma.h b/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_dma.h
new file mode 100644
index 000000000..af4b361c2
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_STREAM5,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/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_gpio.h b/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_gpio.h
new file mode 100644
index 000000000..73a028244
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_ARFH_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_ARFH (STM32_GPIOA_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOB_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOC_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOD_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOE_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOF_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOG_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOH_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOI_BASE+STM32_GPIO_ARFH_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/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_memorymap.h b/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_memorymap.h
new file mode 100644
index 000000000..777b9595f
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_memorymap.h
@@ -0,0 +1,205 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f20xxx_memorymap.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 */
+
+/* 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/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_pinmap.h b/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_pinmap.h
new file mode 100644
index 000000000..817e747f7
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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_PUSHPULLGPIO_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_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_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_PORTI|GPIO_PIN2)
+#define GPIO_SPI2_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|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_PORTI|GPIO_PIN3)
+#define GPIO_SPI2_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN12)
+#define GPIO_SPI2_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN9)
+#define GPIO_SPI2_NSS_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|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_PORTI|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_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_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/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_rcc.h b/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_rcc.h
new file mode 100644
index 000000000..8a926250b
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_rcc.h
@@ -0,0 +1,504 @@
+/****************************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f20xxx_rcc.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 0x0060 /* 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)
+# define RCC_CFGR_RTCPRE(n) ((n) << RCC_CFGR_RTCPRE) /* 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 TCC_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 */
+
+/* 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/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_rtc.h b/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_rtc.h
new file mode 100644
index 000000000..b0d7ec913
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_rtc.h
@@ -0,0 +1,338 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f20xxx_rtc.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_RTC_H
+#define __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_RTC_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 */
+#define STM32_RTC_CALIBR_OFFSET 0x0018 /* RTC calibration register */
+#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 0x0030 /* 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 */
+#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 */
+
+/* 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)
+#define STM32_RTC_CALIBR (STM32_RTC_BASE+STM32_RTC_CALIBR_OFFSET)
+#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)
+#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)
+
+/* 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 */
+#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 */
+
+#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 */
+
+/* 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_
+
+/* RTC tamper and alternate function configuration register */
+
+#define RTC_TAFCR_CALM_SHIFT (0) /* Bits 0-8: Calibration minus */
+#define RTC_TAFCR_CALM_MASK (0x1ff << RTC_TAFCR_CALM_SHIFT)
+#define RTC_TAFCR_CALW16 (1 << 13) /* Bit 13: Use a 16-second calibration cycle period */
+#define RTC_TAFCR_CALW8 (1 << 14) /* Bit 14: Use an 8-second calibration cycle period */
+#define RTC_TAFCR_CALP (1 << 15) /* Bit 15: Increase frequency of RTC by 488.5 ppm */
+
+/* RTC alarm A/B sub second register */
+
+#define RTC_ALRMSSR_SS_SHIFT (0) /* Bits 0-15: Sub second value */
+#define RTC_ALRMSSR_SS_MASK (0xffff << RTC_ALRMSSR_SS_SHIFT)
+#define RTC_ALRMSSR_MASKSS_SHIFT (0) /* Bits 24-27: Mask the most-significant bits starting at this bit */
+#define RTC_ALRMSSR_MASKSS_MASK (0xffff << RTC_ALRMSSR_SS_SHIFT)
+
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_RTC_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_vectors.h b/nuttx/arch/arm/src/stm32/chip/stm32f20xxx_vectors.h
new file mode 100644
index 000000000..12fb5565c
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_dma.h b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_dma.h
new file mode 100644
index 000000000..ab0cfceac
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_dma.h
@@ -0,0 +1,520 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f40xxx_dma.h
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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)
+
+#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_STREAM5,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_STM32F40XXX_DMA_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_gpio.h b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_gpio.h
new file mode 100644
index 000000000..3a5f8bc6a
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_gpio.h
@@ -0,0 +1,370 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f40xxx_gpio.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_ARFH_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_ARFH (STM32_GPIOA_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOB_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOC_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOD_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOE_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOF_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOG_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOH_BASE+STM32_GPIO_ARFH_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_ARFH (STM32_GPIOI_BASE+STM32_GPIO_ARFH_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/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_memorymap.h b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_memorymap.h
new file mode 100644
index 000000000..6b9912121
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_memorymap.h
@@ -0,0 +1,205 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f40xxx_memorymap.h
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 */
+
+/* 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-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/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_pinmap.h b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_pinmap.h
new file mode 100644
index 000000000..ae2436a70
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_pinmap.h
@@ -0,0 +1,695 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f40xxx_pinmap.h
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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 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_PUSHPULLGPIO_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_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_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_PORTI|GPIO_PIN2)
+#define GPIO_SPI2_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|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_PORTI|GPIO_PIN3)
+#define GPIO_SPI2_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN12)
+#define GPIO_SPI2_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN9)
+#define GPIO_SPI2_NSS_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|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_PORTI|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_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_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_STM32F40XXX_PINMAP_H */
+
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_rcc.h b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_rcc.h
new file mode 100644
index 000000000..04cb05741
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_rcc.h
@@ -0,0 +1,506 @@
+/****************************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f40xxx_rcc.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 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 0x0060 /* 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)
+# define RCC_CFGR_RTCPRE(n) ((n) << RCC_CFGR_RTCPRE) /* 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 TCC_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_CCMDATARAMEN (1 << 20) /* Bit 20: CCM data 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_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 */
+
+/* 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_CCMDATARAMLPEN (1 << 20) /* Bit 20: CCM data 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_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_STM32F40XXX_RCC_H */
+
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_rtc.h b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_rtc.h
new file mode 100644
index 000000000..a656cfda0
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_rtc.h
@@ -0,0 +1,338 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f40xxx_rtc.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_RTC_H
+#define __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_RTC_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 */
+#define STM32_RTC_CALIBR_OFFSET 0x0018 /* RTC calibration register */
+#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 0x0030 /* 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 */
+#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 */
+
+/* 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)
+#define STM32_RTC_CALIBR (STM32_RTC_BASE+STM32_RTC_CALIBR_OFFSET)
+#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)
+#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)
+
+/* 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 */
+#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 */
+
+#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 */
+
+/* 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_
+
+/* RTC tamper and alternate function configuration register */
+
+#define RTC_TAFCR_CALM_SHIFT (0) /* Bits 0-8: Calibration minus */
+#define RTC_TAFCR_CALM_MASK (0x1ff << RTC_TAFCR_CALM_SHIFT)
+#define RTC_TAFCR_CALW16 (1 << 13) /* Bit 13: Use a 16-second calibration cycle period */
+#define RTC_TAFCR_CALW8 (1 << 14) /* Bit 14: Use an 8-second calibration cycle period */
+#define RTC_TAFCR_CALP (1 << 15) /* Bit 15: Increase frequency of RTC by 488.5 ppm */
+
+/* RTC alarm A/B sub second register */
+
+#define RTC_ALRMSSR_SS_SHIFT (0) /* Bits 0-15: Sub second value */
+#define RTC_ALRMSSR_SS_MASK (0xffff << RTC_ALRMSSR_SS_SHIFT)
+#define RTC_ALRMSSR_MASKSS_SHIFT (0) /* Bits 24-27: Mask the most-significant bits starting at this bit */
+#define RTC_ALRMSSR_MASKSS_MASK (0xffff << RTC_ALRMSSR_SS_SHIFT)
+
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_RTC_H */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_vectors.h b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_vectors.h
new file mode 100644
index 000000000..8db1bd19e
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_vectors.h
@@ -0,0 +1,142 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32f40xxx_vectors.h
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 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 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 */
+VECTOR(stm32_fpu, STM32_IRQ_FPU) /* Vector 16+81: FPU global interrupt */
+
+#endif /* CONFIG_ARMV7M_CMNVECTOR */
diff --git a/nuttx/arch/arm/src/stm32/stm32.h b/nuttx/arch/arm/src/stm32/stm32.h
new file mode 100644
index 000000000..44a23aece
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32.h
@@ -0,0 +1,103 @@
+/************************************************************************************
+ * 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 <uros.platise@isotel.eu>
+ * Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#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_QENCODER
+#endif
+
+/* NVIC priority levels *************************************************************/
+
+#define NVIC_SYSH_PRIORITY_MIN 0xff /* 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 */
+
+/* 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_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/nuttx/arch/arm/src/stm32/stm32_adc.c b/nuttx/arch/arm/src/stm32/stm32_adc.c
new file mode 100644
index 000000000..777f624aa
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_adc.c
@@ -0,0 +1,1542 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_adc.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ * Diego Sanchez <dsanchez@nx-engineering.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 <nuttx/config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <string.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+#include <unistd.h>
+
+#include <arch/board/board.h>
+#include <nuttx/arch.h>
+#include <nuttx/analog/adc.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "stm32_internal.h"
+#include "stm32_adc.h"
+
+#ifdef CONFIG_ADC
+#if defined(CONFIG_STM32_ADC1) || defined(CONFIG_STM32_ADC2) || defined(CONFIG_STM32_ADC3)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+/* ADC interrupts ***********************************************************/
+
+#ifdef CONFIG_STM32_STM32F10XX
+# define ADC_SR_ALLINTS (ADC_SR_AWD | ADC_SR_EOC | ADC_SR_JEOC)
+#else
+# define ADC_SR_ALLINTS (ADC_SR_AWD | ADC_SR_EOC | ADC_SR_JEOC | ADC_SR_OVR)
+#endif
+
+#ifdef CONFIG_STM32_STM32F10XX
+# define ADC_CR1_ALLINTS (ADC_CR1_AWDIE | ADC_CR1_EOCIE | ADC_CR1_JEOCIE)
+#else
+# define ADC_CR1_ALLINTS (ADC_CR1_AWDIE | ADC_CR1_EOCIE | ADC_CR1_JEOCIE | ADC_CR1_OVRIE)
+#endif
+
+/* 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
+#else
+# define ADC_MAX_SAMPLES 1
+#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 intf; /* ADC interface number */
+ uint8_t current; /* Current ADC channel being converted */
+#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
+ uint8_t chanlist[ADC_MAX_SAMPLES];
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* ADC Register access */
+
+static uint32_t adc_getreg(struct stm32_dev_s *priv, int offset);
+static void adc_putreg(struct stm32_dev_s *priv, int offset, uint32_t value);
+#ifdef ADC_HAVE_TIMER
+static uint16_t tim_getreg(struct stm32_dev_s *priv, int offset);
+static void tim_putreg(struct stm32_dev_s *priv, int offset, uint16_t value);
+static void adc_tim_dumpregs(struct stm32_dev_s *priv, FAR const char *msg);
+#endif
+static void adc_rccreset(struct stm32_dev_s *priv, bool reset);
+
+/* ADC Interrupt Handler */
+
+static int adc_interrupt(FAR struct adc_dev_s *dev);
+#if defined(CONFIG_STM32_STM32F10XX) && (defined(CONFIG_STM32_ADC1) || defined(CONFIG_STM32_ADC2))
+static int adc12_interrupt(int irq, void *context);
+#endif
+#if defined(CONFIG_STM32_STM32F10XX) && defined (CONFIG_STM32_ADC3)
+static int adc3_interrupt(int irq, void *context);
+#endif
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+static int adc123_interrupt(int irq, 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);
+
+#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
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+static void adc_startconv(FAR struct stm32_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_STM32_ADC1
+static struct stm32_dev_s g_adcpriv1 =
+{
+#ifdef CONFIG_STM32_STM32F10XX
+ .irq = STM32_IRQ_ADC12,
+ .isr = adc12_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
+};
+
+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 =
+{
+#ifdef CONFIG_STM32_STM32F10XX
+ .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
+};
+
+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 =
+{
+#ifdef CONFIG_STM32_STM32F10XX
+ .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
+};
+
+static struct adc_dev_s g_adcdev3 =
+{
+ .ad_ops = &g_adcops,
+ .ad_priv= &g_adcpriv3,
+};
+#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 stm32_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 stm32_dev_s *priv, int offset, uint32_t value)
+{
+ putreg32(value, priv->base + offset);
+}
+
+/****************************************************************************
+ * 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(struct stm32_dev_s *priv, int offset)
+{
+ return getreg16(priv->tbase + offset);
+}
+#endif
+
+/****************************************************************************
+ * Name: tim_putreg
+ *
+ * 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:
+ * None
+ *
+ ****************************************************************************/
+
+#ifdef ADC_HAVE_TIMER
+static void tim_putreg(struct stm32_dev_s *priv, int offset, uint16_t value)
+{
+ putreg16(value, priv->tbase + offset);
+}
+#endif
+
+/****************************************************************************
+ * 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 stm32_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, 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));
+
+ 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(struct stm32_dev_s *priv, bool enable)
+{
+ uint16_t regval;
+
+ avdbg("enable: %d\n", enable);
+ regval = tim_getreg(priv, STM32_GTIM_CR1_OFFSET);
+
+ if (enable)
+ {
+ /* Start the counter */
+
+ regval |= ATIM_CR1_CEN;
+ }
+
+ else
+ {
+ /* Disable the counter */
+
+ regval &= ~ATIM_CR1_CEN;
+ }
+ tim_putreg(priv, STM32_GTIM_CR1_OFFSET, regval);
+}
+#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 regval;
+ uint32_t timclk;
+
+ uint16_t cr1;
+ uint16_t cr2;
+ uint16_t ccmr1;
+ uint16_t ccmr2;
+ uint16_t ocmode1;
+ uint16_t ocmode2;
+ uint16_t ccenable;
+ uint16_t ccer;
+ uint16_t egr;
+
+ avdbg("Initializing timers extsel = %d\n", priv->extsel);
+
+ /* If the timer base address is zero, then this ADC was not configured to
+ * use a timer.
+ */
+
+ regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET);
+
+#ifdef CONFIG_STM32_STM32F10XX
+ if (!priv->tbase)
+ {
+ /* Configure the ADC to use the selected timer and timer channel as the trigger
+ * EXTTRIG: External Trigger Conversion mode for regular channels DISABLE
+ */
+
+ regval &= ~ADC_CR2_EXTTRIG;
+ adc_putreg(priv, STM32_ADC_CR2_OFFSET, regval);
+ return OK;
+ }
+ else
+ {
+ regval |= ADC_CR2_EXTTRIG;
+ }
+#endif
+
+ /* EXTSEL selection: These bits select the external event used to trigger
+ * the start of conversion of a regular group. NOTE:
+ *
+ * - The position with with of the EXTSEL field varies from one STM32 MCU
+ * to another.
+ * - The width of the EXTSEL field varies from one STM3 MCU to another.
+ * - The value in priv->extsel is already shifted into the correct bit position.
+ */
+
+ regval &= ~ADC_CR2_EXTSEL_MASK;
+ regval |= priv->extsel;
+ adc_putreg(priv, STM32_ADC_CR2_OFFSET, regval);
+
+ /* 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;
+ }
+
+ /* Set up the timer CR1 register */
+
+ cr1 = tim_getreg(priv, STM32_GTIM_CR1_OFFSET);
+
+ /* Disable the timer until we get it configured */
+
+ adc_timstart(priv, false);
+
+ /* 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
+ */
+
+ cr1 &= ~(ATIM_CR1_DIR | ATIM_CR1_CMS_MASK);
+ cr1 |= ATIM_CR1_EDGE;
+
+ /* Set the clock division to zero for all */
+
+ cr1 &= ~GTIM_CR1_CKD_MASK;
+ tim_putreg(priv, STM32_GTIM_CR1_OFFSET, cr1);
+
+ /* 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 repitition counter in TIM1 */
+
+ 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 */
+ }
+
+ /* TIMx event generation: Bit 0 UG: Update generation */
+
+ tim_putreg(priv, STM32_GTIM_EGR_OFFSET, ATIM_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 */
+ {
+#warning "TRGO support not yet implemented"
+
+ /* Set the event TRGO */
+
+ 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 cr1 and 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;
+
+ if (priv->tbase == STM32_TIM1_BASE || priv->tbase == STM32_TIM8_BASE)
+ {
+ /* Reset output N polarity level, output N state, output compre state,
+ * output compare N idle state.
+ */
+#if defined(CONFIG_STM32_STM32F20XX) || 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_STM32F40XX)
+ else
+ {
+ ccer &= ~(GTIM_CCER_CC1NP | GTIM_CCER_CC2NP | GTIM_CCER_CC3NP | GTIM_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 */
+
+ cr1 = tim_getreg(priv, STM32_GTIM_CR1_OFFSET);
+ cr1 |= GTIM_CR1_ARPE;
+ tim_putreg(priv, STM32_GTIM_CR1_OFFSET, cr1);
+
+ /* Enable the timer counter
+ * All but the CEN bit with the default config in CR1
+ */
+
+ adc_timstart(priv, true);
+
+ adc_tim_dumpregs(priv, "After starting Timers");
+
+ return OK;
+}
+#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_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+static void adc_startconv(struct stm32_dev_s *priv, bool enable)
+{
+ uint32_t regval;
+
+ avdbg("enable: %d\n", enable);
+
+ regval = adc_getreg(priv, STM32_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, STM32_ADC_CR2_OFFSET,regval);
+}
+#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(struct stm32_dev_s *priv, bool reset)
+{
+ irqstate_t flags;
+ uint32_t regval;
+ uint32_t adcbit;
+
+ /* Pick the appropriate bit in the APB2 reset register */
+
+#ifdef CONFIG_STM32_STM32F10XX
+ /* For the STM32 F1, there is an individual bit to reset each ADC. */
+
+ switch (priv->intf)
+ {
+#ifdef CONFIG_STM32_ADC1
+ case 1:
+ adcbit = RCC_APB2RSTR_ADC1RST;
+ break;
+#endif
+#ifdef CONFIG_STM32_ADC2
+ case 2:
+ adcbit = RCC_APB2RSTR_ADC2RST;
+ break;
+#endif
+#ifdef CONFIG_STM32_ADC3
+ case 3:
+ adcbit = RCC_APB2RSTR_ADC3RST;
+ break;
+#endif
+ default:
+ return;
+ }
+
+#else
+ /* For the STM32 F4, there is one common reset for all ADC block.
+ * THIS will probably cause some problems!
+ */
+
+ adcbit = RCC_APB2RSTR_ADCRST;
+#endif
+
+ /* Disable interrupts. This is necessary because the APB2RTSR register
+ * is used by several different drivers.
+ */
+
+ flags = irqsave();
+
+ /* Set or clear the selected bit in the APB2 reset register */
+
+ regval = getreg32(STM32_RCC_APB2RSTR);
+ if (reset)
+ {
+ /* Enable ADC reset state */
+
+ regval |= adcbit;
+ }
+ else
+ {
+ /* Release ADC from reset state */
+
+ regval &= ~adcbit;
+ }
+ putreg32(regval, STM32_RCC_APB2RSTR);
+ irqrestore(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 stm32_dev_s *priv, bool enable)
+{
+ uint32_t regval;
+
+ avdbg("enable: %d\n", enable);
+
+ regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET);
+ if (enable)
+ {
+ regval |= ADC_CR2_ADON;
+ }
+ else
+ {
+ regval &= ~ADC_CR2_ADON;
+ }
+ adc_putreg(priv, STM32_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 stm32_dev_s *priv = (FAR struct stm32_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 = irqsave();
+
+ /* Enable ADC reset state */
+
+ adc_rccreset(priv, true);
+
+ /* Release ADC from reset state */
+
+ adc_rccreset(priv, false);
+
+ /* Initialize the ADC data structures */
+
+ /* 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);
+
+ /* 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, STM32_ADC_SMPR1_OFFSET, 0x00b6db6d);
+ adc_putreg(priv, STM32_ADC_SMPR2_OFFSET, 0x00b6db6d);
+
+ /* ADC CR1 Configuration */
+
+ regval = adc_getreg(priv, STM32_ADC_CR1_OFFSET);
+
+ /* Set mode configuration (Independent mode) */
+
+#ifdef CONFIG_STM32_STM32F10XX
+ regval |= ADC_CR1_IND;
+#endif
+
+ /* Initialize the Analog watchdog enable */
+
+ regval |= ADC_CR1_AWDEN;
+ regval |= (priv->chanlist[0] << ADC_CR1_AWDCH_SHIFT);
+
+ /* Enable interrupt flags */
+
+ regval |= ADC_CR1_ALLINTS;
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+
+ /* Enable or disable Overrun interrupt */
+
+ regval &= ~ADC_CR1_OVRIE;
+
+ /* Set the resolution of the conversion */
+
+ regval |= ACD_CR1_RES_12BIT;
+#endif
+
+ adc_putreg(priv, STM32_ADC_CR1_OFFSET, regval);
+
+ /* ADC CR2 Configuration */
+
+ regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET);
+
+ /* Clear CONT, continuous mode disable */
+
+ regval &= ~ADC_CR2_CONT;
+
+ /* Set ALIGN (Right = 0) */
+
+ regval &= ~ADC_CR2_ALIGN;
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+ /* External trigger enable for regular channels */
+
+ regval |= ACD_CR2_EXTEN_RISING;
+#endif
+
+ adc_putreg(priv, STM32_ADC_CR2_OFFSET, regval);
+
+ /* Configuration of the channel conversions */
+
+ regval = adc_getreg(priv, STM32_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, STM32_ADC_SQR3_OFFSET, regval);
+
+ regval = adc_getreg(priv, STM32_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, STM32_ADC_SQR2_OFFSET, regval);
+
+ regval = adc_getreg(priv, STM32_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 */
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+ regval = getreg32(STM32_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, STM32_ADC_CCR);
+#endif
+
+ /* Set the number of conversions */
+
+ DEBUGASSERT(priv->nchannels <= ADC_MAX_SAMPLES);
+
+ regval |= (((uint32_t)priv->nchannels-1) << ADC_SQR1_L_SHIFT);
+ adc_putreg(priv, STM32_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);
+
+#ifdef ADC_HAVE_TIMER
+ ret = adc_timinit(priv);
+ if (ret!=OK)
+ {
+ adbg("Error initializing the timers\n");
+ }
+#else
+#ifdef CONFIG_STM32_STM32F10XX
+ /* Set ADON (Again) to start the conversion. Only if Timers are not
+ * configured as triggers
+ */
+
+ adc_enable(priv, true);
+#else
+ adc_startconv(priv, true);
+#endif /* CONFIG_STM32_STM32F10XX */
+#endif /* ADC_HAVE_TIMER */
+
+ irqrestore(flags);
+
+ 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));
+ 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_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+ avdbg("CCR: 0x%08x\n",
+ getreg32(STM32_ADC_CCR));
+#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 == OK)
+ {
+ /* 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;
+
+ /* 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;
+ uint32_t regval;
+
+ avdbg("intf: %d enable: %d\n", priv->intf, enable);
+
+ regval = adc_getreg(priv, STM32_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, STM32_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 stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
+ uint32_t adcsr;
+ int32_t value;
+
+ /* Identifies the interruption AWD, OVR or EOC */
+
+ adcsr = adc_getreg(priv, STM32_ADC_SR_OFFSET);
+ if ((adcsr & ADC_SR_AWD) != 0)
+ {
+ alldbg("WARNING: Analog Watchdog, Value converted out of range!\n");
+ }
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+ if ((adcsr & ADC_SR_OVR) != 0)
+ {
+ alldbg("WARNING: Overrun has ocurred!\n");
+ }
+#endif
+
+ /* 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, STM32_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;
+}
+
+/****************************************************************************
+ * Name: adc12_interrupt
+ *
+ * Description:
+ * ADC12 interrupt handler for the STM32 F1 family.
+ *
+ * Input Parameters:
+ *
+ * Returned Value:
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_STM32_STM32F10XX) && (defined(CONFIG_STM32_ADC1) || defined(CONFIG_STM32_ADC2))
+static int adc12_interrupt(int irq, void *context)
+{
+ uint32_t regval;
+ uint32_t pending;
+
+ /* Check for pending ADC1 interrupts */
+
+#ifdef CONFIG_STM32_ADC1
+ regval = getreg32(STM32_ADC1_SR);
+ pending = regval & ADC_SR_ALLINTS;
+ if (pending != 0)
+ {
+ adc_interrupt(&g_adcdev1);
+ regval &= ~pending;
+ putreg32(regval, STM32_ADC1_SR);
+ }
+#endif
+
+ /* Check for pending ADC2 interrupts */
+
+#ifdef CONFIG_STM32_ADC2
+ regval = getreg32(STM32_ADC2_SR);
+ pending = regval & ADC_SR_ALLINTS;
+ if (pending != 0)
+ {
+ adc_interrupt(&g_adcdev2);
+ regval &= ~pending;
+ putreg32(regval, STM32_ADC2_SR);
+ }
+#endif
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: adc3_interrupt
+ *
+ * Description:
+ * ADC1/2 interrupt handler for the STM32 F1 family.
+ *
+ * Input Parameters:
+ *
+ * Returned Value:
+ *
+ ****************************************************************************/
+
+#if defined (CONFIG_STM32_STM32F10XX) && defined (CONFIG_STM32_ADC3)
+static int adc3_interrupt(int irq, void *context)
+{
+ uint32_t regval;
+ uint32_t pending;
+
+ /* Check for pending ADC3 interrupts */
+
+ regval = getreg32(STM32_ADC3_SR);
+ pending = regval & ADC_SR_ALLINTS;
+ if (pending != 0)
+ {
+ adc_interrupt(&g_adcdev3);
+ regval &= ~pending;
+ putreg32(regval, STM32_ADC3_SR);
+ }
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: adc123_interrupt
+ *
+ * Description:
+ * ADC1/2/3 interrupt handler for the STM32 F4 family.
+ *
+ * Input Parameters:
+ *
+ * Returned Value:
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+static int adc123_interrupt(int irq, void *context)
+{
+ uint32_t regval;
+ uint32_t pending;
+
+ /* Check for pending ADC1 interrupts */
+
+#ifdef CONFIG_STM32_ADC1
+ regval = getreg32(STM32_ADC1_SR);
+ pending = regval & ADC_SR_ALLINTS;
+ if (pending != 0)
+ {
+ adc_interrupt(&g_adcdev1);
+ regval &= ~pending;
+ putreg32(regval, STM32_ADC1_SR);
+ }
+#endif
+
+ /* Check for pending ADC2 interrupts */
+
+#ifdef CONFIG_STM32_ADC2
+ regval = getreg32(STM32_ADC2_SR);
+ pending = regval & ADC_SR_ALLINTS;
+ if (pending != 0)
+ {
+ adc_interrupt(&g_adcdev2);
+ regval &= ~pending;
+ putreg32(regval, STM32_ADC2_SR);
+ }
+#endif
+
+ /* Check for pending ADC3 interrupts */
+
+#ifdef CONFIG_STM32_ADC3
+ regval = getreg32(STM32_ADC3_SR);
+ pending = regval & ADC_SR_ALLINTS;
+ if (pending != 0)
+ {
+ adc_interrupt(&g_adcdev3);
+ regval &= ~pending;
+ putreg32(regval, STM32_ADC3_SR);
+ }
+#endif
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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
+ * nchannels - Number of channels
+ *
+ * Returned Value:
+ * Valid ADC device structure reference on succcess; a NULL on failure
+ *
+ ****************************************************************************/
+
+struct adc_dev_s *stm32_adcinitialize(int intf, const uint8_t *chanlist, int nchannels)
+{
+ FAR struct adc_dev_s *dev;
+ FAR struct stm32_dev_s *priv;
+
+ avdbg("intf: %d nchannels: %d\n", intf, nchannels);
+
+#ifdef CONFIG_STM32_ADC1
+ if (intf == 1)
+ {
+ avdbg("ADC1 Selected\n");
+ dev = &g_adcdev1;
+ }
+ else
+#endif
+#ifdef CONFIG_STM32_ADC2
+ if (intf == 2)
+ {
+ avdbg("ADC2 Selected\n");
+ dev = &g_adcdev2;
+ }
+ else
+#endif
+#ifdef CONFIG_STM32_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_STM32_ADC || CONFIG_STM32_ADC2 || CONFIG_STM32_ADC3 */
+#endif /* CONFIG_ADC */
+
diff --git a/nuttx/arch/arm/src/stm32/stm32_adc.h b/nuttx/arch/arm/src/stm32/stm32_adc.h
new file mode 100644
index 000000000..34f29020c
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_adc.h
@@ -0,0 +1,602 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_adc.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "chip/stm32_adc.h"
+
+#include <nuttx/analog/adc.h>
+
+/************************************************************************************
+ * 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 STM32 F4 line, timers 1-5 and
+ * 8 may be used.
+ */
+
+#ifndef CONFIG_STM32_TIM1
+# undef CONFIG_STM32_TIM1_ADC
+# undef CONFIG_STM32_TIM1_ADC1
+# undef CONFIG_STM32_TIM1_ADC2
+# undef CONFIG_STM32_TIM1_ADC3
+#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
+#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
+#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
+#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
+# endif
+# ifndef CONFIG_STM32_TIM8
+# undef CONFIG_STM32_TIM8_ADC
+# undef CONFIG_STM32_TIM8_ADC1
+# undef CONFIG_STM32_TIM8_ADC2
+# undef CONFIG_STM32_TIM8_ADC3
+# 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_TIM8_ADC
+# undef CONFIG_STM32_TIM8_ADC1
+# undef CONFIG_STM32_TIM8_ADC2
+# undef CONFIG_STM32_TIM8_ADC3
+#endif
+
+/* Timers 6, 7, and 10-14 are not used with the ADC by any supported family */
+
+#undef CONFIG_STM32_TIM6_ADC
+#undef CONFIG_STM32_TIM6_ADC1
+#undef CONFIG_STM32_TIM6_ADC2
+#undef CONFIG_STM32_TIM6_ADC3
+#undef CONFIG_STM32_TIM7_ADC
+#undef CONFIG_STM32_TIM7_ADC1
+#undef CONFIG_STM32_TIM7_ADC2
+#undef CONFIG_STM32_TIM7_ADC3
+#undef CONFIG_STM32_TIM9_ADC
+#undef CONFIG_STM32_TIM9_ADC1
+#undef CONFIG_STM32_TIM9_ADC2
+#undef CONFIG_STM32_TIM9_ADC3
+#undef CONFIG_STM32_TIM10_ADC
+#undef CONFIG_STM32_TIM10_ADC1
+#undef CONFIG_STM32_TIM10_ADC2
+#undef CONFIG_STM32_TIM10_ADC3
+#undef CONFIG_STM32_TIM11_ADC
+#undef CONFIG_STM32_TIM11_ADC1
+#undef CONFIG_STM32_TIM11_ADC2
+#undef CONFIG_STM32_TIM11_ADC3
+#undef CONFIG_STM32_TIM12_ADC
+#undef CONFIG_STM32_TIM12_ADC1
+#undef CONFIG_STM32_TIM12_ADC2
+#undef CONFIG_STM32_TIM12_ADC3
+#undef CONFIG_STM32_TIM13_ADC
+#undef CONFIG_STM32_TIM13_ADC1
+#undef CONFIG_STM32_TIM13_ADC2
+#undef CONFIG_STM32_TIM13_ADC3
+#undef CONFIG_STM32_TIM14_ADC
+#undef CONFIG_STM32_TIM14_ADC1
+#undef CONFIG_STM32_TIM14_ADC2
+#undef CONFIG_STM32_TIM14_ADC3
+
+/* Up to 3 ADC interfaces are supported */
+
+#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)
+
+/* 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_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_TIM8_ADC1)
+# define ADC1_HAVE_TIMER 1
+# define ADC1_TIMER_BASE STM32_TIM8_BASE
+# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB2_TIM8_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_TIM8_ADC2)
+# define ADC2_HAVE_TIMER 1
+# define ADC2_TIMER_BASE STM32_TIM8_BASE
+# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB2_TIM8_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_TIM8_ADC3)
+# define ADC3_HAVE_TIMER 1
+# define ADC3_TIMER_BASE STM32_TIM8_BASE
+# define ADC3_TIMER_PCLK_FREQUENCY STM32_APB2_TIM8_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(ADC1_HAVE_TIMER) || defined(ADC2_HAVE_TIMER) || defined(ADC3_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 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_STM32_TIM1_ADC1)
+# if CONFIG_STM32_ADC1_TIMTRIG == 0
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC1
+# elif CONFIG_STM32_ADC1_TIMTRIG == 1
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC2
+# elif CONFIG_STM32_ADC1_TIMTRIG == 2
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC3
+# elif CONFIG_STM32_ADC1_TIMTRIG == 3
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC4
+# elif CONFIG_STM32_ADC1_TIMTRIG == 4
+# define ADC1_EXTSEL_VALUE ADC_CR2_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 ADC_CR2_EXTSEL_T2CC1
+# elif CONFIG_STM32_ADC1_TIMTRIG == 1
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC2
+# elif CONFIG_STM32_ADC1_TIMTRIG == 2
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC3
+# elif CONFIG_STM32_ADC1_TIMTRIG == 3
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC4
+# elif CONFIG_STM32_ADC1_TIMTRIG == 4
+# define ADC1_EXTSEL_VALUE ADC_CR2_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 ADC_CR2_EXTSEL_T3CC1
+# elif CONFIG_STM32_ADC1_TIMTRIG == 1
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC2
+# elif CONFIG_STM32_ADC1_TIMTRIG == 2
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC3
+# elif CONFIG_STM32_ADC1_TIMTRIG == 3
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC4
+# elif CONFIG_STM32_ADC1_TIMTRIG == 4
+# define ADC1_EXTSEL_VALUE ADC_CR2_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 ADC_CR2_EXTSEL_T4CC1
+# elif CONFIG_STM32_ADC1_TIMTRIG == 1
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC2
+# elif CONFIG_STM32_ADC1_TIMTRIG == 2
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC3
+# elif CONFIG_STM32_ADC1_TIMTRIG == 3
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC4
+# elif CONFIG_STM32_ADC1_TIMTRIG == 4
+# define ADC1_EXTSEL_VALUE ADC_CR2_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 ADC_CR2_EXTSEL_T5CC1
+# elif CONFIG_STM32_ADC1_TIMTRIG == 1
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC2
+# elif CONFIG_STM32_ADC1_TIMTRIG == 2
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC3
+# elif CONFIG_STM32_ADC1_TIMTRIG == 3
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC4
+# elif CONFIG_STM32_ADC1_TIMTRIG == 4
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T5TRGO
+# 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 ADC_CR2_EXTSEL_T8CC1
+# elif CONFIG_STM32_ADC1_TIMTRIG == 1
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC2
+# elif CONFIG_STM32_ADC1_TIMTRIG == 2
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC3
+# elif CONFIG_STM32_ADC1_TIMTRIG == 3
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC4
+# elif CONFIG_STM32_ADC1_TIMTRIG == 4
+# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T8TRGO
+# 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 ADC_CR2_EXTSEL_T1CC1
+# elif CONFIG_STM32_ADC2_TIMTRIG == 1
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC2
+# elif CONFIG_STM32_ADC2_TIMTRIG == 2
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC3
+# elif CONFIG_STM32_ADC2_TIMTRIG == 3
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC4
+# elif CONFIG_STM32_ADC2_TIMTRIG == 4
+# define ADC2_EXTSEL_VALUE ADC_CR2_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 ADC_CR2_EXTSEL_T2CC1
+# elif CONFIG_STM32_ADC2_TIMTRIG == 1
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC2
+# elif CONFIG_STM32_ADC2_TIMTRIG == 2
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC3
+# elif CONFIG_STM32_ADC2_TIMTRIG == 3
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC4
+# elif CONFIG_STM32_ADC2_TIMTRIG == 4
+# define ADC2_EXTSEL_VALUE ADC_CR2_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 ADC_CR2_EXTSEL_T3CC1
+# elif CONFIG_STM32_ADC2_TIMTRIG == 1
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC2
+# elif CONFIG_STM32_ADC2_TIMTRIG == 2
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC3
+# elif CONFIG_STM32_ADC2_TIMTRIG == 3
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC4
+# elif CONFIG_STM32_ADC2_TIMTRIG == 4
+# define ADC2_EXTSEL_VALUE ADC_CR2_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 ADC_CR2_EXTSEL_T4CC1
+# elif CONFIG_STM32_ADC2_TIMTRIG == 1
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC2
+# elif CONFIG_STM32_ADC2_TIMTRIG == 2
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC3
+# elif CONFIG_STM32_ADC2_TIMTRIG == 3
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC4
+# elif CONFIG_STM32_ADC2_TIMTRIG == 4
+# define ADC2_EXTSEL_VALUE ADC_CR2_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 ADC_CR2_EXTSEL_T5CC1
+# elif CONFIG_STM32_ADC2_TIMTRIG == 1
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC2
+# elif CONFIG_STM32_ADC2_TIMTRIG == 2
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC3
+# elif CONFIG_STM32_ADC2_TIMTRIG == 3
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC4
+# elif CONFIG_STM32_ADC2_TIMTRIG == 4
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T5TRGO
+# 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 ADC_CR2_EXTSEL_T8CC1
+# elif CONFIG_STM32_ADC2_TIMTRIG == 1
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC2
+# elif CONFIG_STM32_ADC2_TIMTRIG == 2
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC3
+# elif CONFIG_STM32_ADC2_TIMTRIG == 3
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC4
+# elif CONFIG_STM32_ADC2_TIMTRIG == 4
+# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T8TRGO
+# 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 ADC_CR2_EXTSEL_T1CC1
+# elif CONFIG_STM32_ADC3_TIMTRIG == 1
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC2
+# elif CONFIG_STM32_ADC3_TIMTRIG == 2
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC3
+# elif CONFIG_STM32_ADC3_TIMTRIG == 3
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC4
+# elif CONFIG_STM32_ADC3_TIMTRIG == 4
+# define ADC3_EXTSEL_VALUE ADC_CR2_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 ADC_CR2_EXTSEL_T2CC1
+# elif CONFIG_STM32_ADC3_TIMTRIG == 1
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC2
+# elif CONFIG_STM32_ADC3_TIMTRIG == 2
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC3
+# elif CONFIG_STM32_ADC3_TIMTRIG == 3
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC4
+# elif CONFIG_STM32_ADC3_TIMTRIG == 4
+# define ADC3_EXTSEL_VALUE ADC_CR2_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 ADC_CR2_EXTSEL_T3CC1
+# elif CONFIG_STM32_ADC3_TIMTRIG == 1
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC2
+# elif CONFIG_STM32_ADC3_TIMTRIG == 2
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC3
+# elif CONFIG_STM32_ADC3_TIMTRIG == 3
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC4
+# elif CONFIG_STM32_ADC3_TIMTRIG == 4
+# define ADC3_EXTSEL_VALUE ADC_CR2_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 ADC_CR2_EXTSEL_T4CC1
+# elif CONFIG_STM32_ADC3_TIMTRIG == 1
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC2
+# elif CONFIG_STM32_ADC3_TIMTRIG == 2
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC3
+# elif CONFIG_STM32_ADC3_TIMTRIG == 3
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC4
+# elif CONFIG_STM32_ADC3_TIMTRIG == 4
+# define ADC3_EXTSEL_VALUE ADC_CR2_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 ADC_CR2_EXTSEL_T5CC1
+# elif CONFIG_STM32_ADC3_TIMTRIG == 1
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC2
+# elif CONFIG_STM32_ADC3_TIMTRIG == 2
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC3
+# elif CONFIG_STM32_ADC3_TIMTRIG == 3
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC4
+# elif CONFIG_STM32_ADC3_TIMTRIG == 4
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T5TRGO
+# 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 ADC_CR2_EXTSEL_T8CC1
+# elif CONFIG_STM32_ADC3_TIMTRIG == 1
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC2
+# elif CONFIG_STM32_ADC3_TIMTRIG == 2
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC3
+# elif CONFIG_STM32_ADC3_TIMTRIG == 3
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC4
+# elif CONFIG_STM32_ADC3_TIMTRIG == 4
+# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T8TRGO
+# else
+# error "CONFIG_STM32_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: 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;
+EXTERN struct adc_dev_s *stm32_adcinitialize(int intf, const uint8_t *chanlist,
+ int nchannels);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_STM32_ADC || CONFIG_STM32_ADC2 || CONFIG_STM32_ADC3 */
+#endif /* __ARCH_ARM_SRC_STM32_STM32_ADC_H */
+
diff --git a/nuttx/arch/arm/src/stm32/stm32_allocateheap.c b/nuttx/arch/arm/src/stm32/stm32_allocateheap.c
new file mode 100644
index 000000000..4b8707a2b
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_allocateheap.c
@@ -0,0 +1,324 @@
+/****************************************************************************
+ * arch/arm/src/stm32/up_allocateheap.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/mm.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Private 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_DRAM_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
+
+/* For the STM312F10xxx family, all internal SRAM is in one contiguous block
+ * starting at g_heapbase and extending through CONFIG_DRAM_END (my apologies for
+ * the bad naming). In addition, external FSMC SRAM may be available.
+ */
+
+#if defined(CONFIG_STM32_STM32F10XX)
+
+ /* Set the end of system SRAM */
+
+# define SRAM1_END CONFIG_DRAM_END
+
+ /* Check if external FSMC SRAM is provided */
+
+# if 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
+
+/* All members of the STM32F20xxx and STM32F40xxx families have 192Kb in three banks:
+ *
+ * 1) 112Kb of System SRAM beginning at address 0x2000:0000
+ * 2) 16Kb of System SRAM beginning at address 0x2001:c000
+ * 3) 64Kb of CCM SRAM beginning at address 0x1000:0000
+ *
+ * As determined by ld.script, g_heapbase lies in the 112Kb 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.
+ *
+ * As a complication, it appears that CCM SRAM cannot be used for DMA. So, if
+ * STM32 DMA is enabled, CCM SRAM should probably be excluded from the heap.
+ *
+ * In addition, external FSMC SRAM may be available.
+ */
+
+#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+
+
+ /* The STM32 F2 has no CCM SRAM */
+
+# ifdef CONFIG_STM32_STM32F20XX
+# undef CONFIG_STM32_CCMEXCLUDE
+# define CONFIG_STM32_CCMEXCLUDE 1
+# endif
+
+ /* Set the end of system SRAM */
+
+# define SRAM1_END 0x20020000
+
+ /* 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 consitent 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
+# error "CCM SRAM excluded from the heap because CONFIG_MM_REGIONS < 2"
+# 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_allocate_heap
+ *
+ * Description:
+ * The heap may be statically allocated by
+ * defining CONFIG_HEAP_BASE and CONFIG_HEAP_SIZE. If these
+ * are not defined, then this function will be called to
+ * dynamically set aside the heap region.
+ *
+ ****************************************************************************/
+
+void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
+{
+ up_ledon(LED_HEAPALLOCATE);
+ *heap_start = (FAR void*)g_heapbase;
+ *heap_size = SRAM1_END - g_heapbase;
+}
+
+/****************************************************************************
+ * 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)
+{
+ /* Add the STM32F20xxx/STM32F40xxx CCM SRAM heap region. */
+
+#ifndef CONFIG_STM32_CCMEXCLUDE
+ mm_addregion((FAR void*)SRAM2_START, SRAM2_END-SRAM2_START);
+#endif
+
+ /* Add the external FSMC SRAM heap region. */
+
+#ifdef CONFIG_STM32_FSMC_SRAM
+ mm_addregion((FAR void*)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE);
+#endif
+}
+#endif
diff --git a/nuttx/arch/arm/src/stm32/stm32_bkp.h b/nuttx/arch/arm/src/stm32/stm32_bkp.h
new file mode 100644
index 000000000..21399c38b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "chip/stm32_bkp.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_STM32_STM32_BKP_H */
diff --git a/nuttx/arch/arm/src/stm32/stm32_can.c b/nuttx/arch/arm/src/stm32/stm32_can.c
new file mode 100644
index 000000000..bed2a80f6
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_can.c
@@ -0,0 +1,1636 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_can.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+#include <nuttx/arch.h>
+#include <nuttx/can.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "os_internal.h"
+
+#include "chip.h"
+#include "stm32_internal.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 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 void can_putreg(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,
+#if defined(CONFIG_STM32_STM32F10XX) && !defined(CONFIG_STM32_CONNECTIVITYLINE)
+ .canrx0 = STM32_IRQ_USBLPCANRX0,
+ .cantx = STM32_IRQ_USBHPCANTX,
+#else
+ .canrx0 = STM32_IRQ_CAN1RX0,
+ .cantx = STM32_IRQ_CAN1TX,
+#endif
+ .filter = 0,
+ .base = 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,
+ .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
+ *
+ * Description:
+ * Read the value of an CAN 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 stm32_can_s *priv, int offset)
+{
+ static uint32_t prevaddr = 0;
+ static uint32_t preval = 0;
+ static uint32_t count = 0;
+ uint32_t addr = priv->base + offset;
+
+ /* 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;
+}
+#else
+static uint32_t can_getreg(struct stm32_can_s *priv, int offset)
+{
+ return getreg32(priv->base + offset);
+}
+#endif
+
+/****************************************************************************
+ * Name: can_putreg
+ *
+ * Description:
+ * Set the value of an CAN 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 stm32_can_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 stm32_can_s *priv, int offset, uint32_t value)
+{
+ putreg32(value, priv->base + 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_FR_OFFSET(i,1)),
+ i, getreg32(priv->base + STM32_CAN_FR_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 = irqsave();
+
+ /* Reset the CAN */
+
+ regval = getreg32(STM32_RCC_APB1RSTR);
+ regval |= regbit;
+ putreg32(regval, STM32_RCC_APB1RSTR);
+
+ regval &= ~regbit;
+ putreg32(regval, STM32_RCC_APB1RSTR);
+ irqrestore(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)
+ {
+ txmb = 0;
+ }
+ else if ((regval & CAN_TSR_TME1) != 0)
+ {
+ txmb = 1;
+ }
+ else if ((regval & CAN_TSR_TME2) != 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(OSERR_UNEXPECTEDISR);
+ }
+#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
+
+ /* 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 OK;
+}
+
+/****************************************************************************
+ * 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(OSERR_UNEXPECTEDISR);
+ }
+#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);
+ }
+ }
+
+ /* Were all transmissions complete in all mailboxes when we entered this
+ * handler?
+ */
+
+ if ((regval & CAN_ALL_MAILBOXES) == CAN_ALL_MAILBOXES)
+ {
+ /* Yes.. disable further TX interrupts */
+
+ regval = can_getreg(priv, STM32_CAN_IER_OFFSET);
+ regval &= ~CAN_IER_TMEIE;
+ can_putreg(priv, STM32_CAN_IER_OFFSET, regval);
+ }
+
+ 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 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_getreg(priv, STM32_CAN_FMR_OFFSET);
+ regval |= CAN_FMR_FINIT;
+ can_putreg(priv, STM32_CAN_FMR_OFFSET, regval);
+
+ /* Disable the filter */
+
+ regval = can_getreg(priv, STM32_CAN_FA1R_OFFSET);
+ regval &= ~bitmask;
+ can_putreg(priv, STM32_CAN_FA1R_OFFSET, regval);
+
+ /* Select the 32-bit scale for the filter */
+
+ regval = can_getreg(priv, STM32_CAN_FS1R_OFFSET);
+ regval |= bitmask;
+ can_putreg(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_putreg(priv, STM32_CAN_FR_OFFSET(priv->filter, 1), 0);
+ can_putreg(priv, STM32_CAN_FR_OFFSET(priv->filter, 2), 0);
+
+ /* Set Id/Mask mode for the filter */
+
+ regval = can_getreg(priv, STM32_CAN_FM1R_OFFSET);
+ regval &= ~bitmask;
+ can_putreg(priv, STM32_CAN_FM1R_OFFSET, regval);
+
+ /* Assign FIFO 0 for the filter */
+
+ regval = can_getreg(priv, STM32_CAN_FFA1R_OFFSET);
+ regval &= ~bitmask;
+ can_putreg(priv, STM32_CAN_FFA1R_OFFSET, regval);
+
+ /* Enable the filter */
+
+ regval = can_getreg(priv, STM32_CAN_FA1R_OFFSET);
+ regval |= bitmask;
+ can_putreg(priv, STM32_CAN_FA1R_OFFSET, regval);
+
+ /* Exit filter initialization mode */
+
+ regval = can_getreg(priv, STM32_CAN_FMR_OFFSET);
+ regval &= ~CAN_FMR_FINIT;
+ can_putreg(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/nuttx/arch/arm/src/stm32/stm32_can.h b/nuttx/arch/arm/src/stm32/stm32_can.h
new file mode 100644
index 000000000..15203b5c9
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_can.h
@@ -0,0 +1,145 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_can.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "chip/stm32_can.h"
+
+#include <nuttx/can.h>
+
+/************************************************************************************
+ * 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;
+EXTERN 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/nuttx/arch/arm/src/stm32/stm32_dac.c b/nuttx/arch/arm/src/stm32/stm32_dac.c
new file mode 100644
index 000000000..b92da7b71
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_dac.c
@@ -0,0 +1,860 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_dac.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+#include <nuttx/arch.h>
+#include <nuttx/analog/dac.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "stm32_internal.h"
+#include "stm32_dac.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)
+# ifndef CONFIG_STM32_DMA2
+# warning "STM32 F1 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)
+# 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.
+ */
+
+#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 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 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 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 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 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 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 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
+
+/* Calculate timer divider values based upon DACn_TIMER_PCLK_FREQUENCY and
+ * CONFIG_STM32_DACn_TIMER_FREQUENCY.
+ */
+#warning "Missing Logic"
+
+/****************************************************************************
+ * 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 */
+#endif
+ uint8_t intf; /* DAC zero-based interface number (0 or 1) */
+#ifdef HAVE_DMA
+ uint16_t dmachan; /* DMA channel needed by this DAC */
+ DMA_HANDLE dma; /* Allocated DMA channel */
+ uint32_t tsel; /* CR trigger select value */
+ uint32_t tbase; /* Timer base address */
+#endif
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+/* DAC Register access */
+
+#ifdef HAVE_DMA
+static uint32_t tim_getreg(struct stm32_chan_s *chan, int offset);
+static void tim_putreg(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, 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);
+static int dac_interrupt(int irq, void *context);
+
+/* Initialization */
+
+#ifdef HAVE_DMA
+static int dac_timinit(struct stm32_chan_s *chan);
+#endif
+static int dac_chaninit(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;
+#ifdef CONFIG_STM32_DAC1_DMA
+ .hasdma = 1;
+ .dmachan = DAC1_DMA_CHAN,
+ .tsel = DAC1_TSEL_VALUE,
+ .tbase = DAC1_TIMER_BASE
+#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;
+#ifdef CONFIG_STM32_DAC2_DMA
+ .hasdma = 1;
+ .dmachan = DAC2_DMA_CHAN,
+ .tsel = DAC2_TSEL_VALUE.
+ .tbase = DAC2_TIMER_BASE
+#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: 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(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
+ *
+ ****************************************************************************/
+
+static void tim_putreg(struct stm32_chan_s *chan, int offset, uint32_t value)
+{
+ putreg32(value, chan->tbase + offset);
+}
+#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, 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;
+ uint32_t regval;
+
+ /* Reset only the selected DAC channel; the other DAC channel must remain
+ * functional.
+ */
+
+ flags = irqsave();
+
+#warning "Missing logic"
+
+ irqrestore(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 -ENOSYS;
+}
+
+/****************************************************************************
+ * 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_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)
+{
+#ifdef HAVE_DMA
+ if (priv->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
+ */
+#warning "Missing logic"
+
+ /* Enable DMA */
+#warning "Missing logic"
+
+ /* Enable DAC Channel */
+#warning "Missing logic"
+
+ /* Enable DMA for DAC Channel */
+#warning "Missing logic"
+ }
+ else
+ {
+ /* Non-DMA transfer */
+#warning "Missing logic"
+ }
+ return -ENOSYS;
+}
+
+/****************************************************************************
+ * 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(struct stm32_chan_s *chan)
+{
+ /* Configure the time base: Timer period, prescaler, clock division,
+ * counter mode (up).
+ */
+#warning "Missing Logic"
+
+ /* Selection TRGO selection: update */
+#warning "Missing Logic"
+
+ /* Enable the counter */
+#warning "Missing Logic"
+}
+#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(struct stm32_chan_s *chan)
+{
+ /* 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.
+ */
+#warning "Missing logic"
+
+ /* Determine if DMA is supported by this channel */
+
+#ifdef HAVE_DMA
+ if (priv->hasdma)
+ {
+ /* Yes.. allocate a DMA channel */
+
+ priv->dma = stm32_dmachannel(priv->dmachan);
+ if (!priv->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 = irqsave();
+ 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);
+ irqrestore(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_dacdev1;
+ }
+ 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);
+ 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);
+ return ret;
+ }
+
+ /* 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);
+ return ret;
+ }
+
+ return dev;
+}
+
+#endif /* CONFIG_STM32_DAC1 || CONFIG_STM32_DAC2 */
+#endif /* CONFIG_DAC */
diff --git a/nuttx/arch/arm/src/stm32/stm32_dac.h b/nuttx/arch/arm/src/stm32/stm32_dac.h
new file mode 100644
index 000000000..44404e6fb
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_dac.h
@@ -0,0 +1,139 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_dac.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "chip/stm32_dac.h"
+
+#include <nuttx/analog/dac.h>
+
+/************************************************************************************
+ * 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;
+EXTERN 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/nuttx/arch/arm/src/stm32/stm32_dbgmcu.h b/nuttx/arch/arm/src/stm32/stm32_dbgmcu.h
new file mode 100644
index 000000000..5fb192186
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/stm32/stm32_dma.c b/nuttx/arch/arm/src/stm32/stm32_dma.c
new file mode 100644
index 000000000..0dd8eb94e
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_dma.c
@@ -0,0 +1,80 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_dma.c
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#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.
+ *
+ * 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_STM32F10XX)
+# 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/nuttx/arch/arm/src/stm32/stm32_dma.h b/nuttx/arch/arm/src/stm32/stm32_dma.h
new file mode 100644
index 000000000..cccbc41f0
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_dma.h
@@ -0,0 +1,309 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_dma.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <sys/types.h>
+
+#include "chip.h"
+
+/* Include the correct DMA register definitions for this STM32 family */
+
+#if defined(CONFIG_STM32_STM32F10XX)
+# 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_STM32F10XX)
+# 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_STM32F10XX)
+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.
+ *
+ ****************************************************************************/
+
+EXTERN 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
+ *
+ ****************************************************************************/
+
+EXTERN void stm32_dmafree(DMA_HANDLE handle);
+
+/****************************************************************************
+ * Name: stm32_dmasetup
+ *
+ * Description:
+ * Configure DMA before using
+ *
+ ****************************************************************************/
+
+EXTERN 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
+ *
+ ****************************************************************************/
+
+EXTERN 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()
+ *
+ ****************************************************************************/
+
+EXTERN 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()
+ *
+ ****************************************************************************/
+
+EXTERN size_t stm32_dmaresidual(DMA_HANDLE handle);
+
+/****************************************************************************
+ * Name: stm32_dmasample
+ *
+ * Description:
+ * Sample DMA register contents
+ *
+ * Assumptions:
+ * - DMA handle allocated by stm32_dmachannel()
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_DMA
+EXTERN 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
+EXTERN 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/nuttx/arch/arm/src/stm32/stm32_dumpgpio.c b/nuttx/arch/arm/src/stm32/stm32_dumpgpio.c
new file mode 100644
index 000000000..cd1933831
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_dumpgpio.c
@@ -0,0 +1,179 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_gpio.c
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <debug.h>
+
+#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 > 9
+# error "Additional support required for this number of GPIOs"
+#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;
+ 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;
+ base = g_gpiobase[port];
+
+ /* The following requires exclusive access to the GPIO registers */
+
+ flags = irqsave();
+#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_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_ARFH_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
+ irqrestore(flags);
+ return OK;
+}
+
+#endif /* CONFIG_DEBUG */
diff --git a/nuttx/arch/arm/src/stm32/stm32_eth.c b/nuttx/arch/arm/src/stm32/stm32_eth.c
new file mode 100644
index 000000000..59f3def7f
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_eth.c
@@ -0,0 +1,3245 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_eth.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_STM32_ETHMAC)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <time.h>
+#include <string.h>
+#include <debug.h>
+#include <wdog.h>
+#include <queue.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/net/mii.h>
+
+#include <nuttx/net/uip/uip.h>
+#include <nuttx/net/uip/uip-arp.h>
+#include <nuttx/net/uip/uip-arch.h>
+
+#include "up_internal.h"
+
+#include "chip.h"
+#include "stm32_gpio.h"
+#include "stm32_rcc.h"
+#include "stm32_syscfg.h"
+#include "stm32_eth.h"
+
+#include <arch/board/board.h>
+
+/* STM32_NETHERNET determines the number of physical interfaces
+ * that will be supported.
+ */
+
+#if STM32_NETHERNET > 0
+
+/****************************************************************************
+ * 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 !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
+# 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
+
+#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.
+ */
+
+#define OPTIMAL_ETH_BUFSIZE (CONFIG_NET_BUFSIZE+4)
+
+#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 != 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 <= 168000000
+# define ETH_MACMIIAR_CR ETH_MACMIIAR_CR_150_168
+#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)
+#define STM32_POLLHSEC (1*2)
+
+/* 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
+ */
+
+#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_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)
+ *
+ * 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
+ */
+
+#if 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
+ */
+
+#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)
+
+/* 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)
+ */
+
+#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 uip_eth_hdr *)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 */
+
+ /* This holds the information visible to uIP/NuttX */
+
+ struct uip_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_uiptxpoll(struct uip_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);
+static int stm32_interrupt(int irq, FAR void *context);
+
+/* Watchdog timer expirations */
+
+static void stm32_polltimer(int argc, uint32_t arg, ...);
+static void stm32_txtimeout(int argc, uint32_t arg, ...);
+
+/* NuttX callback functions */
+
+static int stm32_ifup(struct uip_driver_s *dev);
+static int stm32_ifdown(struct uip_driver_s *dev);
+static int stm32_txavail(struct uip_driver_s *dev);
+#ifdef CONFIG_NET_IGMP
+static int stm32_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
+static int stm32_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
+#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 */
+
+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);
+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);
+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_BUFSIZE);
+ 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, 1, (uint32_t)priv);
+ return OK;
+}
+
+/****************************************************************************
+ * Function: stm32_uiptxpoll
+ *
+ * Description:
+ * The transmitter is available, check if uIP has any outgoing packets ready
+ * to send. This is a callback from uip_poll(). uip_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_uiptxpoll(struct uip_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)
+ {
+ /* Send the packet */
+
+ uip_arp_out(&priv->dev);
+ 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 when a frame is received using the DMA receive
+ * interrupt. It scans the RX descriptors to the 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_dopoll(FAR struct stm32_ethmac_s *priv)
+{
+ FAR struct uip_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)uip_poll(dev, stm32_uiptxpoll);
+
+ /* 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 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++;
+
+ nllvdbg("rxhead: %p rxcurr: %p segments: %d\n",
+ priv->rxhead, priv->rxcurr, priv->segments);
+
+ /* Check if the there is only one segment in the frame */
+
+ if (priv->segments == 1)
+ {
+ rxcurr = rxdesc;
+ }
+ else
+ {
+ rxcurr = priv->rxcurr;
+ }
+
+ /* Check if any errors are reported in the frame */
+
+ if ((rxdesc->rdes0 & ETH_RDES0_ES) == 0)
+ {
+ struct uip_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 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 uip_driver_s *dev = &priv->dev;
+
+ /* Loop while while stm32_recvframe() successfully retrieves valid
+ * Ethernet frames.
+ */
+
+ while (stm32_recvframe(priv) == OK)
+ {
+ /* Check if the packet is a valid size for the uIP buffer configuration
+ * (this should not happen)
+ */
+
+ if (dev->d_len > CONFIG_NET_BUFSIZE)
+ {
+ nlldbg("DROPPED: Too big: %d\n", dev->d_len);
+ }
+
+ /* We only accept IP packets of the configured type and ARP packets */
+
+#ifdef CONFIG_NET_IPv6
+ else if (BUF->type == HTONS(UIP_ETHTYPE_IP6))
+#else
+ else if (BUF->type == HTONS(UIP_ETHTYPE_IP))
+#endif
+ {
+ nllvdbg("IP frame\n");
+
+ /* Handle ARP on input then give the IP packet to uIP */
+
+ uip_arp_ipin(&priv->dev);
+ uip_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)
+ {
+ uip_arp_out(&priv->dev);
+ stm32_transmit(priv);
+ }
+ }
+ else if (BUF->type == htons(UIP_ETHTYPE_ARP))
+ {
+ nllvdbg("ARP frame\n");
+
+ /* Handle ARP packet */
+
+ uip_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
+ {
+ 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;
+ }
+ }
+}
+
+/****************************************************************************
+ * 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_FS) != 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(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(FAR struct stm32_ethmac_s *priv)
+{
+ DEBUGASSERT(priv->txtail != NULL);
+
+ /* Scan the TX desciptor change, returning buffers to free list */
+
+ stm32_freeframe(priv);
+
+ /* If no further xmits are pending, then cancel the TX timeout */
+
+ if (priv->inflight <= 0)
+ {
+ wd_cancel(priv->txtimeout);
+
+ /* And disable further TX interrupts. */
+
+ stm32_disableint(priv, ETH_DMAINT_TI);
+ }
+
+ /* Then poll uIP for new XMIT data */
+
+ stm32_dopoll(priv);
+}
+
+/****************************************************************************
+ * 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)
+{
+ register FAR struct stm32_ethmac_s *priv = &g_stm32ethmac[0];
+ 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 tansmissions.
+ */
+
+ 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
+ return OK;
+}
+
+/****************************************************************************
+ * Function: stm32_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 stm32_txtimeout(int argc, uint32_t arg, ...)
+{
+ FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg;
+
+ nlldbg("Timeout!\n");
+
+ /* Then reset the hardware. Just take the interface down, then back
+ * up again.
+ */
+
+ stm32_ifdown(&priv->dev);
+ stm32_ifup(&priv->dev);
+
+ /* Then poll uIP for new XMIT data */
+
+ stm32_dopoll(priv);
+}
+
+/****************************************************************************
+ * Function: stm32_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 stm32_polltimer(int argc, uint32_t arg, ...)
+{
+ FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg;
+ FAR struct uip_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 missing 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)uip_timer(dev, stm32_uiptxpoll, STM32_POLLHSEC);
+
+ /* 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_polltimer, 1, arg);
+}
+
+/****************************************************************************
+ * 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 uip_driver_s *dev)
+{
+ FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)dev->d_private;
+ 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 );
+
+ /* 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_polltimer, 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 uip_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 = irqsave();
+ 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;
+ irqrestore(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * 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 uip_driver_s *dev)
+{
+ FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_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 = irqsave();
+
+ /* Ignore the notification if the interface is not yet up */
+
+ if (priv->ifup)
+ {
+ /* Poll uIP for new XMIT data */
+
+ stm32_dopoll(priv);
+ }
+
+ irqrestore(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * 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:
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IGMP
+static int stm32_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
+{
+ FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)dev->d_private;
+
+ 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 routing table */
+ /* Add the MAC address to the hardware multicast routing table */
+#error "Missing logic"
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * 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 uip_driver_s *dev, FAR const uint8_t *mac)
+{
+ FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)dev->d_private;
+
+ 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 routing table */
+#error "Missing logic"
+
+ 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_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_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 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\n");
+ 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 */
+
+ 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;
+ }
+
+#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
+
+ /* Enable pulse-per-second (PPS) output signal */
+
+ stm32_configgpio(GPIO_ETH_PPS_OUT);
+}
+
+/****************************************************************************
+ * 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 uip_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_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);
+
+ /* 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
+ 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);
+ 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/nuttx/arch/arm/src/stm32/stm32_eth.h b/nuttx/arch/arm/src/stm32/stm32_eth.h
new file mode 100644
index 000000000..f0c14b5b1
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_eth.h
@@ -0,0 +1,97 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_eth.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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
+EXTERN int stm32_ethinitialize(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/nuttx/arch/arm/src/stm32/stm32_exti.h b/nuttx/arch/arm/src/stm32/stm32_exti.h
new file mode 100644
index 000000000..6dddf3836
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_exti.h
@@ -0,0 +1,119 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_exti.h
+ *
+ * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include <nuttx/irq.h>
+
+#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.
+ *
+ ************************************************************************************/
+
+EXTERN 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 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.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC_ALARM
+EXTERN 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/nuttx/arch/arm/src/stm32/stm32_exti_alarm.c b/nuttx/arch/arm/src/stm32/stm32_exti_alarm.c
new file mode 100644
index 000000000..07db26fd4
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ * Diego Sanchez <dsanchez@nx-engineering.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 <nuttx/config.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+
+#include <arch/irq.h>
+
+#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/nuttx/arch/arm/src/stm32/stm32_exti_gpio.c b/nuttx/arch/arm/src/stm32/stm32_exti_gpio.c
new file mode 100644
index 000000000..f897691ef
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_exti_gpio.c
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_exti_gpio.c
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ * Uros Platise <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#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];
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+ /****************************************************************************
+ * 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
+ * - 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)
+{
+ uint32_t pin = pinset & GPIO_PIN_MASK;
+ uint32_t exti = STM32_EXTI_BIT(pin);
+ int irq;
+ xcpt_t handler;
+ xcpt_t oldhandler = NULL;
+
+ /* Select the interrupt handler for this EXTI pin */
+
+ if (pin < 5)
+ {
+ irq = pin + STM32_IRQ_EXTI0;
+ 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;
+ }
+ else
+ {
+ irq = STM32_IRQ_EXTI1510;
+ handler = stm32_exti1510_isr;
+ }
+
+ /* 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
+ {
+ 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/nuttx/arch/arm/src/stm32/stm32_flash.c b/nuttx/arch/arm/src/stm32/stm32_flash.c
new file mode 100644
index 000000000..83fcc6172
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_flash.c
@@ -0,0 +1,247 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_flash.c
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Author: Uros Platise <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+#include <nuttx/arch.h>
+#include <errno.h>
+
+#include "stm32_flash.h"
+#include "stm32_rcc.h"
+#include "stm32_waste.h"
+
+#include "up_arch.h"
+
+/* Only for the STM32F10xx family for now */
+
+#ifdef CONFIG_STM32_STM32F10XX
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+#define FLASH_KEY1 0x45670123
+#define FLASH_KEY2 0xCDEF89AB
+
+/************************************************************************************
+ * Private 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)
+{
+ modifyreg16(STM32_FLASH_CR, 0, FLASH_CR_LOCK);
+}
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+uint16_t up_progmem_npages(void)
+{
+ return STM32_FLASH_NPAGES;
+}
+
+bool up_progmem_isuniform(void)
+{
+ return true;
+}
+
+uint16_t up_progmem_pagesize(uint16_t page)
+{
+ return STM32_FLASH_PAGESIZE;
+}
+
+int up_progmem_getpage(uint32_t addr)
+{
+ if (addr >= STM32_FLASH_SIZE)
+ {
+ return -EFAULT;
+ }
+
+ return addr / STM32_FLASH_PAGESIZE;
+}
+
+int up_progmem_erasepage(uint16_t page)
+{
+ uint32_t addr;
+ uint16_t count;
+
+ 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_PER);
+ putreg32(page * STM32_FLASH_PAGESIZE, STM32_FLASH_AR);
+ modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_STRT);
+
+ while(getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) up_waste();
+
+ modifyreg32(STM32_FLASH_CR, FLASH_CR_PER, 0);
+
+ /* Verify */
+
+ for (addr = page * STM32_FLASH_PAGESIZE + STM32_FLASH_BASE, count = STM32_FLASH_PAGESIZE;
+ count; count-=4, addr += 4)
+ {
+ if (getreg32(addr) != 0xffffffff)
+ {
+ return -EIO;
+ }
+ }
+
+ return STM32_FLASH_PAGESIZE;
+}
+
+int up_progmem_ispageerased(uint16_t page)
+{
+ uint32_t addr;
+ uint16_t count;
+ uint16_t bwritten = 0;
+
+ if (page >= STM32_FLASH_NPAGES)
+ {
+ return -EFAULT;
+ }
+
+ /* Verify */
+
+ for (addr = page * STM32_FLASH_PAGESIZE + STM32_FLASH_BASE, count = STM32_FLASH_PAGESIZE;
+ count; count--, addr++)
+ {
+ if (getreg8(addr) != 0xff)
+ {
+ bwritten++;
+ }
+ }
+
+ return bwritten;
+}
+
+int up_progmem_write(uint32_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+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);
+
+ for (addr += STM32_FLASH_BASE; count; count--, 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_WRPRT_ERR)
+ {
+ 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 /* CONFIG_STM32_STM32F10XX */
diff --git a/nuttx/arch/arm/src/stm32/stm32_flash.h b/nuttx/arch/arm/src/stm32/stm32_flash.h
new file mode 100644
index 000000000..10c5cc189
--- /dev/null
+++ b/nuttx/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 <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <nuttx/progmem.h>
+
+#include "chip.h"
+#include "chip/stm32_flash.h"
+
+#endif /* __ARCH_ARM_SRC_STM32_STM32_FLASH_H */
diff --git a/nuttx/arch/arm/src/stm32/stm32_fsmc.h b/nuttx/arch/arm/src/stm32/stm32_fsmc.h
new file mode 100644
index 000000000..9fd4f3fa2
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_fsmc.h
@@ -0,0 +1,304 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_fsmc.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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 */
+
+/* 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 )
+
+/* 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_BUSTRUN(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 */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_STM32_STM32_FSMC_H */
diff --git a/nuttx/arch/arm/src/stm32/stm32_gpio.c b/nuttx/arch/arm/src/stm32/stm32_gpio.c
new file mode 100644
index 000000000..143e48a2c
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_gpio.c
@@ -0,0 +1,736 @@
+/****************************************************************************
+ * 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 <gnutt@nuttx.org>
+ * Uros Platise <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#include "up_arch.h"
+
+#include "chip.h"
+#include "stm32_gpio.h"
+
+#if defined(CONFIG_STM32_STM32F20XX) || 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 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
+};
+
+/****************************************************************************
+ * 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_JTAG_FULL_ENABLE
+ /* The reset default */
+#elif CONFIG_STM32_JTAG_NOJNTRST_ENABLE
+ val |= AFIO_MAPR_SWJ; /* enabled but without JNTRST */
+#elif 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
+
+#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_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_SPI1_REMAP
+ val |= AFIO_MAPR_SPI1_REMAP;
+#endif
+#ifdef CONFIG_STM32_SPI3_REMAP
+#endif
+
+#ifdef CONFIG_STM32_I2C1_REMAP
+ val |= AFIO_MAPR_I2C1_REMAP;
+#endif
+
+#ifdef CONFIG_STM32_CAN1_REMAP1
+ val |= AFIO_MAPR_PB89;
+#endif
+#ifdef CONFIG_STM32_CAN1_REMAP2
+ val |= AFIO_MAPR_PD01;
+#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 = irqsave();
+
+ /* 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 */
+
+ irqrestore(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 */
+
+ irqrestore(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);
+
+ irqrestore(flags);
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_configgpio (for the STM2F20xxx and STM32F40xxx family)
+ ****************************************************************************/
+
+#if defined(CONFIG_STM32_STM32F20XX) || 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 = irqsave();
+
+ /* 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_ARFH_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);
+ }
+
+ irqrestore(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_STM32F20XX) || 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_STM32F20XX) || 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_STM32F20XX) || 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/nuttx/arch/arm/src/stm32/stm32_gpio.h b/nuttx/arch/arm/src/stm32/stm32_gpio.h
new file mode 100644
index 000000000..fde564cbb
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_gpio.h
@@ -0,0 +1,514 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_gpio.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ * Uros Platise <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#ifndef __ASSEMBLY__
+# include <stdint.h>
+# include <stdbool.h>
+#endif
+
+#include <nuttx/irq.h>
+
+#include "chip.h"
+
+#if defined(CONFIG_STM32_STM32F10XX)
+# include "chip/stm32f10xxx_gpio.h"
+#elif defined(CONFIG_STM32_STM32F20XX)
+# include "chip/stm32f20xxx_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_STM32F20XX) || 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)
+# 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 */
+
+/* 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.
+ *
+ ************************************************************************************/
+
+EXTERN 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
+ *
+ ************************************************************************************/
+
+EXTERN int stm32_unconfiggpio(uint32_t cfgset);
+
+/************************************************************************************
+ * Name: stm32_gpiowrite
+ *
+ * Description:
+ * Write one or zero to the selected GPIO pin
+ *
+ ************************************************************************************/
+
+EXTERN void stm32_gpiowrite(uint32_t pinset, bool value);
+
+/************************************************************************************
+ * Name: stm32_gpioread
+ *
+ * Description:
+ * Read one or zero from the selected GPIO pin
+ *
+ ************************************************************************************/
+
+EXTERN 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.
+ *
+ ************************************************************************************/
+
+EXTERN 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
+EXTERN 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().
+ *
+ ************************************************************************************/
+
+EXTERN void stm32_gpioinit(void);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32_STM32_GPIO_H */
diff --git a/nuttx/arch/arm/src/stm32/stm32_i2c.c b/nuttx/arch/arm/src/stm32/stm32_i2c.c
new file mode 100644
index 000000000..cbd6f6b14
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_i2c.c
@@ -0,0 +1,1917 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_i2c.c
+ * STM32 I2C Hardware Layer - Device Driver
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Author: Uros Platise <uros.platise@isotel.eu>
+ *
+ * With extensions, modifications by:
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregroy Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/i2c.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/clock.h>
+
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+
+#include "stm32_rcc.h"
+#include "stm32_i2c.h"
+#include "stm32_waste.h"
+
+#if defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2) || defined(CONFIG_STM32_I2C3)
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+/* Configuration ********************************************************************/
+/* CONFIG_I2C_POLLED may be set so that I2C interrrupts 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 */
+
+#define CONFIG_STM32_I2CTIMEOTICKS \
+ (SEC2TICK(CONFIG_STM32_I2CTIMEOSEC) + MSEC2TICK(CONFIG_STM32_I2CTIMEOMS))
+
+/* 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
+
+/* 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 lib_rawprintf() 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 */
+ uint32_t time; /* First of event or first status */
+};
+
+/* I2C Device Private Data */
+
+struct stm32_i2c_priv_s
+{
+ uint32_t base; /* I2C base address */
+ 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 */
+ int dcnt; /* Current message length */
+ uint16_t flags; /* Current message flags */
+
+ /* I2C trace support */
+
+#ifdef CONFIG_I2C_TRACE
+ int tndx; /* Trace array index */
+ uint32_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 */
+};
+
+/* I2C Device, Instance */
+
+struct stm32_i2c_inst_s
+{
+ struct i2c_ops_s *ops; /* Standard I2C operations */
+ struct stm32_i2c_priv_s *priv; /* Common driver private data structure */
+
+ uint32_t frequency; /* Frequency used in this instantiation */
+ int address; /* Address used in this instantiation */
+ uint16_t flags; /* Flags used in this instantiation */
+};
+
+/************************************************************************************
+ * 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 i2c_dev_s *dev);
+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 i2c_dev_s *dev);
+static inline void stm32_i2c_sem_init(FAR struct i2c_dev_s *dev);
+static inline void stm32_i2c_sem_destroy(FAR struct i2c_dev_s *dev);
+#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
+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
+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 uint32_t stm32_i2c_setfrequency(FAR struct i2c_dev_s *dev,
+ uint32_t frequency);
+static int stm32_i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits);
+static int stm32_i2c_process(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs,
+ int count);
+static int stm32_i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer,
+ int buflen);
+static int stm32_i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen);
+#ifdef CONFIG_I2C_WRITEREAD
+static int stm32_i2c_writeread(FAR struct i2c_dev_s *dev,
+ const uint8_t *wbuffer, int wbuflen,
+ uint8_t *buffer, int buflen);
+#endif
+#ifdef CONFIG_I2C_TRANSFER
+static int stm32_i2c_transfer(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs,
+ int count);
+#endif
+
+/************************************************************************************
+ * Private Data
+ ************************************************************************************/
+
+#ifdef CONFIG_STM32_I2C1
+struct stm32_i2c_priv_s stm32_i2c1_priv =
+{
+ .base = STM32_I2C1_BASE,
+ .refs = 0,
+ .intstate = INTSTATE_IDLE,
+ .msgc = 0,
+ .msgv = NULL,
+ .ptr = NULL,
+ .dcnt = 0,
+ .flags = 0,
+ .status = 0
+};
+#endif
+
+#ifdef CONFIG_STM32_I2C2
+struct stm32_i2c_priv_s stm32_i2c2_priv =
+{
+ .base = STM32_I2C2_BASE,
+ .refs = 0,
+ .intstate = INTSTATE_IDLE,
+ .msgc = 0,
+ .msgv = NULL,
+ .ptr = NULL,
+ .dcnt = 0,
+ .flags = 0,
+ .status = 0
+};
+#endif
+
+#ifdef CONFIG_STM32_I2C3
+struct stm32_i2c_priv_s stm32_i2c3_priv =
+{
+ .base = STM32_I2C3_BASE,
+ .refs = 0,
+ .intstate = INTSTATE_IDLE,
+ .msgc = 0,
+ .msgv = NULL,
+ .ptr = NULL,
+ .dcnt = 0,
+ .flags = 0,
+ .status = 0
+};
+#endif
+
+
+/* Device Structures, Instantiation */
+
+struct i2c_ops_s stm32_i2c_ops =
+{
+ .setfrequency = stm32_i2c_setfrequency,
+ .setaddress = stm32_i2c_setaddress,
+ .write = stm32_i2c_write,
+ .read = stm32_i2c_read
+#ifdef CONFIG_I2C_WRITEREAD
+ , .writeread = stm32_i2c_writeread
+#endif
+#ifdef CONFIG_I2C_TRANSFER
+ , .transfer = stm32_i2c_transfer
+#endif
+#ifdef CONFIG_I2C_SLAVE
+ , .setownaddress = stm32_i2c_setownaddress,
+ .registercallback = stm32_i2c_registercallback
+#endif
+};
+
+/************************************************************************************
+ * Private Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: stm32_i2c_getreg
+ *
+ * Description:
+ * Get register value by offset
+ *
+ ************************************************************************************/
+
+static inline uint16_t stm32_i2c_getreg(FAR struct stm32_i2c_priv_s *priv,
+ uint8_t offset)
+{
+ return getreg16(priv->base + offset);
+}
+
+/************************************************************************************
+ * Name: stm32_i2c_putreg
+ *
+ * Description:
+ * Put 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->base + offset);
+}
+
+/************************************************************************************
+ * Name: stm32_i2c_modifyreg
+ *
+ * Description:
+ * Modify 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->base + offset, clearbits, setbits);
+}
+
+/************************************************************************************
+ * Name:
+ *
+ * Description:
+ *
+ *
+ ************************************************************************************/
+
+static inline void stm32_i2c_sem_wait(FAR struct i2c_dev_s *dev)
+{
+ while (sem_wait(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl) != 0)
+ {
+ ASSERT(errno == EINTR);
+ }
+}
+
+/************************************************************************************
+ * 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 = irqsave();
+
+ /* 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
+#if 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);
+
+ irqrestore(flags);
+ return ret;
+}
+#else
+static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv )
+{
+ uint32_t start;
+ uint32_t elapsed;
+ int ret;
+
+ /* 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 < CONFIG_STM32_I2CTIMEOTICKS);
+
+ i2cvdbg("intstate: %d elapsed: %d threshold: %d status: %08x\n",
+ priv->intstate, elapsed, CONFIG_STM32_I2CTIMEOTICKS, 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)
+{
+ uint32_t start;
+ uint32_t elapsed;
+ uint32_t cr1;
+ uint32_t sr1;
+
+ /* 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 < CONFIG_STM32_I2CTIMEOTICKS);
+
+ /* 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 i2c_dev_s *dev)
+{
+ sem_post( &((struct stm32_i2c_inst_s *)dev)->priv->sem_excl );
+}
+
+/************************************************************************************
+ * Name: stm32_i2c_sem_init
+ *
+ * Description:
+ * Initialize semaphores
+ *
+ ************************************************************************************/
+
+static inline void stm32_i2c_sem_init(FAR struct i2c_dev_s *dev)
+{
+ sem_init(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl, 0, 1);
+#ifndef CONFIG_I2C_POLLED
+ sem_init(&((struct stm32_i2c_inst_s *)dev)->priv->sem_isr, 0, 0);
+#endif
+}
+
+/************************************************************************************
+ * Name: stm32_i2c_sem_destroy
+ *
+ * Description:
+ * Destroy semaphores.
+ *
+ ************************************************************************************/
+
+static inline void stm32_i2c_sem_destroy(FAR struct i2c_dev_s *dev)
+{
+ sem_destroy(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl);
+#ifndef CONFIG_I2C_POLLED
+ sem_destroy(&((struct stm32_i2c_inst_s *)dev)->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;
+
+ lib_rawprintf("Elapsed time: %d\n", clock_systimer() - priv->start_time);
+ for (i = 0; i <= priv->tndx; i++)
+ {
+ trace = &priv->trace[i];
+ lib_rawprintf("%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)
+{
+ uint16_t cr1;
+ uint16_t ccr;
+ uint16_t trise;
+ uint16_t freqmhz;
+ uint16_t speed;
+
+ /* 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_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);
+}
+
+/************************************************************************************
+ * 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 */
+
+#ifdef CONFIG_STM32_I2C2
+ if (priv->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-enabled 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);
+
+ /* 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--;
+ }
+
+ /* In 10-bit addressing mode, was first byte sent */
+
+ else if ((status & I2C_SR1_ADD10) != 0)
+ {
+ /* TODO: Finish 10-bit mode addressing */
+ }
+
+ /* 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);
+
+ /* Receive a byte */
+
+ *priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET);
+
+ /* Disable acknowledge when last byte is to be received */
+
+ if (priv->dcnt == 1)
+ {
+ stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, 0);
+ }
+ priv->dcnt--;
+ }
+ }
+
+ /* 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)
+ 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)
+ {
+ 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 */
+
+ switch (priv->base)
+ {
+#ifdef CONFIG_STM32_I2C1
+ case STM32_I2C1_BASE:
+
+ /* Enable power and reset the peripheral */
+
+ modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_I2C1EN);
+
+ modifyreg32(STM32_RCC_APB1RSTR, 0, RCC_APB1RSTR_I2C1RST);
+ modifyreg32(STM32_RCC_APB1RSTR, RCC_APB1RSTR_I2C1RST, 0);
+
+ /* Configure pins */
+
+ if (stm32_configgpio(GPIO_I2C1_SCL) < 0)
+ {
+ return ERROR;
+ }
+
+ if (stm32_configgpio(GPIO_I2C1_SDA) < 0)
+ {
+ stm32_unconfiggpio(GPIO_I2C1_SCL);
+ return ERROR;
+ }
+
+ /* Attach ISRs */
+
+#ifndef CONFIG_I2C_POLLED
+ irq_attach(STM32_IRQ_I2C1EV, stm32_i2c1_isr);
+ irq_attach(STM32_IRQ_I2C1ER, stm32_i2c1_isr);
+ up_enable_irq(STM32_IRQ_I2C1EV);
+ up_enable_irq(STM32_IRQ_I2C1ER);
+#endif
+ break;
+#endif
+
+#ifdef CONFIG_STM32_I2C2
+ case STM32_I2C2_BASE:
+
+ /* Enable power and reset the peripheral */
+
+ modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_I2C2EN);
+
+ modifyreg32(STM32_RCC_APB1RSTR, 0, RCC_APB1RSTR_I2C2RST);
+ modifyreg32(STM32_RCC_APB1RSTR, RCC_APB1RSTR_I2C2RST, 0);
+
+ /* Configure pins */
+
+ if (stm32_configgpio(GPIO_I2C2_SCL) < 0)
+ {
+ return ERROR;
+ }
+
+ if (stm32_configgpio(GPIO_I2C2_SDA) < 0)
+ {
+ stm32_unconfiggpio(GPIO_I2C2_SCL);
+ return ERROR;
+ }
+
+ /* Attach ISRs */
+
+#ifndef CONFIG_I2C_POLLED
+ irq_attach(STM32_IRQ_I2C2EV, stm32_i2c2_isr);
+ irq_attach(STM32_IRQ_I2C2ER, stm32_i2c2_isr);
+ up_enable_irq(STM32_IRQ_I2C2EV);
+ up_enable_irq(STM32_IRQ_I2C2ER);
+#endif
+ break;
+#endif
+
+#ifdef CONFIG_STM32_I2C3
+ case STM32_I2C3_BASE:
+
+ /* Enable power and reset the peripheral */
+
+ modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_I2C3EN);
+
+ modifyreg32(STM32_RCC_APB1RSTR, 0, RCC_APB1RSTR_I2C3RST);
+ modifyreg32(STM32_RCC_APB1RSTR, RCC_APB1RSTR_I2C3RST, 0);
+
+ /* Configure pins */
+
+ if (stm32_configgpio(GPIO_I2C3_SCL) < 0)
+ {
+ return ERROR;
+ }
+
+ if (stm32_configgpio(GPIO_I2C3_SDA) < 0)
+ {
+ stm32_unconfiggpio(GPIO_I2C3_SCL);
+ return ERROR;
+ }
+
+ /* Attach ISRs */
+
+#ifndef CONFIG_I2C_POLLED
+ irq_attach(STM32_IRQ_I2C3EV, stm32_i2c3_isr);
+ irq_attach(STM32_IRQ_I2C3ER, stm32_i2c3_isr);
+ up_enable_irq(STM32_IRQ_I2C3EV);
+ up_enable_irq(STM32_IRQ_I2C3ER);
+#endif
+ break;
+#endif
+
+ default:
+ return ERROR;
+ }
+
+ /* 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));
+ 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);
+
+ switch (priv->base)
+ {
+#ifdef CONFIG_STM32_I2C1
+ case STM32_I2C1_BASE:
+ stm32_unconfiggpio(GPIO_I2C1_SCL);
+ stm32_unconfiggpio(GPIO_I2C1_SDA);
+
+#ifndef CONFIG_I2C_POLLED
+ up_disable_irq(STM32_IRQ_I2C1EV);
+ up_disable_irq(STM32_IRQ_I2C1ER);
+ irq_detach(STM32_IRQ_I2C1EV);
+ irq_detach(STM32_IRQ_I2C1ER);
+#endif
+ modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_I2C1EN, 0);
+ break;
+#endif
+
+#ifdef CONFIG_STM32_I2C2
+ case STM32_I2C2_BASE:
+ stm32_unconfiggpio(GPIO_I2C2_SCL);
+ stm32_unconfiggpio(GPIO_I2C2_SDA);
+
+#ifndef CONFIG_I2C_POLLED
+ up_disable_irq(STM32_IRQ_I2C2EV);
+ up_disable_irq(STM32_IRQ_I2C2ER);
+ irq_detach(STM32_IRQ_I2C2EV);
+ irq_detach(STM32_IRQ_I2C2ER);
+#endif
+ modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_I2C2EN, 0);
+ break;
+#endif
+
+ default:
+ return ERROR;
+ }
+
+ return OK;
+}
+
+/************************************************************************************
+ * Device Driver Operations
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: stm32_i2c_setfrequency
+ *
+ * Description:
+ * Set the I2C frequency
+ *
+ ************************************************************************************/
+
+static uint32_t stm32_i2c_setfrequency(FAR struct i2c_dev_s *dev, uint32_t frequency)
+{
+ stm32_i2c_sem_wait(dev);
+
+#if STM32_PCLK1_FREQUENCY < 4000000
+ ((struct stm32_i2c_inst_s *)dev)->frequency = 100000;
+#else
+ ((struct stm32_i2c_inst_s *)dev)->frequency = frequency;
+#endif
+
+ stm32_i2c_sem_post(dev);
+ return ((struct stm32_i2c_inst_s *)dev)->frequency;
+}
+
+/************************************************************************************
+ * Name: stm32_i2c_setaddress
+ *
+ * Description:
+ * Set the I2C slave address
+ *
+ ************************************************************************************/
+
+static int stm32_i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits)
+{
+ stm32_i2c_sem_wait(dev);
+
+ ((struct stm32_i2c_inst_s *)dev)->address = addr;
+ ((struct stm32_i2c_inst_s *)dev)->flags = (nbits == 10) ? I2C_M_TEN : 0;
+
+ stm32_i2c_sem_post(dev);
+ return OK;
+}
+
+/************************************************************************************
+ * Name: stm32_i2c_process
+ *
+ * Description:
+ * Common I2C transfer logic
+ *
+ ************************************************************************************/
+
+static int stm32_i2c_process(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, int count)
+{
+ struct stm32_i2c_inst_s *inst = (struct stm32_i2c_inst_s *)dev;
+ FAR struct stm32_i2c_priv_s *priv = inst->priv;
+ uint32_t status = 0;
+ uint32_t ahbenr;
+ int errval = 0;
+
+ ASSERT(count);
+
+ /* Disable FSMC that shares a pin with I2C1 (LBAR) */
+
+ ahbenr = stm32_i2c_disablefsmc(priv);
+
+ /* 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.
+ */
+
+#ifndef I2C1_FSMC_CONFLICT
+ 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 !) */
+
+ stm32_i2c_setclock(priv, inst->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);
+ errval = 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);
+ }
+ 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 */
+
+ errval = EIO;
+ }
+ else if (status & I2C_SR1_ARLO)
+ {
+ /* Arbitration Lost (master mode) */
+
+ errval = EAGAIN;
+ }
+ else if (status & I2C_SR1_AF)
+ {
+ /* Acknowledge Failure */
+
+ errval = ENXIO;
+ }
+ else if (status & I2C_SR1_OVR)
+ {
+ /* Overrun/Underrun */
+
+ errval = EIO;
+ }
+ else if (status & I2C_SR1_PECERR)
+ {
+ /* PEC Error in reception */
+
+ errval = EPROTO;
+ }
+ else if (status & I2C_SR1_TIMEOUT)
+ {
+ /* Timeout or Tlow Error */
+
+ errval = 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.
+ */
+
+ errval = 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_SR2_BUSY << 16)) != 0)
+ {
+ /* I2C Bus is for some reason busy */
+
+ errval = EBUSY;
+ }
+
+ /* Dump the trace result */
+
+ stm32_i2c_tracedump(priv);
+
+ /* 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.
+ */
+
+#ifdef I2C1_FSMC_CONFLICT
+ stm32_i2c_sem_waitstop(priv);
+#endif
+
+ /* Re-enable the FSMC */
+
+ stm32_i2c_enablefsmc(ahbenr);
+ stm32_i2c_sem_post(dev);
+
+ return -errval;
+}
+
+/************************************************************************************
+ * Name: stm32_i2c_write
+ *
+ * Description:
+ * Write I2C data
+ *
+ ************************************************************************************/
+
+static int stm32_i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer, int buflen)
+{
+ stm32_i2c_sem_wait(dev); /* ensure that address or flags don't change meanwhile */
+
+ struct i2c_msg_s msgv =
+ {
+ .addr = ((struct stm32_i2c_inst_s *)dev)->address,
+ .flags = ((struct stm32_i2c_inst_s *)dev)->flags,
+ .buffer = (uint8_t *)buffer,
+ .length = buflen
+ };
+
+ return stm32_i2c_process(dev, &msgv, 1);
+}
+
+/************************************************************************************
+ * Name: stm32_i2c_read
+ *
+ * Description:
+ * Read I2C data
+ *
+ ************************************************************************************/
+
+int stm32_i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
+{
+ stm32_i2c_sem_wait(dev); /* ensure that address or flags don't change meanwhile */
+
+ struct i2c_msg_s msgv =
+ {
+ .addr = ((struct stm32_i2c_inst_s *)dev)->address,
+ .flags = ((struct stm32_i2c_inst_s *)dev)->flags | I2C_M_READ,
+ .buffer = buffer,
+ .length = buflen
+ };
+
+ return stm32_i2c_process(dev, &msgv, 1);
+}
+
+/************************************************************************************
+ * Name: stm32_i2c_writeread
+ *
+ * Description:
+ * Read then write I2C data
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_I2C_WRITEREAD
+static int stm32_i2c_writeread(FAR struct i2c_dev_s *dev,
+ const uint8_t *wbuffer, int wbuflen,
+ uint8_t *buffer, int buflen)
+{
+ stm32_i2c_sem_wait(dev); /* ensure that address or flags don't change meanwhile */
+
+ struct i2c_msg_s msgv[2] =
+ {
+ {
+ .addr = ((struct stm32_i2c_inst_s *)dev)->address,
+ .flags = ((struct stm32_i2c_inst_s *)dev)->flags,
+ .buffer = (uint8_t *)wbuffer, /* this is really ugly, sorry const ... */
+ .length = wbuflen
+ },
+ {
+ .addr = ((struct stm32_i2c_inst_s *)dev)->address,
+ .flags = ((struct stm32_i2c_inst_s *)dev)->flags | ((buflen>0) ? I2C_M_READ : I2C_M_NORESTART),
+ .buffer = buffer,
+ .length = (buflen>0) ? buflen : -buflen
+ }
+ };
+
+ return stm32_i2c_process(dev, msgv, 2);
+}
+#endif
+
+/************************************************************************************
+ * Name: stm32_i2c_transfer
+ *
+ * Description:
+ * Generic I2C transfer function
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_I2C_TRANSFER
+static int stm32_i2c_transfer(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs,
+ int count)
+{
+ stm32_i2c_sem_wait(dev); /* ensure that address or flags don't change meanwhile */
+ return stm32_i2c_process(dev, msgs, count);
+}
+#endif
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: up_i2cinitialize
+ *
+ * Description:
+ * Initialize one I2C bus
+ *
+ ************************************************************************************/
+
+FAR struct i2c_dev_s *up_i2cinitialize(int port)
+{
+ struct stm32_i2c_priv_s * priv = NULL; /* private data of device with multiple instances */
+ struct stm32_i2c_inst_s * inst = NULL; /* device, single instance */
+ int irqs;
+
+#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;
+ }
+
+ /* Allocate instance */
+
+ if (!(inst = kmalloc( sizeof(struct stm32_i2c_inst_s))))
+ {
+ return NULL;
+ }
+
+ /* Initialize instance */
+
+ inst->ops = &stm32_i2c_ops;
+ inst->priv = priv;
+ inst->frequency = 100000;
+ inst->address = 0;
+ inst->flags = 0;
+
+ /* Init private data for the first time, increment refs count,
+ * power-up hardware and configure GPIOs.
+ */
+
+ irqs = irqsave();
+
+ if ((volatile int)priv->refs++ == 0)
+ {
+ stm32_i2c_sem_init( (struct i2c_dev_s *)inst );
+ stm32_i2c_init( priv );
+ }
+
+ irqrestore(irqs);
+ return (struct i2c_dev_s *)inst;
+}
+
+/************************************************************************************
+ * Name: up_i2cuninitialize
+ *
+ * Description:
+ * Uninitialize an I2C bus
+ *
+ ************************************************************************************/
+
+int up_i2cuninitialize(FAR struct i2c_dev_s * dev)
+{
+ int irqs;
+
+ ASSERT(dev);
+
+ /* Decrement refs and check for underflow */
+
+ if (((struct stm32_i2c_inst_s *)dev)->priv->refs == 0)
+ {
+ return ERROR;
+ }
+
+ irqs = irqsave();
+
+ if (--((struct stm32_i2c_inst_s *)dev)->priv->refs)
+ {
+ irqrestore(irqs);
+ kfree(dev);
+ return OK;
+ }
+
+ irqrestore(irqs);
+
+ /* Disable power and other HW resource (GPIO's) */
+
+ stm32_i2c_deinit( ((struct stm32_i2c_inst_s *)dev)->priv );
+
+ /* Release unused resources */
+
+ stm32_i2c_sem_destroy( (struct i2c_dev_s *)dev );
+
+ kfree(dev);
+ return OK;
+}
+
+#endif /* defined(CONFIG_STM32_I2C1) && defined(CONFIG_STM32_I2C2) */
diff --git a/nuttx/arch/arm/src/stm32/stm32_i2c.h b/nuttx/arch/arm/src/stm32/stm32_i2c.h
new file mode 100644
index 000000000..b914c4247
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_i2c.h
@@ -0,0 +1,50 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_i2c.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <nuttx/i2c.h>
+
+#include "chip.h"
+#include "chip/stm32_i2c.h"
+
+#endif /* __ARCH_ARM_SRC_STM32_STM32_I2C_H */
+
diff --git a/nuttx/arch/arm/src/stm32/stm32_idle.c b/nuttx/arch/arm/src/stm32/stm32_idle.c
new file mode 100644
index 000000000..791a79429
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_idle.c
@@ -0,0 +1,188 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_idle.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <arch/board/board.h>
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/power/pm.h>
+
+#include <arch/irq.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() up_ledon(LED_IDLE)
+# define END_IDLE() up_ledoff(LED_IDLE)
+#else
+# define BEGIN_IDLE()
+# define END_IDLE()
+#endif
+
+/****************************************************************************
+ * 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();
+
+ /* 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(newstate);
+ if (ret < 0)
+ {
+ /* The new state change failed, revert to the preceding state */
+
+ (void)pm_changestate(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;
+ }
+
+ 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 */
+
+ BEGIN_IDLE();
+ asm("WFI");
+ END_IDLE();
+#endif
+}
+
diff --git a/nuttx/arch/arm/src/stm32/stm32_internal.h b/nuttx/arch/arm/src/stm32/stm32_internal.h
new file mode 100644
index 000000000..8db936786
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_internal.h
@@ -0,0 +1,45 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_internal.h
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_INTERNAL_H
+#define __ARCH_ARM_SRC_STM32_STM32_INTERNAL_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include "stm32.h"
+
+#endif /* __ARCH_ARM_SRC_STM32_STM32_INTERNAL_H */
diff --git a/nuttx/arch/arm/src/stm32/stm32_irq.c b/nuttx/arch/arm/src/stm32/stm32_irq.c
new file mode 100644
index 000000000..36a5cf5fa
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_irq.c
@@ -0,0 +1,476 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_irq.c
+ * arch/arm/src/chip/stm32_irq.c
+ *
+ * Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "nvic.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+#include "stm32_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* Enable NVIC debug features that are probably only desireable during
+ * bringup
+ */
+
+#undef STM32_IRQ_DEBUG
+
+/* 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
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dumpnvic
+ *
+ * Description:
+ * Dump some interesting NVIC registers
+ *
+ ****************************************************************************/
+
+#if defined(STM32_IRQ_DEBUG) && defined (CONFIG_DEBUG)
+static void stm32_dumpnvic(const char *msg, int irq)
+{
+ irqstate_t flags;
+
+ flags = irqsave();
+ slldbg("NVIC (%s, irq=%d):\n", msg, irq);
+ slldbg(" INTCTRL: %08x VECTAB: %08x\n",
+ getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB));
+#if 0
+ slldbg(" 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
+ slldbg(" IRQ ENABLE: %08x %08x %08x\n",
+ getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE),
+ getreg32(NVIC_IRQ64_95_ENABLE));
+ slldbg(" SYSH_PRIO: %08x %08x %08x\n",
+ getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY),
+ getreg32(NVIC_SYSH12_15_PRIORITY));
+ slldbg(" 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));
+ slldbg(" %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));
+ slldbg(" %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));
+ slldbg(" %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));
+ slldbg(" %08x\n",
+ getreg32(NVIC_IRQ64_67_PRIORITY));
+ irqrestore(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)irqsave();
+ dbg("PANIC!!! NMI received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int stm32_busfault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Bus fault recived\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int stm32_usagefault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Usage fault received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int stm32_pendsv(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! PendSV received\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int stm32_dbgmonitor(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Debug Monitor receieved\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+
+static int stm32_reserved(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Reserved interrupt\n");
+ PANIC(OSERR_UNEXPECTEDISR);
+ return 0;
+}
+#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, uint32_t *regaddr, uint32_t *bit)
+{
+ DEBUGASSERT(irq >= STM32_IRQ_NMI && irq < NR_IRQS);
+
+ /* Check for external interrupt */
+
+ if (irq >= STM32_IRQ_INTERRUPTS)
+ {
+ if (irq < STM32_IRQ_INTERRUPTS + 32)
+ {
+ *regaddr = NVIC_IRQ0_31_ENABLE;
+ *bit = 1 << (irq - STM32_IRQ_INTERRUPTS);
+ }
+ else if (irq < STM32_IRQ_INTERRUPTS + 64)
+ {
+ *regaddr = NVIC_IRQ32_63_ENABLE;
+ *bit = 1 << (irq - STM32_IRQ_INTERRUPTS - 32);
+ }
+ else if (irq < NR_IRQS)
+ {
+ *regaddr = NVIC_IRQ64_95_ENABLE;
+ *bit = 1 << (irq - STM32_IRQ_INTERRUPTS - 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);
+
+ /* 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.
+ */
+
+#ifdef CONFIG_STM32_DFU
+ putreg32((uint32_t)stm32_vectors, 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);
+
+ /* 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
+
+ /* If the MPU is enabled, then attach and enable the Memory Management
+ * Fault handler.
+ */
+
+#ifdef CONFIG_ARMV7M_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_ARMV7M_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 */
+
+ setbasepri(NVIC_SYSH_PRIORITY_MAX);
+ irqrestore(0);
+#endif
+}
+
+/****************************************************************************
+ * Name: up_disable_irq
+ *
+ * Description:
+ * Disable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_disable_irq(int irq)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (stm32_irqinfo(irq, &regaddr, &bit) == 0)
+ {
+ /* Clear the appropriate bit in the register to enable the interrupt */
+
+ 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)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (stm32_irqinfo(irq, &regaddr, &bit) == 0)
+ {
+ /* Set the appropriate bit in the register to enable the interrupt */
+
+ regval = getreg32(regaddr);
+ regval |= bit;
+ putreg32(regval, regaddr);
+ }
+ stm32_dumpnvic("enable", irq);
+}
+
+/****************************************************************************
+ * Name: up_maskack_irq
+ *
+ * Description:
+ * Mask the IRQ and acknowledge it
+ *
+ ****************************************************************************/
+
+void up_maskack_irq(int irq)
+{
+ up_disable_irq(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_INTERRUPTS)
+ {
+ irq -= 4;
+ regaddr = NVIC_SYSH_PRIORITY(irq);
+ }
+ else
+ {
+ irq -= STM32_IRQ_INTERRUPTS;
+ 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/nuttx/arch/arm/src/stm32/stm32_iwdg.c b/nuttx/arch/arm/src/stm32/stm32_iwdg.c
new file mode 100644
index 000000000..fd51ba0fe
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_iwdg.c
@@ -0,0 +1,711 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_iwdg.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <nuttx/arch.h>
+
+#include <stdint.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/clock.h>
+#include <nuttx/watchdog.h>
+#include <arch/board/board.h>
+
+#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, uncalibrathed 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 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_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 millisecnds.
+ *
+ * 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 = irqsave();
+ stm32_putreg(IWDG_KR_KEY_START, STM32_IWDG_KR);
+ priv->lastreset = clock_systimer();
+ priv->started = true;
+ irqrestore(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 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 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 = irqsave();
+ stm32_putreg(IWDG_KR_KEY_RELOAD, STM32_IWDG_KR);
+ priv->lastreset = clock_systimer();
+ irqrestore(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.
+ * stawtus - 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 millisecnds.
+ *
+ * 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 explicity 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 intialized 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 ocsillator is enabled. NOTE: The LSI oscillator
+ * is enabled here but is not disabled by this file (because this file does
+ * not know the 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)
+ {
+ uint32_t cr = getreg32(STM32_DBGMCU_CR);
+ cr |= DBGMCU_CR_IWDGSTOP;
+ putreg32(cr, STM32_DBGMCU_CR);
+ }
+#endif
+}
+
+#endif /* CONFIG_WATCHDOG && CONFIG_STM32_IWDG */
diff --git a/nuttx/arch/arm/src/stm32/stm32_lowputc.c b/nuttx/arch/arm/src/stm32/stm32_lowputc.c
new file mode 100644
index 000000000..7f7205672
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_lowputc.c
@@ -0,0 +1,428 @@
+/**************************************************************************
+ * arch/arm/src/stm32/stm32_lowputc.c
+ *
+ * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+
+#include "stm32_rcc.h"
+#include "stm32_gpio.h"
+#include "stm32_uart.h"
+#include "stm32_internal.h"
+
+/**************************************************************************
+ * Private Definitions
+ **************************************************************************/
+/* Select USART parameters for the selected console */
+
+#if defined(CONFIG_USART1_SERIAL_CONSOLE)
+# define STM32_CONSOLE_BASE STM32_USART1_BASE
+# define STM32_APBCLOCK STM32_PCLK2_FREQUENCY
+# 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
+#elif defined(CONFIG_USART2_SERIAL_CONSOLE)
+# define STM32_CONSOLE_BASE STM32_USART2_BASE
+# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY
+# 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
+#elif defined(CONFIG_USART3_SERIAL_CONSOLE)
+# define STM32_CONSOLE_BASE STM32_USART3_BASE
+# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY
+# 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
+#elif defined(CONFIG_UART4_SERIAL_CONSOLE)
+# define STM32_CONSOLE_BASE STM32_UART4_BASE
+# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY
+# 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
+#elif defined(CONFIG_UART5_SERIAL_CONSOLE)
+# define STM32_CONSOLE_BASE STM32_UART5_BASE
+# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY
+# 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
+#elif defined(CONFIG_USART6_SERIAL_CONSOLE)
+# define STM32_CONSOLE_BASE STM32_USART6_BASE
+# define STM32_APBCLOCK STM32_PCLK2_FREQUENCY
+# 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
+#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
+
+#define USART_CR1_CLRBITS (USART_CR1_M|USART_CR1_PCE|USART_CR1_PS|USART_CR1_TE|USART_CR1_RE|USART_CR1_ALLINTS)
+#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
+
+#define USART_CR2_CLRBITS (USART_CR2_STOP_MASK|USART_CR2_CLKEN|USART_CR2_CPOL|USART_CR2_CPHA|USART_CR2_LBCL|USART_CR2_LBDIE)
+#define USART_CR2_SETBITS USART_CR2_STOP2_VALUE
+
+/* CR3 settings */
+
+#define USART_CR3_CLRBITS (USART_CR3_CTSIE|USART_CR3_CTSE|USART_CR3_RTSE|USART_CR3_EIE)
+#define USART_CR3_SETBITS 0
+
+/* Calculate USART BAUD rate divider
+ *
+ * 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))
+
+/**************************************************************************
+ * Private Types
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Function Prototypes
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * 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(STM32_CONSOLE_BASE + STM32_USART_SR_OFFSET) & USART_SR_TXE) == 0);
+
+ /* Then send the character */
+
+ putreg32((uint32_t)ch, STM32_CONSOLE_BASE + STM32_USART_DR_OFFSET);
+#endif
+}
+
+/**************************************************************************
+ * 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);
+ stm32_configgpio(STM32_CONSOLE_TX);
+#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
+#endif /* HAVE_UART */
+}
+#elif defined(CONFIG_STM32_STM32F20XX) || 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
+
+ /* 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);
+ stm32_configgpio(STM32_CONSOLE_TX);
+#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
+#endif /* HAVE_UART */
+}
+#else
+# error "Unsupported STM32 chip"
+#endif
+
+
diff --git a/nuttx/arch/arm/src/stm32/stm32_lowputc.h b/nuttx/arch/arm/src/stm32/stm32_lowputc.h
new file mode 100644
index 000000000..659de7b1c
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_lowputc.h
@@ -0,0 +1,79 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_lowputc.h
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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.
+ *
+ ************************************************************************************/
+
+EXTERN void stm32_lowsetup(void);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32_STM32_LOWPUTC_H */
+
diff --git a/nuttx/arch/arm/src/stm32/stm32_lse.c b/nuttx/arch/arm/src/stm32/stm32_lse.c
new file mode 100644
index 000000000..931199efd
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_lse.c
@@ -0,0 +1,105 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_lse.c
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.orgr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include "up_arch.h"
+
+#include "stm32_rcc.h"
+#include "stm32_waste.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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.
+ *
+ * Todo:
+ * Check for LSE good timeout and return with -1,
+ *
+ ****************************************************************************/
+
+void stm32_rcc_enablelse(void)
+{
+ /* 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();
+ }
+
+ /* The primariy purpose of the LSE clock is to drive the RTC. The RTC could
+ * also be driven by the LSI (but that would be very inaccurate) or by the
+ * HSE (but that would prohibit low-power operation)
+ *
+ * Select LSE as RTC Clock Source by setting the RTCSEL field of the RCC BDCR
+ * register.
+ */
+
+#ifdef CONFIG_RTC
+ modifyreg16(STM32_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSE);
+
+ /* Enable the RTC Clock by setting the RTCEN bit in the RCC BDCR register */
+
+ modifyreg16(STM32_RCC_BDCR, 0, RCC_BDCR_RTCEN);
+#endif
+}
diff --git a/nuttx/arch/arm/src/stm32/stm32_lsi.c b/nuttx/arch/arm/src/stm32/stm32_lsi.c
new file mode 100644
index 000000000..e365fbf06
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_lsi.c
@@ -0,0 +1,100 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_lsi.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.orgr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include "up_arch.h"
+
+#include "stm32_rcc.h"
+
+/****************************************************************************
+ * 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/nuttx/arch/arm/src/stm32/stm32_otgfs.h b/nuttx/arch/arm/src/stm32/stm32_otgfs.h
new file mode 100644
index 000000000..74f2bdd31
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_otgfs.h
@@ -0,0 +1,93 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_otgfs.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include <stdint.h>
+
+#include "stm32.h"
+#include "chip/stm32_otgfs.h"
+
+/************************************************************************************
+ * 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_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.
+ *
+ ************************************************************************************/
+
+EXTERN void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32_STM32_OTGFS_H */
+
diff --git a/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c b/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
new file mode 100644
index 000000000..461d500ad
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
@@ -0,0 +1,5439 @@
+/*******************************************************************************
+ * arch/arm/src/stm32/stm32_usbdev.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/usb/usb.h>
+#include <nuttx/usb/usbdev.h>
+#include <nuttx/usb/usbdev_trace.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "stm32_otgfs.h"
+
+#if defined(CONFIG_USBDEV) && defined(CONFIG_STM32_OTGFS)
+
+/*******************************************************************************
+ * 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
+
+/* REVISIT! This forces a hack that polls DTXFSTS for space in the Tx FIFO.
+ * Enabling this option is a BAD thing. It will cause inline waits inside
+ * of the USB interrupt handler. The correct way to handle this is to
+ * enable the correct TxFIFO interrupt and wait until the Tx FIFO is empty.
+ * Unfortunately, the interrupt driven logic is not working... Please fix!
+ */
+
+#define ENABLE_DTXFSTS_POLLHACK 1
+
+/* 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_EPOUTNULLPACKET 0x14
+#define STM32_TRACEERR_INVALIDCTRLREQ 0x15
+#define STM32_TRACEERR_INVALIDPARMS 0x16
+#define STM32_TRACEERR_IRQREGISTRATION 0x17
+#define STM32_TRACEERR_NOEP 0x18
+#define STM32_TRACEERR_NOTCONFIGURED 0x19
+#define STM32_TRACEERR_EPOUTQEMPTY 0x1a
+#define STM32_TRACEERR_EPINQEMPTY 0x1b
+#define STM32_TRACEERR_NOOUTSETUP 0x1c
+
+/* 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 configured:1; /* 1: Endpoint has been configured */
+ 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 connected:1; /* 1: Host connected */
+ 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:4; /* Bitset of available 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 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,
+};
+
+/*******************************************************************************
+ * 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 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: 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 packed 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 isconchronous 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;
+#ifdef ENABLE_DTXFSTS_POLLHACK
+ int32_t timeout;
+#endif
+ 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_EPINQEMPTY), 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;
+ }
+
+ /* Loop while there are still bytes to be transferred (or a zero-length-
+ * packet, ZLP, to be sent). The loop will also be terminated if there
+ * is insufficient space remaining in the TxFIFO to send a complete
+ * packet.
+ */
+
+ while (privreq->req.xfrd < privreq->req.len || privep->zlp)
+ {
+ /* 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);
+
+#ifdef ENABLE_DTXFSTS_POLLHACK
+ /* If ENABLE_DTXFSTS_POLLHACK is enabled , then poll DTXFSTS until
+ * space in the TxFIFO is available. If it doesn't become available,
+ * in a reasonable amount of time, then just pretend that it is.
+ */
+
+ for (timeout = 250000; timeout > 0; timeout--)
+ {
+ regval = stm32_getreg(regaddr);
+ if ((regval & OTGFS_DTXFSTS_MASK) >= nwords)
+ {
+ break;
+ }
+ }
+#else
+ /* If ENABLE_DTXFSTS_POLLHACK is not enabled, then check once 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 ((regval & OTGFS_DTXFSTS_MASK) < nwords)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_EMPWAIT), (uint16_t)regval);
+
+ /* There is insufficent 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 loop */
+
+ break;
+ }
+#endif
+
+ /* 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);
+ stm32_req_complete(privep, OK);
+
+ /* The endpoint is no longer transferring data */
+
+ privep->active = false;
+ }
+}
+
+/*******************************************************************************
+ * 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 addess 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 addess 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;
+ DEBUGASSERT(priv->ep0state == EP0STATE_SETUP_OUT);
+
+ 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];
+ }
+
+ /* Verify that the endpoint has been configured */
+
+ if (!privep->configured)
+ {
+ return NULL;
+ }
+
+ /* 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);
+ }
+ priv->epavail = 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)
+{
+ uint32_t regval;
+ uint8_t testmode;
+
+ regval = stm32_getreg(STM32_OTGFS_DCTL);
+
+ 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 selfpowered */
+
+ 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;
+
+ /* 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 interrrupt 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 dat from the exisiting 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;
+
+ /* 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 for FIFO not empty. Bits n corresponds to endpoint n.
+ * That condition corresponds to bit 7 of the DIEPINT interrupt
+ * status register.
+ */
+
+ 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 interrups 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);
+}
+
+/*******************************************************************************
+ * 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;
+
+ /* 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 &&
+ priv->connected &&
+ 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;
+ 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)
+ {
+ /* 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 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 ((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)
+ {
+ regval &= ~(OTGFS_DOEPCTL_MPSIZ_MASK | OTGFS_DIEPCTL_EPTYP_MASK | OTGFS_DIEPCTL_TXFNUM_MASK);
+ regval |= mpsiz;
+ regval |= (eptype << OTGFS_DOEPCTL_EPTYP_SHIFT);
+ regval |= (eptype << OTGFS_DIEPCTL_TXFNUM_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)
+ {
+ 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 = irqsave();
+ 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_mdelay(50);
+#endif
+
+ /* Then disble 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);
+
+ irqrestore(flags);
+}
+
+/*******************************************************************************
+ * Name: stm32_epin_disable
+ *
+ * Description:
+ * Diable an IN endpoint 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);
+
+ /* 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);
+ stm32_putreg(OTGFS_DIEPINT_INEPNE, regaddr);
+
+ /* Deactivate and disable the endpoint by setting the EPIS and SNAK bits
+ * the DIEPCTLx register.
+ */
+
+ flags = irqsave();
+ 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);
+
+ /* 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);
+
+ irqrestore(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 *)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);
+ 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 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
+ 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 = irqsave();
+
+ /* 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 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);
+ stm32_epout_request(priv, privep);
+ }
+ }
+ }
+
+ irqrestore(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;
+ FAR struct stm32_usbdev_s *priv;
+ irqstate_t flags;
+
+#ifdef CONFIG_DEBUG
+ if (!ep || !req)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
+ return -EINVAL;
+ }
+#endif
+
+ usbtrace(TRACE_EPCANCEL, privep->epphy);
+ priv = privep->dev;
+
+ flags = irqsave();
+
+ /* 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);
+ irqrestore(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_mdelay(50);
+#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);
+
+ /* Is the endpoint enabled? */
+
+ if ((regval & OTGFS_DIEPCTL_EPENA) != 0)
+ {
+ /* Yes.. the endpoint is enabled, disable it */
+
+ regval = OTGFS_DIEPCTL_EPDIS;
+ }
+ else
+ {
+ regval = 0;
+ }
+
+ /* 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 = irqsave();
+ if (resume)
+ {
+ ret = stm32_ep_clrstall(privep);
+ }
+ else
+ {
+ ret = stm32_ep_setstall(privep);
+ }
+ irqrestore(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 */
+
+ flags = irqsave();
+ epavail = priv->epavail;
+
+ /* 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 &= ~(1 << epno);
+
+ /* And return the pointer to the standard endpoint structure */
+
+ irqrestore(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);
+ irqrestore(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 = irqsave();
+ priv->epavail |= (1 << privep->epphy);
+ irqrestore(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 = irqsave();
+ 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);
+ }
+ }
+
+ irqrestore(flags);
+ return OK;
+}
+
+/*******************************************************************************
+ * Name: stm32_selfpowered
+ *
+ * Description:
+ * Sets/clears the device selfpowered 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 = irqsave();
+ 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);
+ up_mdelay(3);
+
+ irqrestore(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 = 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 startup the core is in FS mode. */
+
+ /* Disable the USB global interrupt by clearing GINTMSK in the global OTG
+ * FS AHB configuration register.
+ */
+
+ 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 */
+
+ 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(regval, STM32_OTGFS_GCCFG);
+ up_mdelay(20);
+
+ /* 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(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.
+ */
+
+ 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);
+
+ /* Set the interrrupt priority */
+
+ up_prioritize_irq(STM32_IRQ_OTGFS, CONFIG_OTGFS_PRI);
+ 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 = irqsave();
+ 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_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;
+ irqrestore(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 = irqsave();
+ stm32_usbreset(priv);
+
+ /* Unbind the class driver */
+
+ CLASS_UNBIND(driver, &priv->usbdev);
+
+ /* Disable USB controller interrupts */
+
+ up_disable_irq(STM32_IRQ_OTGFS);
+
+ /* Disconnect device */
+
+ stm32_pullup(&priv->usbdev, false);
+
+ /* Unhook the driver */
+
+ priv->driver = NULL;
+ irqrestore(flags);
+
+ return OK;
+}
+
+#endif /* CONFIG_USBDEV && CONFIG_STM32_OTGFSDEV */
diff --git a/nuttx/arch/arm/src/stm32/stm32_otgfshost.c b/nuttx/arch/arm/src/stm32/stm32_otgfshost.c
new file mode 100644
index 000000000..02b12ec87
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_otgfshost.c
@@ -0,0 +1,4290 @@
+/*******************************************************************************
+ * arch/arm/src/stm32/stm32_otgfshost.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/usb/usb.h>
+#include <nuttx/usb/usbhost.h>
+
+#include <arch/irq.h>
+
+#include "chip.h" /* Includes default GPIO settings */
+#include <arch/board/board.h> /* May redefine GPIO settings */
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "stm32_usbhost.h"
+
+#if defined(CONFIG_USBHOST) && defined(CONFIG_STM32_OTGFS)
+
+/*******************************************************************************
+ * 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-requistites (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 */
+#define STM32_DEF_DEVADDR 0 /* Default device address */
+
+/* Delays **********************************************************************/
+
+#define STM32_READY_DELAY 200000 /* In loop counts */
+#define STM32_FLUSH_DELAY 200000 /* In loop counts */
+#define STM32_SETUP_DELAY 5000 /* In frames */
+#define STM32_DATANAK_DELAY 5000 /* In frames */
+
+/* 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 */
+};
+
+/* 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 epno; /* Device endpoint number (0-127) */
+ uint8_t eptype; /* See OTGFS_EPTYPE_* definitions */
+ 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 */
+ volatile uint16_t buflen; /* Buffer length (remaining) */
+ volatile uint16_t inflight; /* Number of Tx bytes "in-flight" */
+ FAR uint8_t *buffer; /* Transfer buffer pointer */
+};
+
+/* 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;
+
+ /* The bound device class driver */
+
+ struct usbhost_class_s *class;
+
+ /* Overall driver status */
+
+ volatile uint8_t smstate; /* The state of the USB host state machine */
+ uint8_t devaddr; /* Device address */
+ uint8_t ep0in; /* EP0 IN control channel index */
+ uint8_t ep0out; /* EP0 OUT control channel index */
+ uint8_t ep0size; /* EP0 max packet size */
+ uint8_t chidx; /* ID of channel waiting for space in Tx FIFO */
+ bool lowspeed; /* True: low speed device */
+ volatile bool connected; /* Connected to device */
+ volatile bool eventwait; /* True: Thread is waiting for a port event */
+ sem_t exclsem; /* Support mutually exclusive access */
+ sem_t eventsem; /* Semaphore to wait for a port event */
+
+ /* 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);
+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);
+
+/* Control/data transfer logic *************************************************/
+
+static void stm32_transfer_start(FAR struct stm32_usbhost_s *priv, int chidx);
+static inline uint16_t stm32_getframe(void);
+static int stm32_ctrl_sendsetup(FAR struct stm32_usbhost_s *priv,
+ FAR const struct usb_ctrlreq_s *req);
+static int stm32_ctrl_senddata(FAR struct stm32_usbhost_s *priv,
+ FAR uint8_t *buffer, unsigned int buflen);
+static int stm32_ctrl_recvdata(FAR struct stm32_usbhost_s *priv,
+ FAR uint8_t *buffer, unsigned int buflen);
+static int stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
+ FAR uint8_t *buffer, size_t buflen);
+static int stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
+ FAR uint8_t *buffer, size_t buflen);
+
+/* 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_iisooxfrisr(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_driver_s *drvr, bool connected);
+static int stm32_enumerate(FAR struct usbhost_driver_s *drvr);
+static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
+ 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,
+ FAR const struct usb_ctrlreq_s *req,
+ FAR uint8_t *buffer);
+static int stm32_ctrlout(FAR struct usbhost_driver_s *drvr,
+ FAR const struct usb_ctrlreq_s *req,
+ FAR const uint8_t *buffer);
+static int stm32_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
+ FAR uint8_t *buffer, size_t buflen);
+static void stm32_disconnect(FAR struct usbhost_driver_s *drvr);
+
+/* 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 =
+{
+ .drvr =
+ {
+ .wait = stm32_wait,
+ .enumerate = stm32_enumerate,
+ .ep0configure = stm32_ep0configure,
+ .epalloc = stm32_epalloc,
+ .epfree = stm32_epfree,
+ .alloc = stm32_alloc,
+ .free = stm32_free,
+ .ioalloc = stm32_ioalloc,
+ .iofree = stm32_iofree,
+ .ctrlin = stm32_ctrlin,
+ .ctrlout = stm32_ctrlout,
+ .transfer = stm32_transfer,
+ .disconnect = stm32_disconnect,
+ },
+ .class = NULL,
+};
+
+/*******************************************************************************
+ * 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)
+{
+ 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 (priv->chan[chidx].eptype)
+ {
+ case OTGFS_EPTYPE_CTRL:
+ case OTGFS_EPTYPE_BULK:
+ {
+ /* 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 (priv->chan[chidx].in)
+ {
+ regval |= OTGFS_HCINT_BBERR;
+ }
+ else
+ {
+ 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 (priv->chan[chidx].in)
+ {
+ regval |= OTGFS_HCINT_BBERR;
+ }
+ }
+ 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 (priv->chan[chidx].in)
+ {
+ regval |= (OTGFS_HCINT_TXERR | OTGFS_HCINT_BBERR);
+ }
+ }
+ 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)priv->chan[chidx].maxpacket << OTGFS_HCCHAR_MPSIZ_SHIFT) |
+ ((uint32_t)priv->chan[chidx].epno << OTGFS_HCCHAR_EPNUM_SHIFT) |
+ ((uint32_t)priv->chan[chidx].eptype << OTGFS_HCCHAR_EPTYP_SHIFT) |
+ ((uint32_t)priv->devaddr << OTGFS_HCCHAR_DAD_SHIFT);
+
+ /* Special case settings for low speed devices */
+
+ if (priv->lowspeed)
+ {
+ regval |= OTGFS_HCCHAR_LSDEV;
+ }
+
+ /* Special case settings for IN endpoints */
+
+ if (priv->chan[chidx].in)
+ {
+ regval |= OTGFS_HCCHAR_EPDIR_IN;
+ }
+
+ /* Special case settings for INTR endpoints */
+
+ if (priv->chan[chidx].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 interrrupt
+ * handling logic to know what to do next.
+ */
+
+ 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 = irqsave();
+ 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;
+ ret = OK;
+ }
+
+ irqrestore(flags);
+ return ret;
+}
+
+/*******************************************************************************
+ * 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 = irqsave();
+
+ /* Loop, testing for an end of transfer conditino. 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
+ * tranfer 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 succeeed. 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;
+ irqrestore(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 the transfer complete? Is there a thread waiting for this transfer
+ * to complete?
+ */
+
+ if (chan->result != EBUSY && chan->waiter)
+ {
+ ullvdbg("Wakeup with result: %d\n", chan->result);
+ stm32_givesem(&chan->waitsem);
+ chan->waiter = false;
+ }
+}
+
+/*******************************************************************************
+ * 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];
+ uvdbg("chidx: %d buflen: %d\n", chidx, chan->buflen);
+
+ chan->result = EBUSY;
+ chan->inflight = 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;
+ ulldbg("CLIP: chidx: %d buflen: %d\n", 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;
+ }
+
+ 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.
+ *
+ *******************************************************************************/
+
+static inline uint16_t stm32_getframe(void)
+{
+ return (uint16_t)(stm32_getreg(STM32_OTGFS_HFNUM) & OTGFS_HFNUM_FRNUM_MASK);
+}
+
+/*******************************************************************************
+ * Name: stm32_ctrl_sendsetup
+ *
+ * Description:
+ * Send an IN/OUT SETUP packet.
+ *
+ *******************************************************************************/
+
+static int stm32_ctrl_sendsetup(FAR struct stm32_usbhost_s *priv,
+ FAR const struct usb_ctrlreq_s *req)
+{
+ FAR struct stm32_chan_s *chan;
+ uint16_t start;
+ uint16_t elapsed;
+ int ret;
+
+ /* Loop while the device reports NAK (and a timeout is not exceeded */
+
+ chan = &priv->chan[priv->ep0out];
+ start = stm32_getframe();
+
+ do
+ {
+ /* Send the SETUP packet */
+
+ chan->pid = OTGFS_PID_SETUP;
+ chan->buffer = (FAR uint8_t *)req;
+ chan->buflen = USB_SIZEOF_CTRLREQ;
+
+ /* Set up for the wait BEFORE starting the transfer */
+
+ ret = stm32_chan_waitsetup(priv, chan);
+ if (ret != OK)
+ {
+ udbg("ERROR: Device disconnected\n");
+ return ret;
+ }
+
+ /* Start the transfer */
+
+ stm32_transfer_start(priv, priv->ep0out);
+
+ /* 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)
+ {
+ udbg("Transfer failed: %d\n", ret);
+ }
+
+ /* Return the result in any event */
+
+ return ret;
+ }
+
+ /* Get the elapsed time (in frames) */
+
+ elapsed = stm32_getframe() - 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 uint8_t *buffer, unsigned int buflen)
+{
+ FAR struct stm32_chan_s *chan = &priv->chan[priv->ep0out];
+ int ret;
+
+ /* Save buffer information */
+
+ chan->buffer = buffer;
+ chan->buflen = buflen;
+
+ /* 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 != OK)
+ {
+ udbg("ERROR: Device disconnected\n");
+ return ret;
+ }
+
+ /* Start the transfer */
+
+ stm32_transfer_start(priv, priv->ep0out);
+
+ /* 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 uint8_t *buffer, unsigned int buflen)
+{
+ FAR struct stm32_chan_s *chan = &priv->chan[priv->ep0in];
+ int ret;
+
+ /* Save buffer information */
+
+ chan->pid = OTGFS_PID_DATA1;
+ chan->buffer = buffer;
+ chan->buflen = buflen;
+
+ /* Set up for the wait BEFORE starting the transfer */
+
+ ret = stm32_chan_waitsetup(priv, chan);
+ if (ret != OK)
+ {
+ udbg("ERROR: Device disconnected\n");
+ return ret;
+ }
+
+ /* Start the transfer */
+
+ stm32_transfer_start(priv, priv->ep0in);
+
+ /* Wait for the transfer to complete and return the result */
+
+ return stm32_chan_wait(priv, chan);
+}
+
+/*******************************************************************************
+ * Name: stm32_in_transfer
+ *
+ * Description:
+ * Transfer 'buflen' bytes into 'buffer' from an IN channel.
+ *
+ *******************************************************************************/
+
+static int stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
+ FAR uint8_t *buffer, size_t buflen)
+{
+ FAR struct stm32_chan_s *chan;
+ uint16_t start;
+ uint16_t elapsed;
+ int ret = OK;
+
+ /* 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;
+
+ start = stm32_getframe();
+ while (chan->buflen > 0)
+ {
+ /* Set up for the wait BEFORE starting the transfer */
+
+ ret = stm32_chan_waitsetup(priv, chan);
+ if (ret != OK)
+ {
+ udbg("ERROR: Device disconnected\n");
+ return ret;
+ }
+
+ /* Set up for the transfer based on the direction and the endpoint type */
+
+ 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 */
+
+ chan->pid = OTGFS_PID_DATA0;
+ }
+ break;
+
+ case OTGFS_EPTYPE_BULK: /* Bulk */
+ case OTGFS_EPTYPE_INTR: /* Interrupt */
+ {
+ /* Setup the IN data PID */
+
+ chan->pid = chan->indata1 ? OTGFS_PID_DATA1 : OTGFS_PID_DATA0;
+ }
+ break;
+ }
+
+ /* Start the transfer */
+
+ stm32_transfer_start(priv, chidx);
+
+ /* 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 != OK)
+ {
+ udbg("Transfer failed: %d\n", 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 becasue the then the transfer
+ * buffer pointer and buffer size will be unaltered.
+ */
+
+ elapsed = stm32_getframe() - start;
+ if (ret != -EAGAIN || /* Not a NAK condition OR */
+ elapsed >= STM32_DATANAK_DELAY || /* Timeout has elapsed OR */
+ chan->buflen != buflen) /* Data has been partially transferred */
+ {
+ /* Break out and return the error */
+
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*******************************************************************************
+ * Name: stm32_out_transfer
+ *
+ * Description:
+ * Transfer the 'buflen' bytes in 'buffer' through an OUT channel.
+ *
+ *******************************************************************************/
+
+static int stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
+ FAR uint8_t *buffer, size_t buflen)
+{
+ FAR struct stm32_chan_s *chan;
+ uint16_t start;
+ uint16_t elapsed;
+ size_t xfrlen;
+ int ret = OK;
+
+ /* 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 = stm32_getframe();
+
+ 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;
+
+ /* Set up for the wait BEFORE starting the transfer */
+
+ ret = stm32_chan_waitsetup(priv, chan);
+ if (ret != OK)
+ {
+ udbg("ERROR: Device disconnected\n");
+ return ret;
+ }
+
+ /* Set up for the transfer based on the direction and the endpoint type */
+
+ 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 */
+
+ chan->pid = OTGFS_PID_DATA0;
+ }
+ break;
+
+ case OTGFS_EPTYPE_BULK: /* Bulk */
+ {
+ /* Setup the OUT data PID */
+
+ chan->pid = chan->outdata1 ? OTGFS_PID_DATA1 : OTGFS_PID_DATA0;
+ }
+ break;
+
+ case OTGFS_EPTYPE_INTR: /* Interrupt */
+ {
+ /* Setup the OUT data PID */
+
+ chan->pid = chan->outdata1 ? OTGFS_PID_DATA1 : OTGFS_PID_DATA0;
+
+ /* Toggle the OUT data PID for the next transfer */
+
+ chan->outdata1 ^= true;
+ }
+ }
+
+ /* Start the transfer */
+
+ stm32_transfer_start(priv, chidx);
+
+ /* Wait for the transfer to complete and get the result */
+
+ ret = stm32_chan_wait(priv, chan);
+
+ /* Handle transfer failures */
+
+ if (ret != OK)
+ {
+ udbg("Transfer failed: %d\n", 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 becasue the then the transfer
+ * buffer pointer and buffer size will be unaltered.
+ */
+
+ elapsed = stm32_getframe() - start;
+ if (ret != -EAGAIN || /* Not a NAK condition OR */
+ elapsed >= STM32_DATANAK_DELAY || /* Timeout has elapsed OR */
+ chan->buflen != xfrlen) /* Data has been partially transferred */
+ {
+ /* Break out and return the error */
+
+ break;
+ }
+
+ /* 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;
+ }
+ }
+
+ return ret;
+}
+
+/*******************************************************************************
+ * 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 interrrupt 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 interrrupt 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 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 reult */
+
+ 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 tranfer, 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 even of a NAK.
+ */
+
+#if 0
+ /* Halt the interrupt channel */
+
+ if (chan->eptype == OTGFS_EPTYPE_CTRL)
+ {
+ /* Halt the channel -- the CHH interrrupt is expected next */
+
+ stm32_chan_halt(priv, chidx, CHREASON_NAK);
+ }
+
+ /* Re-activate CTRL and BULK channels */
+
+ 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 interrrupt 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].buflen -= priv->chan[chidx].inflight;
+ priv->chan[chidx].inflight = 0;
+
+ /* Halt the channel -- the CHH interrrupt 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 interrrupt 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 */
+
+ ullvdbg("Connected\n");
+ priv->connected = true;
+ DEBUGASSERT(priv->smstate == SMSTATE_DETACHED);
+
+ /* Notify any waiters */
+
+ priv->smstate = SMSTATE_ATTACHED;
+ if (priv->eventwait)
+ {
+ stm32_givesem(&priv->eventsem);
+ priv->eventwait = 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 */
+
+ ullvdbg("Disconnected\n");
+
+ /* Are we bound to a class driver? */
+
+ if (priv->class)
+ {
+ /* Yes.. Disconnect the class driver */
+
+ CLASS_DISCONNECTED(priv->class);
+ priv->class = NULL;
+ }
+
+ /* Re-Initilaize Host for new Enumeration */
+
+ priv->smstate = SMSTATE_DETACHED;
+ priv->ep0size = STM32_EP0_MAX_PACKET_SIZE;
+ priv->devaddr = STM32_DEF_DEVADDR;
+ priv->connected = false;
+ priv->lowspeed = false;
+ stm32_chan_freeall(priv);
+
+ /* Notify any waiters that there is a change in the connection state */
+
+ if (priv->eventwait)
+ {
+ stm32_givesem(&priv->eventsem);
+ priv->eventwait = 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].buflen -= 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 minsize;
+ 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->buflen -= 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 NPTXFE interrupt on the final packet).
+ */
+
+ if (chan->buflen <= 0)
+ {
+ /* 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 minimal size packet that can be sent. Something is serioulsy
+ * configured wrong if one packet will not fit into the empty Tx FIFO.
+ */
+
+ minsize = MIN(chan->buflen, chan->maxpacket);
+ DEBUGASSERT(chan->buflen > 0 && avail >= minsize);
+
+ /* Get the size to 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;
+ }
+
+ /* 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 wrsize: %d\n",
+ regval, chidx, avail, chan->buflen, 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 minsize;
+ 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->buflen -= 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->buflen <= 0)
+ {
+ /* 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 minimal size packet that can be sent. Something is serioulsy
+ * configured wrong if one packet will not fit into the empty Tx FIFO.
+ */
+
+ minsize = MIN(chan->buflen, chan->maxpacket);
+ DEBUGASSERT(chan->buflen > 0 && avail >= minsize);
+
+ /* Get the size to 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;
+ }
+
+ /* 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 wrsize: %d\n",
+ regval, chidx, avail, chan->buflen, 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;
+
+ /* 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. */
+
+ 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.
+ */
+
+ newhprt |= OTGFS_HPRT_PCDET;
+ 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. */
+
+ 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 */
+
+ stm32_putreg(STM32_OTGFS_HFIR, 6000);
+
+ /* Are we switching from FS to LS? */
+
+ if ((hcfg & OTGFS_HCFG_FSLSPCS_MASK) != OTGFS_HCFG_FSLSPCS_LS6MHz)
+ {
+ /* 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) */
+ {
+ stm32_putreg(STM32_OTGFS_HFIR, 48000);
+
+ /* Are we switching from LS to FS? */
+
+ if ((hcfg & OTGFS_HCFG_FSLSPCS_MASK) != OTGFS_HCFG_FSLSPCS_FS48MHz)
+ {
+ /* 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_iisooxfrisr
+ *
+ * Description:
+ * USB OTG FS incomplete isochronous interrupt handler
+ *
+ *******************************************************************************/
+
+static inline void stm32_gint_iisooxfrisr(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_IISOOXFR);
+}
+
+/*******************************************************************************
+ * 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 furhter pending
+ * interrupts.
+ */
+
+ if (pending == 0)
+ {
+ return OK;
+ }
+
+ /* Otherwise, process each pending, unmasked GINT interrupts */
+
+ ullvdbg("GINTSTS: %08x\n", pending);
+
+ /* Handle the start of frame interrupt */
+
+#ifdef CONFIG_STM32_OTGFS_SOFINTR
+ if ((pending & OTGFS_GINT_SOF) != 0)
+ {
+ stm32_gint_sofisr(priv);
+ }
+#endif
+
+ /* Handle the RxFIFO non-empty interrupt */
+
+ if ((pending & OTGFS_GINT_RXFLVL) != 0)
+ {
+ stm32_gint_rxflvlisr(priv);
+ }
+
+ /* Handle the non-periodic TxFIFO empty interrupt */
+
+ if ((pending & OTGFS_GINT_NPTXFE) != 0)
+ {
+ stm32_gint_nptxfeisr(priv);
+ }
+
+ /* Handle the periodic TxFIFO empty interrupt */
+
+ if ((pending & OTGFS_GINT_PTXFE) != 0)
+ {
+ stm32_gint_ptxfeisr(priv);
+ }
+
+ /* Handle the host channels interrupt */
+
+ if ((pending & OTGFS_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)
+ {
+ stm32_gint_discisr(priv);
+ }
+
+ /* Handle the incomplete isochronous OUT transfer */
+
+ if ((pending & OTGFS_GINT_IISOOXFR) != 0)
+ {
+ stm32_gint_iisooxfrisr(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_IISOOXFR | 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 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 = irqsave();
+
+ /* 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);
+ irqrestore(flags);
+}
+
+/*******************************************************************************
+ * USB Host Controller Operations
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Name: stm32_wait
+ *
+ * Description:
+ * Wait for a device to be connected or disconneced.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * connected - TRUE: Wait for device to be connected; FALSE: wait for device
+ * to be disconnected
+ *
+ * Returned Values:
+ * Zero (OK) is returned when a device in connected. This function will not
+ * return until either (1) a device is connected or (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_driver_s *drvr, bool connected)
+{
+ FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
+ irqstate_t flags;
+
+ /* Are we already connected? */
+
+ flags = irqsave();
+ while (priv->connected == connected)
+ {
+ /* No... wait for the connection/disconnection */
+
+ priv->eventwait = true;
+ stm32_takesem(&priv->eventsem);
+ }
+
+ irqrestore(flags);
+
+ udbg("Connected:%s\n", priv->connected ? "YES" : "NO");
+ return OK;
+}
+
+/*******************************************************************************
+ * 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 configdesc() method
+ * of the struct usbhost_class_s interface. After that, the class is in
+ * charge of the sequence of operations.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * - Only a single class bound to a single device is supported.
+ * - Called from a single thread so no mutual exclusion is required.
+ * - Never called from an interrupt handler.
+ *
+ *******************************************************************************/
+
+static int stm32_enumerate(FAR struct usbhost_driver_s *drvr)
+{
+ struct stm32_usbhost_s *priv = (struct stm32_usbhost_s *)drvr;
+ uint32_t regval;
+ int chidx;
+ int ret;
+
+ /* 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;
+ }
+
+ DEBUGASSERT(priv->smstate == SMSTATE_ATTACHED);
+
+ /* Allocate and initialize the control OUT channel */
+
+ chidx = stm32_chan_alloc(priv);
+ DEBUGASSERT(chidx >= 0);
+
+ priv->ep0out = chidx;
+ priv->chan[chidx].epno = 0;
+ priv->chan[chidx].in = false;
+ priv->chan[chidx].eptype = OTGFS_EPTYPE_CTRL;
+ priv->chan[chidx].maxpacket = STM32_EP0_DEF_PACKET_SIZE;
+ priv->chan[chidx].indata1 = false;
+ priv->chan[chidx].outdata1 = false;
+
+ /* Allocate and initialize the control IN channel */
+
+ chidx = stm32_chan_alloc(priv);
+ DEBUGASSERT(chidx >= 0);
+
+ priv->ep0in = chidx;
+ priv->chan[chidx].epno = 0;
+ priv->chan[chidx].in = true;
+ priv->chan[chidx].eptype = OTGFS_EPTYPE_CTRL;
+ priv->chan[chidx].maxpacket = STM32_EP0_DEF_PACKET_SIZE;
+ priv->chan[chidx].indata1 = false;
+ priv->chan[chidx].outdata1 = false;
+
+ /* 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);
+ priv->lowspeed = ((regval & OTGFS_HPRT_PSPD_MASK) == OTGFS_HPRT_PSPD_LS);
+
+ /* Configure control channels */
+
+ stm32_chan_configure(priv, priv->ep0out) ;
+ stm32_chan_configure(priv, priv->ep0in) ;
+
+ /* Let the common usbhost_enumerate do all of the real work. Note that the
+ * FunctionAddress (USB address) is hardcoded to one.
+ */
+
+ uvdbg("Enumerate the device\n");
+ priv->smstate = SMSTATE_ENUM;
+ ret = usbhost_enumerate(drvr, 1, &priv->class);
+
+ /* 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 */
+
+ 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.
+ * funcaddr - The USB address of the function containing the endpoint that EP0
+ * controls
+ * 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, uint8_t funcaddr,
+ uint16_t maxpacketsize)
+{
+ FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
+
+ DEBUGASSERT(drvr && funcaddr < 128 && maxpacketsize < 2048);
+
+ /* We must have exclusive access to the USB host hardware and state structures */
+
+ stm32_takesem(&priv->exclsem);
+
+ /* Save the device address and EP0 max packet size */
+
+ priv->devaddr = funcaddr;
+ priv->ep0size = maxpacketsize;
+
+ /* Configure the EP0 OUT channel */
+
+ priv->chan[priv->ep0out].maxpacket = maxpacketsize;
+ stm32_chan_configure(priv, priv->ep0out);
+
+ /* Configure the EP0 IN channel */
+
+ priv->chan[priv->ep0in].maxpacket = maxpacketsize;
+ stm32_chan_configure(priv, priv->ep0in);
+
+ 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 desciptor.
+ *
+ * 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;
+ FAR struct stm32_chan_s *chan;
+ int chidx;
+ 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(priv && epdesc && ep && priv->connected);
+
+ /* We must have exclusive access to the USB host hardware and state structures */
+
+ stm32_takesem(&priv->exclsem);
+
+ /* Allocate a host channel for the endpoint */
+
+ chidx = stm32_chan_alloc(priv);
+ if (chidx < 0)
+ {
+ udbg("Failed to allocate a host channel\n");
+ ret = -ENOMEM;
+ goto errout;
+ }
+
+ /* 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
+ * FS hardware.
+ */
+
+ chan = &priv->chan[chidx];
+ chan->epno = epdesc->addr & USB_EPNO_MASK;
+ chan->in = epdesc->in;
+ chan->eptype = epdesc->xfrtype;
+ 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;
+ ret = OK;
+
+errout:
+ 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 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 stm32_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
+{
+ struct stm32_usbhost_s *priv = (struct stm32_usbhost_s *)drvr;
+ int chidx = (int)ep;
+
+ DEBUGASSERT(priv && chidx < STM32_MAX_TX_FIFOS);
+
+ /* We must have exclusive access to the USB host hardware and state structures */
+
+ stm32_takesem(&priv->exclsem);
+
+ /* Halt the channel and mark the channel avaiable */
+
+ stm32_chan_free(priv, chidx);
+
+ 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 kmalloc.
+ *
+ * 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 *)kmalloc(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 kfree().
+ *
+ * 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);
+ kfree(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 kmalloc.
+ *
+ * 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 *)kmalloc(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 kfree().
+ *
+ * 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);
+ kfree(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.
+ * 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:
+ * - Only a single class bound to a single device is supported.
+ * - 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,
+ FAR const struct usb_ctrlreq_s *req,
+ FAR uint8_t *buffer)
+{
+ struct stm32_usbhost_s *priv = (struct stm32_usbhost_s *)drvr;
+ uint16_t buflen;
+ uint16_t start;
+ uint16_t elapsed;
+ int retries;
+ int ret;
+
+ DEBUGASSERT(drvr && 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, req);
+ if (ret < 0)
+ {
+ udbg("stm32_ctrl_sendsetup failed: %d\n", ret);
+ continue;
+ }
+
+ /* Get the start time. Loop again until the timeout expires */
+
+ start = stm32_getframe();
+ do
+ {
+ /* Handle the IN data phase (if any) */
+
+ if (buflen > 0)
+ {
+ ret = stm32_ctrl_recvdata(priv, buffer, buflen);
+ if (ret < 0)
+ {
+ udbg("stm32_ctrl_recvdata failed: %d\n", ret);
+ }
+ }
+
+ /* Handle the status OUT phase */
+
+ if (ret == OK)
+ {
+ priv->chan[priv->ep0out].outdata1 ^= true;
+ ret = stm32_ctrl_senddata(priv, NULL, 0);
+ if (ret == OK)
+ {
+ /* All success transactions exit here */
+
+ stm32_givesem(&priv->exclsem);
+ return OK;
+ }
+
+ udbg("stm32_ctrl_senddata failed: %d\n", ret);
+ }
+
+ /* Get the elapsed time (in frames) */
+
+ elapsed = stm32_getframe() - 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,
+ FAR const struct usb_ctrlreq_s *req,
+ FAR const uint8_t *buffer)
+{
+ struct stm32_usbhost_s *priv = (struct stm32_usbhost_s *)drvr;
+ uint16_t buflen;
+ uint16_t start;
+ uint16_t elapsed;
+ int retries;
+ int ret;
+
+ DEBUGASSERT(drvr && 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 */
+
+ /* Send the SETUP request */
+
+ ret = stm32_ctrl_sendsetup(priv, req);
+ if (ret < 0)
+ {
+ udbg("stm32_ctrl_sendsetup failed: %d\n", ret);
+ continue;
+ }
+
+ /* Get the start time. Loop again until the timeout expires */
+
+ start = stm32_getframe();
+ do
+ {
+ /* Handle the data OUT phase (if any) */
+
+ if (buflen > 0)
+ {
+ /* Start DATA out transfer (only one DATA packet) */
+
+ priv->chan[priv->ep0out].outdata1 = true;
+ ret = stm32_ctrl_senddata(priv, NULL, 0);
+ if (ret < 0)
+ {
+ udbg("stm32_ctrl_senddata failed: %d\n", ret);
+ }
+ }
+
+ /* Handle the status IN phase */
+
+ if (ret == OK)
+ {
+ ret = stm32_ctrl_recvdata(priv, NULL, 0);
+ if (ret == OK)
+ {
+ /* All success transactins exit here */
+
+ stm32_givesem(&priv->exclsem);
+ return OK;
+ }
+
+ udbg("stm32_ctrl_recvdata failed: %d\n", ret);
+ }
+
+ /* Get the elapsed time (in frames) */
+
+ elapsed = stm32_getframe() - 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 and return immediately. 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:
+ * - Only a single class bound to a single device is supported.
+ * - Called from a single thread so no mutual exclusion is required.
+ * - Never called from an interrupt handler.
+ *
+ *******************************************************************************/
+
+static int 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;
+ 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_transfer(priv, chidx, buffer, buflen);
+ }
+ else
+ {
+ ret = stm32_out_transfer(priv, chidx, buffer, buflen);
+ }
+
+ stm32_givesem(&priv->exclsem);
+ return ret;
+}
+
+/*******************************************************************************
+ * 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.
+ *
+ * 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)
+{
+ struct stm32_usbhost_s *priv = (struct stm32_usbhost_s *)drvr;
+ priv->class = 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(10);
+
+ 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(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);
+}
+
+/*******************************************************************************
+ * 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(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);
+}
+
+/*******************************************************************************
+ * 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)
+{
+ int i;
+
+ /* Initialize the state data structure */
+
+ sem_init(&priv->eventsem, 0, 0);
+ sem_init(&priv->exclsem, 0, 1);
+
+ priv->smstate = SMSTATE_DETACHED;
+ priv->ep0size = STM32_EP0_MAX_PACKET_SIZE;
+ priv->devaddr = STM32_DEF_DEVADDR;
+ priv->connected = false;
+ priv->lowspeed = 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];
+ 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: 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 intialized. 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_driver_s *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 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)
+ {
+ udbg("Failed to attach IRQ\n");
+ return NULL;
+ }
+
+ /* Enable USB OTG FS global interrupts */
+
+ stm32_gint_enable();
+
+ /* Enable interrupts at the interrupt controller */
+
+ up_enable_irq(STM32_IRQ_OTGFS);
+ return &priv->drvr;
+}
+
+#endif /* CONFIG_USBHOST && CONFIG_STM32_OTGFS */
diff --git a/nuttx/arch/arm/src/stm32/stm32_pm.h b/nuttx/arch/arm/src/stm32/stm32_pm.h
new file mode 100644
index 000000000..be040d296
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_pm.h
@@ -0,0 +1,142 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_pm.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include <stdbool.h>
+
+#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 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.
+ *
+ ****************************************************************************/
+
+EXTERN 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.
+ *
+ ****************************************************************************/
+
+EXTERN 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 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.
+ *
+ ****************************************************************************/
+
+EXTERN void stm32_pmsleep(bool sleeponexit);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ARCH_ARM_SRC_STM32_STM32_PM_H */
diff --git a/nuttx/arch/arm/src/stm32/stm32_pminitialize.c b/nuttx/arch/arm/src/stm32/stm32_pminitialize.c
new file mode 100644
index 000000000..a1f44a7f4
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <nuttx/power/pm.h>
+
+#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 intialization 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/nuttx/arch/arm/src/stm32/stm32_pmsleep.c b/nuttx/arch/arm/src/stm32/stm32_pmsleep.c
new file mode 100644
index 000000000..3027b99a7
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ * Diego Sanchez <dsanchez@nx-engineering.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 <nuttx/config.h>
+
+#include <stdbool.h>
+
+#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/nuttx/arch/arm/src/stm32/stm32_pmstandby.c b/nuttx/arch/arm/src/stm32/stm32_pmstandby.c
new file mode 100644
index 000000000..467edaec2
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdbool.h>
+
+#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/nuttx/arch/arm/src/stm32/stm32_pmstop.c b/nuttx/arch/arm/src/stm32/stm32_pmstop.c
new file mode 100644
index 000000000..14ce63b55
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdbool.h>
+
+#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/nuttx/arch/arm/src/stm32/stm32_pwm.c b/nuttx/arch/arm/src/stm32/stm32_pwm.c
new file mode 100644
index 000000000..a3ef23e57
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_pwm.c
@@ -0,0 +1,1525 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_pwm.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/pwm.h>
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "stm32_pwm.h"
+#include "stm32_internal.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)
+
+/****************************************************************************
+ * 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
+#ifdef CONFIG_STM32_STM32F10XX
+# define TIMTYPE_TIM2 TIMTYPE_GENERAL16
+# define TIMTYPE_TIM3 TIMTYPE_GENERAL16
+# define TIMTYPE_TIM4 TIMTYPE_GENERAL16
+# define TIMTYPE_TIM5 TIMTYPE_GENERAL16
+#else
+# define TIMTYPE_TIM2 TIMTYPE_GENERAL32
+# define TIMTYPE_TIM3 TIMTYPE_GENERAL32
+# define TIMTYPE_TIM4 TIMTYPE_GENERAL32
+# 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
+
+/* 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 representst 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,...,14} */
+ uint8_t channel; /* Timer output channel: {1,..4} */
+ uint8_t timtype; /* See the TIMTYPE_* definitions */
+#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 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 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,
+ .channel = CONFIG_STM32_TIM1_CHANNEL,
+ .timtype = TIMTYPE_TIM1,
+#ifdef CONFIG_PWM_PULSECOUNT
+ .irq = STM32_IRQ_TIM1UP,
+#endif
+ .base = STM32_TIM1_BASE,
+ .pincfg = PWM_TIM1_PINCFG,
+ .pclk = STM32_APB2_TIM1_CLKIN,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM2_PWM
+static struct stm32_pwmtimer_s g_pwm2dev =
+{
+ .ops = &g_pwmops,
+ .timid = 2,
+ .channel = CONFIG_STM32_TIM2_CHANNEL,
+#ifdef CONFIG_PWM_PULSECOUNT
+ .irq = STM32_IRQ_TIM2,
+#endif
+ .timtype = TIMTYPE_TIM2,
+ .base = STM32_TIM2_BASE,
+ .pincfg = PWM_TIM2_PINCFG,
+ .pclk = STM32_APB1_TIM2_CLKIN,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM3_PWM
+static struct stm32_pwmtimer_s g_pwm3dev =
+{
+ .ops = &g_pwmops,
+ .timid = 3,
+ .channel = CONFIG_STM32_TIM3_CHANNEL,
+#ifdef CONFIG_PWM_PULSECOUNT
+ .irq = STM32_IRQ_TIM3,
+#endif
+ .timtype = TIMTYPE_TIM3,
+ .base = STM32_TIM3_BASE,
+ .pincfg = PWM_TIM3_PINCFG,
+ .pclk = STM32_APB1_TIM3_CLKIN,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM4_PWM
+static struct stm32_pwmtimer_s g_pwm4dev =
+{
+ .ops = &g_pwmops,
+ .timid = 4,
+ .channel = CONFIG_STM32_TIM4_CHANNEL,
+#ifdef CONFIG_PWM_PULSECOUNT
+ .irq = STM32_IRQ_TIM4,
+#endif
+ .timtype = TIMTYPE_TIM4,
+ .base = STM32_TIM4_BASE,
+ .pincfg = PWM_TIM4_PINCFG,
+ .pclk = STM32_APB1_TIM4_CLKIN,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM5_PWM
+static struct stm32_pwmtimer_s g_pwm5dev =
+{
+ .ops = &g_pwmops,
+ .timid = 5,
+ .channel = CONFIG_STM32_TIM5_CHANNEL,
+#ifdef CONFIG_PWM_PULSECOUNT
+ .irq = STM32_IRQ_TIM5,
+#endif
+ .timtype = TIMTYPE_TIM5,
+ .base = STM32_TIM5_BASE,
+ .pincfg = PWM_TIM5_PINCFG,
+ .pclk = STM32_APB1_TIM5_CLKIN,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM8_PWM
+static struct stm32_pwmtimer_s g_pwm8dev =
+{
+ .ops = &g_pwmops,
+ .timid = 8,
+ .channel = CONFIG_STM32_TIM8_CHANNEL,
+#ifdef CONFIG_PWM_PULSECOUNT
+ .irq = STM32_IRQ_TIM8UP,
+#endif
+ .timtype = TIMTYPE_TIM8,
+ .base = STM32_TIM8_BASE,
+ .pincfg = PWM_TIM8_PINCFG,
+ .pclk = STM32_APB2_TIM8_CLKIN,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM9_PWM
+static struct stm32_pwmtimer_s g_pwm9dev =
+{
+ .ops = &g_pwmops,
+ .timid = 9,
+ .channel = CONFIG_STM32_TIM9_CHANNEL,
+ .timtype = TIMTYPE_TIM9,
+#ifdef CONFIG_PWM_PULSECOUNT
+ .irq = STM32_IRQ_TIM9,
+#endif
+ .base = STM32_TIM9_BASE,
+ .pincfg = PWM_TIM9_PINCFG,
+ .pclk = STM32_APB2_TIM9_CLKIN,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM10_PWM
+static struct stm32_pwmtimer_s g_pwm10dev =
+{
+ .ops = &g_pwmops,
+ .timid = 10,
+ .channel = CONFIG_STM32_TIM10_CHANNEL,
+ .timtype = TIMTYPE_TIM10,
+#ifdef CONFIG_PWM_PULSECOUNT
+ .irq = STM32_IRQ_TIM10,
+#endif
+ .base = STM32_TIM10_BASE,
+ .pincfg = PWM_TIM10_PINCFG,
+ .pclk = STM32_APB2_TIM10_CLKIN,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM11_PWM
+static struct stm32_pwmtimer_s g_pwm11dev =
+{
+ .ops = &g_pwmops,
+ .timid = 11,
+ .channel = CONFIG_STM32_TIM11_CHANNEL,
+#ifdef CONFIG_PWM_PULSECOUNT
+ .irq = STM32_IRQ_TIM11,
+#endif
+ .timtype = TIMTYPE_TIM11,
+ .base = STM32_TIM11_BASE,
+ .pincfg = PWM_TIM11_PINCFG,
+ .pclk = STM32_APB2_TIM11_CLKIN,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM12_PWM
+static struct stm32_pwmtimer_s g_pwm12dev =
+{
+ .ops = &g_pwmops,
+ .timid = 12,
+ .channel = CONFIG_STM32_TIM12_CHANNEL,
+ .timtype = TIMTYPE_TIM12,
+#ifdef CONFIG_PWM_PULSECOUNT
+ .irq = STM32_IRQ_TIM12,
+#endif
+ .base = STM32_TIM12_BASE,
+ .pincfg = PWM_TIM12_PINCFG,
+ .pclk = STM32_APB1_TIM12_CLKIN,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM13_PWM
+static struct stm32_pwmtimer_s g_pwm13dev =
+{
+ .ops = &g_pwmops,
+ .timid = 13,
+ .channel = CONFIG_STM32_TIM13_CHANNEL,
+ .timtype = TIMTYPE_TIM13,
+#ifdef CONFIG_PWM_PULSECOUNT
+ .irq = STM32_IRQ_TIM13,
+#endif
+ .base = STM32_TIM13_BASE,
+ .pincfg = PWM_TIM13_PINCFG,
+ .pclk = STM32_APB1_TIM13_CLKIN,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM14_PWM
+static struct stm32_pwmtimer_s g_pwm14dev =
+{
+ .ops = &g_pwmops,
+ .timid = 14,
+ .channel = CONFIG_STM32_TIM14_CHANNEL,
+ .timtype = TIMTYPE_TIM14,
+#ifdef CONFIG_PWM_PULSECOUNT
+ .irq = STM32_IRQ_TIM14,
+#endif
+ .base = STM32_TIM14_BASE,
+ .pincfg = PWM_TIM14_PINCFG,
+ .pclk = STM32_APB1_TIM14_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)
+{
+ 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)
+{
+ /* 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;
+ uint16_t ccmr1;
+ uint16_t ccmr2;
+
+ /* New timer regiser bit settings */
+
+ uint16_t ccenable;
+ uint16_t ocmode1;
+ uint16_t ocmode2;
+
+ DEBUGASSERT(priv != NULL && info != NULL);
+
+#ifdef 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 && info->duty > 0 &&
+ info->duty < uitoub16(100));
+
+ /* 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 = 7,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;
+ }
+
+ /* Duty cycle:
+ *
+ * duty cycle = ccr / reload (fractional value)
+ */
+
+ ccr = b16toi(info->duty * reload + b16HALF);
+
+ pwmvdbg("TIM%d PCLK: %d frequency: %d TIMCLK: %d prescaler: %d reload: %d ccr: %d\n",
+ priv->timid, priv->pclk, info->frequency, timclk, prescaler, reload, ccr);
+
+ /* 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
+ */
+
+ 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-14), 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 == count up:
+ *
+ * GTIM_CR1_EDGE: The counter counts up or down depending on the
+ * direction bit(DIR).
+ * GTIM_CR1_DIR: 0: count up, 1: count down
+ */
+
+ cr1 &= ~(GTIM_CR1_DIR | GTIM_CR1_CMS_MASK);
+ cr1 |= GTIM_CR1_EDGE;
+ }
+#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 repitition 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 remining 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
+ * repition 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 repitition counter */
+
+ else
+#endif
+ {
+ /* Set the repeition 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 */
+
+ ocmode1 = 0;
+ ocmode2 = 0;
+ switch (priv->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) |
+ (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) |
+ ATIM_CCMR1_OC1PE;
+
+ /* 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) |
+ (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC2M_SHIFT) |
+ ATIM_CCMR1_OC2PE;
+
+ /* 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: Channel3 */
+ {
+ /* 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) |
+ (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR2_OC3M_SHIFT) |
+ ATIM_CCMR2_OC3PE;
+
+ /* 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: /* PWM1 Mode configuration: Channel4 */
+ {
+ /* 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) |
+ (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR2_OC4M_SHIFT) |
+ ATIM_CCMR2_OC4PE;
+
+ /* 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", priv->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);
+ 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;
+
+ /* 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_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_STM32F40XX)
+ else
+#endif
+#endif
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+ {
+ ccer &= ~(GTIM_CCER_CC1NP | GTIM_CCER_CC2NP | GTIM_CCER_CC3NP | GTIM_CCER_CC4NP);
+ }
+#endif
+
+ /* Save the modified register values */
+
+ pwm_putreg(priv, STM32_GTIM_CR2_OFFSET, cr2);
+ pwm_putreg(priv, STM32_GTIM_CCMR1_OFFSET, ccmr1);
+ pwm_putreg(priv, STM32_GTIM_CCMR2_OFFSET, ccmr2);
+ 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 repetitioncount 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_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)
+{
+ FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev;
+
+ pwmvdbg("TIM%d pincfg: %08x\n", priv->timid, priv->pincfg);
+ pwm_dumpregs(priv, "Initially");
+
+ /* Configure the PWM output pin, but do not start the timer yet */
+
+ stm32_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 stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev;
+ uint32_t pincfg;
+
+ pwmvdbg("TIM%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);
+
+#if defined(CONFIG_STM32_STM32F10XX)
+ pincfg |= (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT);
+#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+ 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 = irqsave();
+
+ /* 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
+ }
+
+ /* 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);
+ irqrestore(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,..,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 *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
+
+ default:
+ pwmdbg("No such timer configured\n");
+ return NULL;
+ }
+
+ return (FAR struct pwm_lowerhalf_s *)lower;
+}
+
+#endif /* CONFIG_STM32_TIMn_PWM, n = 1,...,14 */
diff --git a/nuttx/arch/arm/src/stm32/stm32_pwm.h b/nuttx/arch/arm/src/stm32/stm32_pwm.h
new file mode 100644
index 000000000..c51c56950
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_pwm.h
@@ -0,0 +1,370 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_pwm.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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
+
+/* 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)
+
+#include <arch/board/board.h>
+#include "chip/stm32_tim.h"
+
+/* 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 PWM_TIM1_PINCFG GPIO_TIM1_CH1OUT
+# elif CONFIG_STM32_TIM1_CHANNEL == 2
+# define PWM_TIM1_PINCFG GPIO_TIM1_CH2OUT
+# elif CONFIG_STM32_TIM1_CHANNEL == 3
+# define PWM_TIM1_PINCFG GPIO_TIM1_CH3OUT
+# elif CONFIG_STM32_TIM1_CHANNEL == 4
+# define PWM_TIM1_PINCFG 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 PWM_TIM2_PINCFG GPIO_TIM2_CH1OUT
+# elif CONFIG_STM32_TIM2_CHANNEL == 2
+# define PWM_TIM2_PINCFG GPIO_TIM2_CH2OUT
+# elif CONFIG_STM32_TIM2_CHANNEL == 3
+# define PWM_TIM2_PINCFG GPIO_TIM2_CH3OUT
+# elif CONFIG_STM32_TIM2_CHANNEL == 4
+# define PWM_TIM2_PINCFG 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 PWM_TIM3_PINCFG GPIO_TIM3_CH1OUT
+# elif CONFIG_STM32_TIM3_CHANNEL == 2
+# define PWM_TIM3_PINCFG GPIO_TIM3_CH2OUT
+# elif CONFIG_STM32_TIM3_CHANNEL == 3
+# define PWM_TIM3_PINCFG GPIO_TIM3_CH3OUT
+# elif CONFIG_STM32_TIM3_CHANNEL == 4
+# define PWM_TIM3_PINCFG 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 PWM_TIM4_PINCFG GPIO_TIM4_CH1OUT
+# elif CONFIG_STM32_TIM4_CHANNEL == 2
+# define PWM_TIM4_PINCFG GPIO_TIM4_CH2OUT
+# elif CONFIG_STM32_TIM4_CHANNEL == 3
+# define PWM_TIM4_PINCFG GPIO_TIM4_CH3OUT
+# elif CONFIG_STM32_TIM4_CHANNEL == 4
+# define PWM_TIM4_PINCFG 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 PWM_TIM5_PINCFG GPIO_TIM5_CH1OUT
+# elif CONFIG_STM32_TIM5_CHANNEL == 2
+# define PWM_TIM5_PINCFG GPIO_TIM5_CH2OUT
+# elif CONFIG_STM32_TIM5_CHANNEL == 3
+# define PWM_TIM5_PINCFG GPIO_TIM5_CH3OUT
+# elif CONFIG_STM32_TIM5_CHANNEL == 4
+# define PWM_TIM5_PINCFG 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 PWM_TIM8_PINCFG GPIO_TIM8_CH1OUT
+# elif CONFIG_STM32_TIM8_CHANNEL == 2
+# define PWM_TIM8_PINCFG GPIO_TIM8_CH2OUT
+# elif CONFIG_STM32_TIM8_CHANNEL == 3
+# define PWM_TIM8_PINCFG GPIO_TIM8_CH3OUT
+# elif CONFIG_STM32_TIM8_CHANNEL == 4
+# define PWM_TIM8_PINCFG 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 PWM_TIM9_PINCFG GPIO_TIM9_CH1OUT
+# elif CONFIG_STM32_TIM9_CHANNEL == 2
+# define PWM_TIM9_PINCFG GPIO_TIM9_CH2OUT
+# elif CONFIG_STM32_TIM9_CHANNEL == 3
+# define PWM_TIM9_PINCFG GPIO_TIM9_CH3OUT
+# elif CONFIG_STM32_TIM9_CHANNEL == 4
+# define PWM_TIM9_PINCFG 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 PWM_TIM10_PINCFG GPIO_TIM10_CH1OUT
+# elif CONFIG_STM32_TIM10_CHANNEL == 2
+# define PWM_TIM10_PINCFG GPIO_TIM10_CH2OUT
+# elif CONFIG_STM32_TIM10_CHANNEL == 3
+# define PWM_TIM10_PINCFG GPIO_TIM10_CH3OUT
+# elif CONFIG_STM32_TIM10_CHANNEL == 4
+# define PWM_TIM10_PINCFG 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 PWM_TIM11_PINCFG GPIO_TIM11_CH1OUT
+# elif CONFIG_STM32_TIM11_CHANNEL == 2
+# define PWM_TIM11_PINCFG GPIO_TIM11_CH2OUT
+# elif CONFIG_STM32_TIM11_CHANNEL == 3
+# define PWM_TIM11_PINCFG GPIO_TIM11_CH3OUT
+# elif CONFIG_STM32_TIM11_CHANNEL == 4
+# define PWM_TIM11_PINCFG 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 PWM_TIM12_PINCFG GPIO_TIM12_CH1OUT
+# elif CONFIG_STM32_TIM12_CHANNEL == 2
+# define PWM_TIM12_PINCFG GPIO_TIM12_CH2OUT
+# elif CONFIG_STM32_TIM12_CHANNEL == 3
+# define PWM_TIM12_PINCFG GPIO_TIM12_CH3OUT
+# elif CONFIG_STM32_TIM12_CHANNEL == 4
+# define PWM_TIM12_PINCFG 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 PWM_TIM13_PINCFG GPIO_TIM13_CH1OUT
+# elif CONFIG_STM32_TIM13_CHANNEL == 2
+# define PWM_TIM13_PINCFG GPIO_TIM13_CH2OUT
+# elif CONFIG_STM32_TIM13_CHANNEL == 3
+# define PWM_TIM13_PINCFG GPIO_TIM13_CH3OUT
+# elif CONFIG_STM32_TIM13_CHANNEL == 4
+# define PWM_TIM13_PINCFG 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 PWM_TIM14_PINCFG GPIO_TIM14_CH1OUT
+# elif CONFIG_STM32_TIM14_CHANNEL == 2
+# define PWM_TIM14_PINCFG GPIO_TIM14_CH2OUT
+# elif CONFIG_STM32_TIM14_CHANNEL == 3
+# define PWM_TIM14_PINCFG GPIO_TIM14_CH3OUT
+# elif CONFIG_STM32_TIM14_CHANNEL == 4
+# define PWM_TIM14_PINCFG GPIO_TIM14_CH4OUT
+# else
+# error "Unsupported value of CONFIG_STM32_TIM14_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: 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,..,14}.
+ *
+ * Returned Value:
+ * On success, a pointer to the STM32 lower half PWM driver is returned.
+ * NULL is returned on any failure.
+ *
+ ************************************************************************************/
+
+EXTERN 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/nuttx/arch/arm/src/stm32/stm32_pwr.c b/nuttx/arch/arm/src/stm32/stm32_pwr.c
new file mode 100644
index 000000000..14149922f
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_pwr.c
@@ -0,0 +1,98 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_pwr.c
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Author: Uros Platise <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <nuttx/arch.h>
+
+#include <stdint.h>
+#include <errno.h>
+
+#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 getreg32(STM32_PWR_BASE + offset);
+}
+
+static inline void stm32_pwr_putreg(uint8_t offset, uint16_t value)
+{
+ putreg32(value, STM32_PWR_BASE + offset);
+}
+
+static inline void stm32_pwr_modifyreg(uint8_t offset, uint16_t clearbits, uint16_t setbits)
+{
+ modifyreg32(STM32_PWR_BASE + offset, clearbits, 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:
+ * None
+ *
+ * Returned Values:
+ * None
+ *
+ ************************************************************************************/
+
+void stm32_pwr_enablebkp(void)
+{
+ stm32_pwr_modifyreg(STM32_PWR_CR_OFFSET, 0, PWR_CR_DBP);
+}
+
+#endif /* CONFIG_STM32_PWR */
diff --git a/nuttx/arch/arm/src/stm32/stm32_pwr.h b/nuttx/arch/arm/src/stm32/stm32_pwr.h
new file mode 100644
index 000000000..7a2751677
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_pwr.h
@@ -0,0 +1,89 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_pwr.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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:
+ * None
+ *
+ * Returned Values:
+ * None
+ *
+ ************************************************************************************/
+
+EXTERN void stm32_pwr_enablebkp(void);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32_STM32_PWR_H */
diff --git a/nuttx/arch/arm/src/stm32/stm32_qencoder.c b/nuttx/arch/arm/src/stm32/stm32_qencoder.c
new file mode 100644
index 000000000..8553296f9
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_qencoder.c
@@ -0,0 +1,1228 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_qencoder.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt <gnutt@nuttx.org>
+ * Diego Sanchez <dsanchez@nx-engineering.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 <nuttx/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "stm32_internal.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 ***************************************************************************/
+/* On the F1 series, all timers are 16-bit. */
+
+#undef HAVE_32BIT_TIMERS
+#undef HAVE_16BIT_TIMERS
+
+#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 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
+
+/* Debug ****************************************************************************/
+/* Non-standard debug that may be enabled just for testing the quadrature encoder */
+
+#ifndef CONFIG_DEBUG
+# undef CONFIG_DEBUG_QENCODER
+#endif
+
+#ifdef CONFIG_DEBUG_QENCODER
+# define qedbg dbg
+# define qelldbg lldbg
+# ifdef CONFIG_DEBUG_VERBOSE
+# define qevdbg vdbg
+# define qellvdbg llvdbg
+# define qe_dumpgpio(p,m) stm32_dumpgpio(p,m)
+# else
+# define qevdbg(x...)
+# define qellvdbg(x...)
+# define qe_dumpgpio(p,m)
+# endif
+#else
+# define qedbg(x...)
+# define qelldbg(x...)
+# define qevdbg(x...)
+# define qellvdbg(x...)
+# 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
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+ uint32_t ti1cfg; /* TI1 input pin configuration (20-bit encoding) */
+ uint32_t ti2cfg; /* TI2 input pin configuration (20-bit encoding) */
+#else
+ uint16_t ti1cfg; /* TI1 input pin configuration (16-bit encoding) */
+ uint16_t ti2cfg; /* TI2 input pin configuration (16-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(struct stm32_lowerhalf_s *priv, int offset);
+static void stm32_putreg16(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_QENCODER) && defined(CONFIG_DEBUG_VERBOSE)
+static void stm32_dumpregs(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, 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(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_QENCODER) && defined(CONFIG_DEBUG_VERBOSE)
+static void stm32_dumpregs(struct stm32_lowerhalf_s *priv, FAR const char *msg)
+{
+ qevdbg("%s:\n", msg);
+ qevdbg(" 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));
+ qevdbg(" 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));
+ qevdbg(" 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));
+ qevdbg(" 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_QENCODER) || defined(CONFIG_STM32_TIM8_QENCODER)
+ if (priv->timtype == TIMTYPE_ADVANCED)
+ {
+ qevdbg(" 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
+ {
+ qevdbg(" 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:
+#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_putreg32(priv, STM32_GTIM_ARR_OFFSET, 0xffff);
+ }
+#elif defined(HAVE_32BIT_TIMERS)
+ stm32_putreg32(priv, STM32_GTIM_ARR_OFFSET, 0xffffffff);
+#else
+ stm32_putreg32(priv, STM32_GTIM_ARR_OFFSET, 0xffff);
+#endif
+
+ /* Set the timerp rescaler 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 immediatly
+ */
+
+ 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 |= GTIM_CCMR_ICF_FDTSd46 << 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 |= GTIM_CCMR_ICF_FDTSd46 << 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 = irqsave();
+ 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_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
+ 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);
+ irqrestore(flags);
+
+ qevdbg("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);
+
+#if defined(CONFIG_STM32_STM32F10XX)
+ pincfg |= (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT);
+#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+ pincfg |= (GPIO_INPUT|GPIO_FLOAT);
+#else
+# error "Unrecognized STM32 chip"
+#endif
+
+ stm32_configgpio(pincfg);
+
+ /* Put the TI2 GPIO pin back to its default state */
+
+ pincfg = priv->config->ti2cfg & (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_STM32F40XX)
+ pincfg |= (GPIO_INPUT|GPIO_FLOAT);
+#else
+# error "Unrecognized STM32 chip"
+#endif
+
+ stm32_configgpio(pincfg);
+ return -ENOSYS;
+}
+
+/************************************************************************************
+ * Name: stm32_position
+ *
+ * Description:
+ * Return the current position measurement.
+ *
+ ************************************************************************************/
+
+static int stm32_position(FAR struct qe_lowerhalf_s *lower, 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;
+
+ qevdbg("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 = irqsave();
+ stm32_putreg32(priv, STM32_GTIM_CNT_OFFSET, 0);
+ priv->position = 0;
+ irqrestore(flags);
+#else
+ qevdbg("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)
+ {
+ qedbg("TIM%d support not configured\n", tim);
+ return -ENXIO;
+ }
+
+ /* Make sure that it is available */
+
+ if (priv->inuse)
+ {
+ qedbg("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)
+ {
+ qedbg("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/nuttx/arch/arm/src/stm32/stm32_qencoder.h b/nuttx/arch/arm/src/stm32/stm32_qencoder.h
new file mode 100644
index 000000000..5effa7163
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/stm32/stm32_rcc.c b/nuttx/arch/arm/src/stm32/stm32_rcc.c
new file mode 100644
index 000000000..6656186f2
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_rcc.c
@@ -0,0 +1,183 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_rcc.c
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "stm32_rcc.h"
+#include "stm32_flash.h"
+#include "stm32_internal.h"
+#include "stm32_waste.h"
+
+/****************************************************************************
+ * 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_STM32F10XX)
+# include "chip/stm32f10xxx_rcc.c"
+#elif defined(CONFIG_STM32_STM32F20XX)
+# include "chip/stm32f20xxx_rcc.c"
+#elif defined(CONFIG_STM32_STM32F40XX)
+# include "chip/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/nuttx/arch/arm/src/stm32/stm32_rcc.h b/nuttx/arch/arm/src/stm32/stm32_rcc.h
new file mode 100644
index 000000000..292eade73
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_rcc.h
@@ -0,0 +1,272 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_rcc.h
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.orgr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "up_arch.h"
+#include "chip.h"
+
+#if defined(CONFIG_STM32_STM32F10XX)
+# include "chip/stm32f10xxx_rcc.h"
+#elif defined(CONFIG_STM32_STM32F20XX)
+# include "chip/stm32f20xxx_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 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 stm32_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/stm32f40xxx_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/stm32f40xxx_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_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/stm32f40xxx_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/stm32f40xxx_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
+ *
+ ************************************************************************************/
+
+EXTERN void stm32_clockconfig(void);
+
+/************************************************************************************
+ * 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
+EXTERN 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.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ************************************************************************************/
+
+EXTERN void stm32_rcc_enablelse(void);
+
+/****************************************************************************
+ * Name: stm32_rcc_enablelsi
+ *
+ * Description:
+ * Enable the Internal Low-Speed (LSI) RC Oscillator.
+ *
+ ****************************************************************************/
+
+EXTERN void stm32_rcc_enablelsi(void);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32_STM32_RRC_H */
diff --git a/nuttx/arch/arm/src/stm32/stm32_rtc.c b/nuttx/arch/arm/src/stm32/stm32_rtc.c
new file mode 100644
index 000000000..b79a74dcb
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_rtc.c
@@ -0,0 +1,80 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_rtc.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#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 F4 RTC differs dramatically the F1 RTC. The F1 RTC is a simple
+ * battery-backed counter; the F4 RTC is provides broken-out data/time in BCD
+ * format.
+ */
+
+#if defined(CONFIG_STM32_STM32F10XX)
+# include "stm32f10xxx_rtc.c"
+#elif defined(CONFIG_STM32_STM32F20XX)
+# include "stm32f20xxx_rtc.c"
+#elif defined(CONFIG_STM32_STM32F40XX)
+# include "stm32f40xxx_rtc.c"
+#endif
diff --git a/nuttx/arch/arm/src/stm32/stm32_rtc.h b/nuttx/arch/arm/src/stm32/stm32_rtc.h
new file mode 100644
index 000000000..11822f76c
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_rtc.h
@@ -0,0 +1,85 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_rtc.h
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Author: Uros Platise <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 <nuttx/config.h>
+
+#include "chip.h"
+#if defined(CONFIG_STM32_STM32F10XX)
+# include "chip/stm32f10xxx_rtc.h"
+# include "chip/stm32_bkp.h"
+#elif defined(CONFIG_STM32_STM32F20XX)
+# include "chip/stm32f20xxx_rtc.h"
+#elif defined(CONFIG_STM32_STM32F40XX)
+# include "chip/stm32f40xxx_rtc.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 */
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/* Set alarm output pin */
+
+EXTERN void stm32_rtc_settalarmpin(bool activate);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32_STM32_RTC_H */
diff --git a/nuttx/arch/arm/src/stm32/stm32_sdio.c b/nuttx/arch/arm/src/stm32/stm32_sdio.c
new file mode 100644
index 000000000..a8bcae307
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_sdio.c
@@ -0,0 +1,2844 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_sdio.c
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+#include <wdog.h>
+#include <errno.h>
+
+#include <nuttx/clock.h>
+#include <nuttx/arch.h>
+#include <nuttx/sdio.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/mmcsd.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+
+#include "stm32_internal.h"
+#include "stm32_dma.h"
+#include "stm32_sdio.h"
+
+#if 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 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)
+#define SDIO_RESPDONE_ICR (SDIO_ICR_CTIMEOUTC|SDIO_ICR_CCRCFAILC|\
+ SDIO_ICR_CMDRENDC)
+#define SDIO_XFRDONE_ICR (SDIO_ICR_DATAENDC|SDIO_ICR_DCRCFAILC|\
+ SDIO_ICR_DTIMEOUTC|SDIO_ICR_RXOVERRC|\
+ SDIO_ICR_TXUNDERRC|SDIO_ICR_STBITERRC)
+
+#define SDIO_WAITALL_ICR (SDIO_CMDDONE_ICR|SDIO_RESPDONE_ICR|\
+ SDIO_XFRDONE_ICR)
+
+/* 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);
+
+/* 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);
+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,
+ .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,
+ .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;
+
+ /* Save all of the data and set the new interrupt mask in one, atomic
+ * operation.
+ */
+
+ flags = irqsave();
+ 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);
+ irqrestore(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 = irqsave();
+ priv->xfrmask = xfrmask;
+ putreg32(priv->xfrmask | priv->waitmask, STM32_SDIO_MASK);
+ irqrestore(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 the the SDIO is power 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, &regs->dma);
+ }
+#endif
+ stm32_sdiosample(&regs->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, &regs->dma, msg);
+ }
+#endif
+ stm32_sdiodump(&regs->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 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 < 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 < 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);
+ }
+}
+
+/****************************************************************************
+ * Interrrupt Handling
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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 = irqsave();
+ 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);
+ irqrestore(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);
+
+ /* Set the interrrupt priority */
+
+ up_prioritize_irq(STM32_IRQ_SDIO, CONFIG_SDIO_PRI);
+ }
+
+ 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 interrrupts */
+
+ 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.
+ */
+
+ 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 = irqsave();
+ 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 = (timeout + (MSEC_PER_TICK-1)) / MSEC_PER_TICK;
+ 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);
+ }
+ }
+
+ /* 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:
+ irqrestore(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_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;
+ int ret = -EINVAL;
+
+ DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
+ DEBUGASSERT(((uint32_t)buffer & 3) == 0);
+
+ /* Reset the DPSM configuration */
+
+ stm32_datadisable();
+
+ /* Wide bus operation is required for DMA */
+
+ if (priv->widebus)
+ {
+ 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);
+ ret = OK;
+ }
+
+ return ret;
+}
+#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;
+ int ret = -EINVAL;
+
+ DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
+ DEBUGASSERT(((uint32_t)buffer & 3) == 0);
+
+ /* Reset the DPSM configuration */
+
+ stm32_datadisable();
+
+ /* Wide bus operation is required for DMA */
+
+ if (priv->widebus)
+ {
+ 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 interrrupts */
+
+ stm32_configxfrints(priv, SDIO_DMASEND_MASK);
+
+ ret = OK;
+ }
+
+ return ret;
+}
+#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 = irqsave();
+ 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)
+ {
+ stm32_callback(priv);
+ }
+ irqrestore(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 stm32_dev_s *priv = (struct stm32_dev_s *)dev;
+ irqstate_t flags;
+
+ /* Update card status */
+
+ flags = irqsave();
+ if (wrprotect)
+ {
+ priv->cdstatus |= SDIO_STATUS_WRPROTECTED;
+ }
+ else
+ {
+ priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED;
+ }
+ fvdbg("cdstatus: %02x\n", priv->cdstatus);
+ irqrestore(flags);
+}
+#endif /* CONFIG_STM32_SDIO */
diff --git a/nuttx/arch/arm/src/stm32/stm32_sdio.h b/nuttx/arch/arm/src/stm32/stm32_sdio.h
new file mode 100644
index 000000000..ceeb56f0d
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_sdio.h
@@ -0,0 +1,127 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_sdio.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <sys/types.h>
+#include <stdbool.h>
+
+#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 */
+EXTERN 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
+ *
+ ****************************************************************************/
+
+EXTERN 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
+ *
+ ****************************************************************************/
+
+EXTERN 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/nuttx/arch/arm/src/stm32/stm32_serial.c b/nuttx/arch/arm/src/stm32/stm32_serial.c
new file mode 100644
index 000000000..45d685823
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_serial.c
@@ -0,0 +1,1991 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_serial.c
+ *
+ * Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <nuttx/power/pm.h>
+
+#ifdef CONFIG_SERIAL_TERMIOS
+# include <termios.h>
+#endif
+
+#include <arch/serial.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "stm32_uart.h"
+#include "stm32_dma.h"
+#include "up_arch.h"
+#include "up_internal.h"
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+/* Some sanity checks *******************************************************/
+/* DMA configuration */
+
+/* If DMA is enabled on any USART, then very that other pre-requisites
+ * have also been selected.
+ */
+
+#if SERIAL_HAVE_DMA
+
+/* Verify that DMA has been enabled an the DMA channel has been defined.
+ * NOTE: These assignments may only be true for the F4.
+ */
+
+# 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)
+# ifndef CONFIG_STM32_DMA1
+# error STM32 USART2/3/4/5 receive DMA requires CONFIG_STM32_DMA1
+# endif
+# 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
+
+/* The DMA buffer size when using RX DMA to emulate a FIFO.
+ *
+ * When streaming data, the generic serial layer will be called
+ * everytime the FIFO receives half this number of bytes.
+ */
+
+# define RXDMA_BUFFER_SIZE 32
+
+/* DMA priority */
+
+# ifndef CONFIG_USART_DMAPRIO
+# if defined(CONFIG_STM32_STM32F10XX)
+# 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_STM32F10XX)
+# 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
+
+#endif
+
+/* Power management definitions */
+
+#if defined(CONFIG_PM) && !defined(CONFIG_PM_SERIAL_ACTIVITY)
+# define CONFIG_PM_SERIAL_ACTIVITY 10
+#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 */
+ 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 */
+ 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 */
+ const uint32_t rts_gpio; /* U[S]ART RTS GPIO pin configuration */
+ const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */
+
+#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
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void up_setspeed(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, uint32_t *status);
+static void up_rxint(struct uart_dev_s *dev, bool enable);
+static bool up_rxavailable(struct uart_dev_s *dev);
+#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, uint32_t *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, enum pm_state_e pmstate);
+static int up_pm_prepare(struct pm_callback_s *cb, 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
+
+/****************************************************************************
+ * 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,
+ .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,
+ .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
+
+/* 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,
+#ifdef GPIO_USART1_CTS
+ .cts_gpio = GPIO_USART1_CTS,
+#endif
+#ifdef GPIO_USART1_RTS
+ .rts_gpio = GPIO_USART1_RTS,
+#endif
+#ifdef CONFIG_USART1_RXDMA
+ .rxdma_channel = DMAMAP_USART1_RX,
+ .rxfifo = g_usart1rxfifo,
+#endif
+ .vector = up_interrupt_usart1,
+};
+#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,
+#ifdef GPIO_USART2_CTS
+ .cts_gpio = GPIO_USART2_CTS,
+#endif
+#ifdef GPIO_USART2_RTS
+ .rts_gpio = GPIO_USART2_RTS,
+#endif
+#ifdef CONFIG_USART2_RXDMA
+ .rxdma_channel = DMAMAP_USART2_RX,
+ .rxfifo = g_usart2rxfifo,
+#endif
+ .vector = up_interrupt_usart2,
+};
+#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,
+#ifdef GPIO_USART3_CTS
+ .cts_gpio = GPIO_USART3_CTS,
+#endif
+#ifdef GPIO_USART3_RTS
+ .rts_gpio = GPIO_USART3_RTS,
+#endif
+#ifdef CONFIG_USART3_RXDMA
+ .rxdma_channel = DMAMAP_USART3_RX,
+ .rxfifo = g_usart3rxfifo,
+#endif
+ .vector = up_interrupt_usart3,
+};
+#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,
+ .baud = CONFIG_UART4_BAUD,
+ .apbclock = STM32_PCLK1_FREQUENCY,
+ .usartbase = STM32_UART4_BASE,
+ .tx_gpio = GPIO_UART4_TX,
+ .rx_gpio = GPIO_UART4_RX,
+#ifdef GPIO_UART4_CTS
+ .cts_gpio = GPIO_UART4_CTS,
+#endif
+#ifdef GPIO_UART4_RTS
+ .rts_gpio = GPIO_UART4_RTS,
+#endif
+#ifdef CONFIG_UART4_RXDMA
+ .rxdma_channel = DMAMAP_UART4_RX,
+ .rxfifo = g_uart4rxfifo,
+#endif
+ .vector = up_interrupt_uart4,
+};
+#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,
+ .baud = CONFIG_UART5_BAUD,
+ .apbclock = STM32_PCLK1_FREQUENCY,
+ .usartbase = STM32_UART5_BASE,
+ .tx_gpio = GPIO_UART5_TX,
+ .rx_gpio = GPIO_UART5_RX,
+#ifdef GPIO_UART5_CTS
+ .cts_gpio = GPIO_UART5_CTS,
+#endif
+#ifdef GPIO_UART5_RTS
+ .rts_gpio = GPIO_UART5_RTS,
+#endif
+#ifdef CONFIG_UART5_RXDMA
+ .rxdma_channel = DMAMAP_UART5_RX,
+ .rxfifo = g_uart5rxfifo,
+#endif
+ .vector = up_interrupt_uart5,
+};
+#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,
+#ifdef GPIO_USART6_CTS
+ .cts_gpio = GPIO_USART6_CTS,
+#endif
+#ifdef GPIO_USART6_RTS
+ .rts_gpio = GPIO_USART6_RTS,
+#endif
+#ifdef CONFIG_USART6_RXDMA
+ .rxdma_channel = DMAMAP_USART6_RX,
+ .rxfifo = g_usart6rxfifo,
+#endif
+ .vector = up_interrupt_usart6,
+};
+#endif
+
+/* This table lets us iterate over the configured USARTs */
+
+static struct up_dev_s *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_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_RXNEIE|USART_CR1_TXEIE|USART_CR1_PEIE);
+ cr |= (ie & (USART_CR1_RXNEIE|USART_CR1_TXEIE|USART_CR1_PEIE));
+ 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 Bit Status Meaning Usage
+ * ------------------ --- --------------- ------------------------------ ----------
+ * USART_CR1_IDLEIE 4 USART_SR_IDLE Idle Line Detected (not used)
+ * USART_CR1_RXNEIE 5 USART_SR_RXNE Received Data Ready to be Read
+ * " " USART_SR_ORE Overrun Error Detected
+ * USART_CR1_TCIE 6 USART_SR_TC Transmission Complete (not used)
+ * USART_CR1_TXEIE 7 USART_SR_TXE Transmit Data Register Empty
+ * USART_CR1_PEIE 8 USART_SR_PE Parity Error
+ *
+ * USART_CR2_LBDIE 6 USART_SR_LBD Break Flag (not used)
+ * USART_CR3_EIE 0 USART_SR_FE Framing Error
+ * " " USART_SR_NE Noise Error
+ * " " USART_SR_ORE Overrun Error Detected
+ * USART_CR3_CTSIE 10 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_RXNEIE|USART_CR1_TXEIE|USART_CR1_PEIE)) | (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_setspeed
+ *
+ * Description:
+ * Set the serial line speed.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SUPPRESS_UART_CONFIG
+static void up_setspeed(struct uart_dev_s *dev)
+{
+ struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+ 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
+
+/****************************************************************************
+ * 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().
+ */
+
+ /* Configure pins for USART use */
+
+ stm32_configgpio(priv->tx_gpio);
+ stm32_configgpio(priv->rx_gpio);
+
+ if (priv->cts_gpio != 0)
+ {
+ stm32_configgpio(priv->cts_gpio);
+ }
+
+ if (priv->rts_gpio != 0)
+ {
+ stm32_configgpio(priv->rts_gpio);
+ }
+
+ /* 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 M, PCE, PS, TE, REm and all interrupt enable bits */
+
+ regval = up_serialin(priv, STM32_USART_CR1_OFFSET);
+ regval &= ~(USART_CR1_M|USART_CR1_PCE|USART_CR1_PS|USART_CR1_TE|
+ USART_CR1_RE|USART_CR1_ALLINTS);
+
+ /* Configure word length and parity mode */
+
+ if (priv->bits == 9) /* Default: 1 start, 8 data, n stop */
+ {
+ regval |= USART_CR1_M; /* 1 start, 9 data, n stop */
+ }
+
+ if (priv->parity == 1) /* Odd parity */
+ {
+ regval |= (USART_CR1_PCE|USART_CR1_PS);
+ }
+ else if (priv->parity == 2) /* Even parity */
+ {
+ regval |= USART_CR1_PCE;
+ }
+
+ 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);
+
+ /* Configure hardware flow control -- Not yet supported */
+
+ up_serialout(priv, STM32_USART_CR3_OFFSET, regval);
+
+ /* Configure the USART Baud Rate. */
+
+ up_setspeed(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
+
+ /* 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 */
+
+ result = up_setup(dev);
+ if (result != OK)
+ {
+ return result;
+ }
+
+ /* Acquire the DMA channel. This should always succeed. */
+
+ priv->rxdma = stm32_dmachannel(priv->rxdma_channel);
+
+ /* Configure for circular DMA reception into the RX fifo */
+
+ stm32_dmasetup(priv->rxdma,
+ priv->usartbase + STM32_USART_DR_OFFSET,
+ (uint32_t)priv->rxfifo,
+ RXDMA_BUFFER_SIZE,
+ 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);
+
+ /* 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);
+
+ /* 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 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);
+}
+
+/****************************************************************************
+ * 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
+ * approprite 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(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 Bit Status Meaning Usage
+ * ------------------ --- --------------- ------------------------------- ----------
+ * USART_CR1_IDLEIE 4 USART_SR_IDLE Idle Line Detected (not used)
+ * USART_CR1_RXNEIE 5 USART_SR_RXNE Received Data Ready to be Read
+ * " " USART_SR_ORE Overrun Error Detected
+ * USART_CR1_TCIE 6 USART_SR_TC Transmission Complete (not used)
+ * USART_CR1_TXEIE 7 USART_SR_TXE Transmit Data Register Empty
+ * USART_CR1_PEIE 8 USART_SR_PE Parity Error
+ *
+ * USART_CR2_LBDIE 6 USART_SR_LBD Break Flag (not used)
+ * USART_CR3_EIE 0 USART_SR_FE Framing Error
+ * " " USART_SR_NE Noise Error
+ * " " USART_SR_ORE Overrun Error Detected
+ * USART_CR3_CTSIE 10 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.
+ */
+
+ /* 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 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_DR_OFFSET);
+ }
+
+ /* Handle outgoing, transmit bytes */
+
+ if ((priv->sr & USART_SR_TXE) != 0 && (priv->ie & USART_CR1_TXEIE) != 0)
+ {
+ /* Transmit data regiser 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)
+{
+ struct inode *inode = filep->f_inode;
+ struct uart_dev_s *dev = inode->i_private;
+#ifdef CONFIG_SERIAL_TERMIOS
+ struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+#endif
+ int ret = OK;
+
+ switch (cmd)
+ {
+ 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;
+
+#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);
+ up_setspeed(dev);
+ }
+ break;
+#endif
+
+#ifdef CONFIG_USART_BREAKS
+ case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
+ {
+ irqstate_t flags = irqsave();
+ uint32_t cr2 = up_serialin(priv, STM32_USART_CR2_OFFSET);
+ up_serialout(priv, STM32_USART_CR2_OFFSET, cr2 | USART_CR2_LINEN);
+ irqrestore(flags);
+ }
+ break;
+
+ case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
+ {
+ irqstate_t flags;
+ flags = irqsave();
+ uint32_t cr1 = up_serialin(priv, STM32_USART_CR2_OFFSET);
+ up_serialout(priv, STM32_USART_CR2_OFFSET, cr2 & ~USART_CR2_LINEN);
+ irqrestore(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, uint32_t *status)
+{
+ struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+ uint32_t dr;
+
+ /* Get the Rx byte */
+
+ dr = up_serialin(priv, STM32_USART_DR_OFFSET);
+
+ /* Get the Rx byte plux error information. Return those in status */
+
+ *status = priv->sr << 16 | dr;
+ priv->sr = 0;
+
+ /* Then return the actual received byte */
+
+ return dr & 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 Bit Status Meaning Usage
+ * ------------------ --- --------------- ------------------------------- ----------
+ * USART_CR1_IDLEIE 4 USART_SR_IDLE Idle Line Detected (not used)
+ * USART_CR1_RXNEIE 5 USART_SR_RXNE Received Data Ready to be Read
+ * " " USART_SR_ORE Overrun Error Detected
+ * USART_CR1_PEIE 8 USART_SR_PE Parity Error
+ *
+ * USART_CR2_LBDIE 6 USART_SR_LBD Break Flag (not used)
+ * USART_CR3_EIE 0 USART_SR_FE Framing Error
+ * " " USART_SR_NE Noise Error
+ * " " USART_SR_ORE Overrun Error Detected
+ */
+
+ flags = irqsave();
+ 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);
+ irqrestore(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_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, uint32_t *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)
+ {
+ priv->rxdmanext = 0;
+ }
+ }
+
+ return c;
+}
+#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;
+}
+#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;
+ up_serialout(priv, STM32_USART_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;
+
+ /* USART transmit interrupts:
+ *
+ * Enable Bit Status Meaning Usage
+ * ------------------ --- --------------- ---------------------------- ----------
+ * USART_CR1_TCIE 6 USART_SR_TC Transmission Complete (not used)
+ * USART_CR1_TXEIE 7 USART_SR_TXE Transmit Data Register Empty
+ * USART_CR3_CTSIE 10 USART_SR_CTS CTS flag (not used)
+ */
+
+ flags = irqsave();
+ if (enable)
+ {
+ /* Set to receive an interrupt when the TX data register is empty */
+
+#ifndef CONFIG_SUPPRESS_SERIAL_INTS
+ up_restoreusartint(priv, priv->ie | USART_CR1_TXEIE);
+
+ /* 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);
+ }
+ irqrestore(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 ((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
+
+/****************************************************************************
+ * 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);
+ }
+}
+#endif
+
+#endif /* HAVE UART */
+
+/****************************************************************************
+ * 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
+ * strucure 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, 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
+ * strucure 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, enum pm_state_e pmstate)
+{
+ /* Logic to prepare for a reduced power state goes here. */
+
+ return OK;
+}
+#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)
+{
+#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 */
+}
+
+/****************************************************************************
+ * 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, j;
+#ifdef CONFIG_PM
+ int ret;
+#endif
+
+ /* Register to receive power management callbacks */
+
+#ifdef CONFIG_PM
+ ret = pm_register(&g_serialcb);
+ DEBUGASSERT(ret == OK);
+#endif
+
+ /* Register the console */
+
+#if CONSOLE_UART > 0
+ (void)uart_register("/dev/console", &uart_devs[CONSOLE_UART - 1]->dev);
+ (void)uart_register("/dev/ttyS0", &uart_devs[CONSOLE_UART - 1]->dev);
+
+ /* If we need to re-initialise the console to enable DMA do that here. */
+
+# ifdef SERIAL_HAVE_CONSOLE_DMA
+ 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, j = 1; i < STM32_NUSART; i++)
+ {
+
+ /* don't create a device for the console - we did that above */
+
+ if ((uart_devs[i] == 0) || (uart_devs[i]->dev.isconsole))
+ {
+ continue;
+ }
+
+ /* register USARTs as devices in increasing order */
+
+ devname[9] = '0' + j++;
+ (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 = irqsave();
+
+#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
+
+ irqrestore(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/nuttx/arch/arm/src/stm32/stm32_spi.c b/nuttx/arch/arm/src/stm32/stm32_spi.c
new file mode 100644
index 000000000..40b1a29a0
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_spi.c
@@ -0,0 +1,1440 @@
+/************************************************************************************
+ * arm/arm/src/stm32/stm32_spi.c
+ *
+ * Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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.h). All other methods (including up_spiinitialize())
+ * 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 up_spiinitialize() in your low level application
+ * initialization logic
+ * 4. The handle returned by up_spiinitialize() 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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/spi.h>
+
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "stm32_internal.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)
+
+/************************************************************************************
+ * 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)
+# 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)
+# 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 */
+
+#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 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 */
+#endif
+#ifndef CONFIG_SPI_OWNBUS
+ 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 or 16) */
+ uint8_t mode; /* Mode 0,1,2,3 */
+#endif
+};
+
+/************************************************************************************
+ * 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
+#endif
+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_portinitialize(FAR struct stm32_spidev_s *priv);
+
+/************************************************************************************
+ * Private Data
+ ************************************************************************************/
+
+#ifdef CONFIG_STM32_SPI1
+static const struct spi_ops_s g_sp1iops =
+{
+#ifndef CONFIG_SPI_OWNBUS
+ .lock = spi_lock,
+#endif
+ .select = stm32_spi1select,
+ .setfrequency = spi_setfrequency,
+ .setmode = spi_setmode,
+ .setbits = spi_setbits,
+ .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
+ .registercallback = 0,
+};
+
+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 =
+{
+#ifndef CONFIG_SPI_OWNBUS
+ .lock = spi_lock,
+#endif
+ .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
+ .registercallback = 0,
+};
+
+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 =
+{
+#ifndef CONFIG_SPI_OWNBUS
+ .lock = spi_lock,
+#endif
+ .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
+ .registercallback = 0,
+};
+
+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
+
+/************************************************************************************
+ * 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_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)
+{
+ uint32_t ccr;
+
+ /* 8- or 16-bit mode? */
+
+ if (spi_16bitmode(priv))
+ {
+ /* 16-bit mode -- is there a buffer to receive data in? */
+
+ if (rxbuffer)
+ {
+ ccr = SPI_RXDMA16_CONFIG;
+ }
+ else
+ {
+ rxbuffer = rxdummy;
+ ccr = SPI_RXDMA16NULL_CONFIG;
+ }
+ }
+ else
+ {
+ /* 8-bit mode -- is there a buffer to receive data in? */
+
+ if (rxbuffer)
+ {
+ ccr = SPI_RXDMA8_CONFIG;
+ }
+ else
+ {
+ rxbuffer = rxdummy;
+ ccr = SPI_RXDMA8NULL_CONFIG;
+ }
+ }
+
+ /* Configure the RX DMA */
+
+ stm32_dmasetup(priv->rxdma, priv->spibase + STM32_SPI_DR_OFFSET, (uint32_t)rxbuffer, nwords, ccr);
+}
+#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)
+{
+ uint32_t ccr;
+
+ /* 8- or 16-bit mode? */
+
+ if (spi_16bitmode(priv))
+ {
+ /* 16-bit mode -- is there a buffer to transfer data from? */
+
+ if (txbuffer)
+ {
+ ccr = SPI_TXDMA16_CONFIG;
+ }
+ else
+ {
+ txbuffer = txdummy;
+ ccr = SPI_TXDMA16NULL_CONFIG;
+ }
+ }
+ else
+ {
+ /* 8-bit mode -- is there a buffer to transfer data from? */
+
+ if (txbuffer)
+ {
+ ccr = SPI_TXDMA8_CONFIG;
+ }
+ else
+ {
+ txbuffer = txdummy;
+ ccr = SPI_TXDMA8NULL_CONFIG;
+ }
+ }
+
+ /* Setup the TX DMA */
+
+ stm32_dmasetup(priv->txdma, priv->spibase + STM32_SPI_DR_OFFSET,(uint32_t)txbuffer, nwords, ccr);
+}
+#endif
+
+/************************************************************************************
+ * Name: spi_dmarxstart
+ *
+ * Description:
+ * Start RX DMA
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_STM32_SPI_DMA
+static inline void spi_dmarxstart(FAR struct stm32_spidev_s *priv)
+{
+ 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)
+{
+ 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
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_OWNBUS
+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;
+}
+#endif
+
+/************************************************************************************
+ * 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? */
+
+#ifndef CONFIG_SPI_OWNBUS
+ if (frequency != priv->frequency)
+ {
+#endif
+ /* 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, setbits, SPI_CR1_BR_MASK);
+
+ /* Save the frequency selection so that subsequent reconfigurations will be
+ * faster.
+ */
+
+ spivdbg("Frequency %d->%d\n", frequency, actual);
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->frequency = frequency;
+ priv->actual = actual;
+ }
+ return priv->actual;
+#else
+ return actual;
+#endif
+}
+
+/************************************************************************************
+ * 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? */
+
+#ifndef CONFIG_SPI_OWNBUS
+ if (mode != priv->mode)
+ {
+#endif
+ /* 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, setbits, clrbits);
+
+ /* Save the mode so that subsequent re-configurations will be faster */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->mode = mode;
+ }
+#endif
+}
+
+/************************************************************************************
+ * 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? */
+
+#ifndef CONFIG_SPI_OWNBUS
+ if (nbits != priv->nbits)
+ {
+#endif
+ /* Yes... Set CR1 appropriately */
+
+ switch (nbits)
+ {
+ case 8:
+ setbits = 0;
+ clrbits = SPI_CR1_DFF;
+ break;
+
+ case 16:
+ setbits = SPI_CR1_DFF;
+ clrbits = 0;
+ break;
+
+ default:
+ return;
+ }
+
+ spi_modifycr1(priv, setbits, clrbits);
+
+ /* Save the selection so the subsequence re-configurations will be faster */
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->nbits = nbits;
+ }
+#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(FAR struct spi_dev_s *dev, uint16_t wd)
+{
+ FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
+ uint16_t ret;
+
+ DEBUGASSERT(priv && priv->spibase);
+
+ spi_writeword(priv, wd);
+ ret = spi_readword(priv);
+
+ spivdbg("Sent: %04x Return: %04x\n", wd, ret);
+ return ret;
+}
+
+/*************************************************************************
+ * Name: spi_exchange (no DMA)
+ *
+ * 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
+ *
+ ************************************************************************************/
+
+#ifndef 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;
+ 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
+
+/*************************************************************************
+ * 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;
+ uint16_t rxdummy = 0xffff;
+ uint16_t txdummy;
+
+ 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
+
+/*************************************************************************
+ * 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_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 void spi_portinitialize(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);
+
+#ifndef CONFIG_SPI_OWNBUS
+ priv->frequency = 0;
+ priv->nbits = 8;
+ priv->mode = SPIDEV_MODE0;
+#endif
+
+ /* 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 */
+
+#ifndef CONFIG_SPI_OWNBUS
+ sem_init(&priv->exclsem, 0, 1);
+#endif
+
+ /* 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);
+#endif
+
+ /* Enable spi */
+
+ spi_modifycr1(priv, SPI_CR1_SPE, 0);
+}
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: up_spiinitialize
+ *
+ * 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 *up_spiinitialize(int port)
+{
+ FAR struct stm32_spidev_s *priv = NULL;
+
+ irqstate_t flags = irqsave();
+
+#ifdef CONFIG_STM32_SPI1
+ if (port == 1)
+ {
+ /* Select SPI1 */
+
+ priv = &g_spi1dev;
+
+ /* Only configure if the port 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_portinitialize(priv);
+ }
+ }
+ else
+#endif
+#ifdef CONFIG_STM32_SPI2
+ if (port == 2)
+ {
+ /* Select SPI2 */
+
+ priv = &g_spi2dev;
+
+ /* Only configure if the port 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_portinitialize(priv);
+ }
+ }
+ else
+#endif
+#ifdef CONFIG_STM32_SPI3
+ if (port == 3)
+ {
+ /* Select SPI3 */
+
+ priv = &g_spi3dev;
+
+ /* Only configure if the port 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_portinitialize(priv);
+ }
+ }
+#endif
+
+ irqrestore(flags);
+ return (FAR struct spi_dev_s *)priv;
+}
+
+#endif /* CONFIG_STM32_SPI1 || CONFIG_STM32_SPI2 || CONFIG_STM32_SPI3 */
diff --git a/nuttx/arch/arm/src/stm32/stm32_spi.h b/nuttx/arch/arm/src/stm32/stm32_spi.h
new file mode 100644
index 000000000..6030ddfdd
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_spi.h
@@ -0,0 +1,121 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_spi.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <nuttx/config.h>
+
+#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_spi1/2/3select and stm32_spi1/2/3status
+ *
+ * Description:
+ * The external functions, stm32_spi1/2/3select, stm32_spi1/2/3status, and
+ * stm32_spi1/2/3cmddata 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.h). All other methods
+ * (including up_spiinitialize()) 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. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration file, then
+ * provide stm32_spi1/2/3cmddata() 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 up_spiinitialize() in your low level application
+ * initialization logic
+ * 5. The handle returned by up_spiinitialize() 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).
+ *
+ ************************************************************************************/
+
+EXTERN void stm32_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t stm32_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+EXTERN int stm32_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+
+EXTERN void stm32_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t stm32_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+EXTERN int stm32_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+
+EXTERN void stm32_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN uint8_t stm32_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
+EXTERN int stm32_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_STC_STM32_STM32_SPI_H */
+
diff --git a/nuttx/arch/arm/src/stm32/stm32_start.c b/nuttx/arch/arm/src/stm32/stm32_start.c
new file mode 100644
index 000000000..3f2f45b6b
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_start.c
@@ -0,0 +1,232 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_start.c
+ * arch/arm/src/chip/stm32_start.c
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/init.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "stm32_internal.h"
+#include "stm32_gpio.h"
+
+#ifdef CONFIG_ARCH_FPU
+# include "nvic.h"
+#endif
+
+/****************************************************************************
+ * 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: 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
+#ifdef CONFIG_ARMV7M_CMNVECTOR
+
+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
+
+/****************************************************************************
+ * 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 */
+
+ 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 = &_sbss; dest < &_ebss; )
+ {
+ *dest++ = 0;
+ }
+ showprogress('B');
+
+ /* Move the intialized 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');
+
+ /* Initialize onboard resources */
+
+ stm32_boardinitialize();
+ showprogress('E');
+
+ /* Then start NuttX */
+
+ showprogress('\r');
+ showprogress('\n');
+ os_start();
+
+ /* Shoulnd't get here */
+
+ for(;;);
+}
diff --git a/nuttx/arch/arm/src/stm32/stm32_syscfg.h b/nuttx/arch/arm/src/stm32/stm32_syscfg.h
new file mode 100644
index 000000000..d1487da40
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_syscfg.h
@@ -0,0 +1,54 @@
+/****************************************************************************************************
+ * arch/arm/src/stm32/stm32_syscfg.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include "chip.h"
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# include "chip/stm32_syscfg.h"
+#endif /* CONFIG_STM32_STM32F20XX || CONFIG_STM32_STM32F40XX */
+
+/****************************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_STM32_STM32_SYSCFG_H */
diff --git a/nuttx/arch/arm/src/stm32/stm32_tim.c b/nuttx/arch/arm/src/stm32/stm32_tim.c
new file mode 100644
index 000000000..d19c69c03
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_tim.c
@@ -0,0 +1,1020 @@
+/************************************************************************************
+ * arm/arm/src/stm32/stm32_tim.c
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Author: Uros Platise <uros.platise@isotel.eu>
+ *
+ * With modifications and updates by:
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "stm32_internal.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
+
+/* 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);
+}
+
+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);
+ }
+}
+
+/************************************************************************************
+ * 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)
+ {
+#if CONFIG_STM32_TIM2
+ case STM32_TIM2_BASE:
+ vectorno = STM32_IRQ_TIM2;
+ break;
+#endif
+#if CONFIG_STM32_TIM3
+ case STM32_TIM3_BASE:
+ vectorno = STM32_IRQ_TIM3;
+ break;
+#endif
+#if CONFIG_STM32_TIM4
+ case STM32_TIM4_BASE:
+ vectorno = STM32_IRQ_TIM4;
+ break;
+#endif
+#if CONFIG_STM32_TIM5
+ case STM32_TIM5_BASE:
+ vectorno = STM32_IRQ_TIM5;
+ break;
+#endif
+#if STM32_NBTIM > 0
+#if CONFIG_STM32_TIM6
+ case STM32_TIM6_BASE:
+ vectorno = STM32_IRQ_TIM6;
+ break;
+#endif
+#endif
+#if STM32_NBTIM > 1
+#if 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 */
+#if CONFIG_STM32_TIM1
+ case STM32_TIM1_BASE:
+ vectorno = STM32_IRQ_TIM1UP;
+ break;
+#endif
+#if 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);
+//up_prioritize_irq(vectorno, NVIC_SYSH_PRIORITY_DEFAULT);
+ 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_val = 0;
+ 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;
+ }
+
+ if (channel > 1)
+ {
+ ccmr_offset = STM32_GTIM_CCMR2_OFFSET;
+ }
+
+ stm32_putreg16(dev, ccmr_offset, ccmr_val);
+ stm32_putreg16(dev, STM32_GTIM_CCER_OFFSET, ccer_val);
+
+ /* set GPIO */
+
+ switch (((struct stm32_tim_priv_s *)dev)->base)
+ {
+#if 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
+#if 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
+#if 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
+#if 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
+#if 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
+#if 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
+};
+
+#if 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
+
+#if 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
+
+#if 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
+
+#if 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
+#if 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
+#if 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
+
+#if 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
+
+#if 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)
+ {
+#if CONFIG_STM32_TIM2
+ case 2:
+ dev = (struct stm32_tim_dev_s *)&stm32_tim2_priv;
+ modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_TIM2EN);
+ break;
+#endif
+#if CONFIG_STM32_TIM3
+ case 3:
+ dev = (struct stm32_tim_dev_s *)&stm32_tim3_priv;
+ modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_TIM3EN);
+ break;
+#endif
+#if CONFIG_STM32_TIM4
+ case 4:
+ dev = (struct stm32_tim_dev_s *)&stm32_tim4_priv;
+ modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_TIM4EN);
+ break;
+#endif
+#if 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
+#if 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
+#if 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
+#if CONFIG_STM32_TIM1
+ case 1:
+ dev = (struct stm32_tim_dev_s *)&stm32_tim1_priv;
+ modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM1EN);
+ break;
+#endif
+#if 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)
+ {
+#if CONFIG_STM32_TIM2
+ case STM32_TIM2_BASE:
+ modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_TIM2EN, 0);
+ break;
+#endif
+#if CONFIG_STM32_TIM3
+ case STM32_TIM3_BASE:
+ modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_TIM3EN, 0);
+ break;
+#endif
+#if CONFIG_STM32_TIM4
+ case STM32_TIM4_BASE:
+ modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_TIM4EN, 0);
+ break;
+#endif
+#if CONFIG_STM32_TIM5
+ case STM32_TIM5_BASE:
+ modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_TIM5EN, 0);
+ break;
+#endif
+#if STM32_NBTIM > 0
+#if CONFIG_STM32_TIM6
+ case STM32_TIM6_BASE:
+ modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_TIM6EN, 0);
+ break;
+#endif
+#endif
+#if STM32_NBTIM > 1
+#if CONFIG_STM32_TIM7
+ case STM32_TIM7_BASE:
+ modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_TIM7EN, 0);
+ break;
+#endif
+#endif
+
+#if STM32_NATIM > 0
+#if CONFIG_STM32_TIM1
+ case STM32_TIM1_BASE:
+ modifyreg32(STM32_RCC_APB2ENR, RCC_APB2ENR_TIM1EN, 0);
+ break;
+#endif
+#if 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/nuttx/arch/arm/src/stm32/stm32_tim.h b/nuttx/arch/arm/src/stm32/stm32_tim.h
new file mode 100644
index 000000000..081a3489f
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_tim.h
@@ -0,0 +1,191 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_tim.h
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Author: Uros Platise <uros.platise@isotel.eu>
+ *
+ * With modifications and updates by:
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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);
+
+ 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 */
+
+EXTERN FAR struct stm32_tim_dev_s * stm32_tim_init(int timer);
+
+/* Power-down timer, mark it as unused */
+
+EXTERN int stm32_tim_deinit(FAR struct stm32_tim_dev_s * dev);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32_STM32_TIM_H */
diff --git a/nuttx/arch/arm/src/stm32/stm32_timerisr.c b/nuttx/arch/arm/src/stm32/stm32_timerisr.c
new file mode 100644
index 000000000..ff6499415
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_timerisr.c
@@ -0,0 +1,164 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_timerisr.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <time.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "nvic.h"
+#include "clock_internal.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "stm32_internal.h"
+
+/****************************************************************************
+ * 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 */
+
+#if 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 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize
+ * the timer interrupt.
+ *
+ ****************************************************************************/
+
+void up_timerinit(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);
+#if 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/nuttx/arch/arm/src/stm32/stm32_uart.h b/nuttx/arch/arm/src/stm32/stm32_uart.h
new file mode 100644
index 000000000..a70923cbf
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_uart.h
@@ -0,0 +1,271 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_uart.h
+ *
+ * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <nuttx/config.h>
+
+#include "chip.h"
+#include "chip/stm32_uart.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+/* Make sure that we have not enabled more U[S]ARTs than are support by
+ * the device.
+ */
+
+#if STM32_NUSART < 6
+# undef CONFIG_STM32_USART6
+#endif
+#if STM32_NUSART < 5
+# undef CONFIG_STM32_UART5
+#endif
+#if STM32_NUSART < 4
+# undef CONFIG_STM32_UART4
+#endif
+#if STM32_NUSART < 3
+# 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)
+# 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
+# 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
+# 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
+# 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
+# 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
+# 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
+# define CONSOLE_UART 6
+# 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
+# define CONSOLE_UART 0
+# undef HAVE_CONSOLE
+#endif
+
+/* DMA support is only provided if CONFIG_ARCH_DMA is in the NuttX configuration.
+ * Furthermore, DMA support is currently only implemented for the F4 (but could be
+ * extended to the F1 and F2 with a little effort in the DMA code.
+ */
+
+#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA) || !defined(CONFIG_STM32_STM32F40XX)
+# undef CONFIG_USART1_RXDMA
+# undef CONFIG_USART2_RXDMA
+# undef CONFIG_USART3_RXDMA
+# undef CONFIG_UART4_RXDMA
+# undef CONFIG_UART5_RXDMA
+# undef CONFIG_USART6_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
+
+/* 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)
+# 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
+#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
+#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
+EXTERN 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/nuttx/arch/arm/src/stm32/stm32_usbdev.c b/nuttx/arch/arm/src/stm32/stm32_usbdev.c
new file mode 100644
index 000000000..602de3824
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_usbdev.c
@@ -0,0 +1,3664 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_usbdev.c
+ *
+ * Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.orgr>
+ *
+ * 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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/usb/usb.h>
+#include <nuttx/usb/usbdev.h>
+#include <nuttx/usb/usbdev_trace.h>
+
+#include <arch/irq.h>
+
+#include "up_arch.h"
+#include "stm32_internal.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_USB_PRI
+# define CONFIG_USB_PRI NVIC_SYSH_PRIORITY_DEFAULT
+#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)<<STM32_MAXPACKET_SHIFT))
+
+/* 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 stm32_rqempty(ep) ((ep)->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
+
+/* 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_devstate_e
+{
+ DEVSTATE_IDLE = 0, /* No request in progress */
+ DEVSTATE_RDREQUEST, /* Read request in progress */
+ DEVSTATE_WRREQUEST, /* Write request in progress */
+ DEVSTATE_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 */
+
+ struct usb_ctrlreq_s ctrl; /* Last EP0 request */
+ uint8_t devstate; /* Driver state (see enum stm32_devstate_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 */
+
+ /* 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);
+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
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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_USBCANRAM_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_USBCANRAM_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 = irqsave();
+ privreq = stm32_rqdequeue(privep);
+ irqrestore(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->devstate == DEVSTATE_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
+ ****************************************************************************/
+
+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);
+ priv->devstate = DEVSTATE_IDLE;
+ return OK;
+ }
+
+ 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);
+
+ /* 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"
+
+ /* Send the next packet */
+
+ if (nbytes > 0)
+ {
+ /* 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 nbytes == 0) */
+
+ buf = privreq->req.buf + privreq->req.xfrd;
+ stm32_epwrite(priv, privep, buf, nbytes);
+ priv->devstate = DEVSTATE_WRREQUEST;
+
+ /* 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 transfer
+ */
+
+ if (bytesleft == 0 && !privep->txnullpkt)
+ {
+ usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd);
+ privep->txnullpkt = 0;
+ stm32_reqcomplete(privep, OK);
+ priv->devstate = DEVSTATE_IDLE;
+ }
+
+ 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 OK;
+ }
+
+ 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);
+ priv->devstate = DEVSTATE_RDREQUEST;
+
+ /* If the receive buffer is full or this is a partial packet,
+ * then we are finished with the transfer
+ */
+
+ privreq->req.xfrd += readlen;
+ if (pmalen < privep->ep.maxpacket || privreq->req.xfrd >= privreq->req.len)
+ {
+ /* Complete the transfer and mark the state IDLE. The endpoint
+ * RX will be marked valid when the data phase completes.
+ */
+
+ usbtrace(TRACE_COMPLETE(epno), privreq->req.xfrd);
+ stm32_reqcomplete(privep, OK);
+ priv->devstate = DEVSTATE_IDLE;
+ }
+
+ 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, NULL, 0);
+ if (ret < 0)
+ {
+ /* Stall on failure */
+
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DISPATCHSTALL), 0);
+ priv->devstate = DEVSTATE_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 */
+
+ 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;
+ 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 */
+ int ret;
+
+ /* 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;
+
+ /* 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);
+
+ priv->devstate = DEVSTATE_IDLE;
+
+ /* 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->devstate = DEVSTATE_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->devstate = DEVSTATE_STALLED;
+ }
+ else
+ {
+ privep = &priv->eplist[epno];
+ 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->devstate = DEVSTATE_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->devstate = DEVSTATE_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;
+ ret = stm32_epstall(&privep->ep, true);
+ }
+ else
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0);
+ priv->devstate = DEVSTATE_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;
+ ret = stm32_epstall(&privep->ep, false);
+ }
+ else
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0);
+ priv->devstate = DEVSTATE_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->devstate = DEVSTATE_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->devstate = DEVSTATE_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->devstate = DEVSTATE_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->devstate = DEVSTATE_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->devstate = DEVSTATE_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 devstate != DEVSTATE_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 DEVSTATE_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->devstate != DEVSTATE_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->devstate = DEVSTATE_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->devstate == DEVSTATE_WRREQUEST)
+ {
+ stm32_wrrequest(priv, &priv->eplist[EP0]);
+ }
+
+ /* No.. Are we processing the completion of a status response? */
+
+ else if (priv->devstate == DEVSTATE_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->devstate = DEVSTATE_STALLED;
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_ep0out
+ ****************************************************************************/
+
+static void stm32_ep0out(struct stm32_usbdev_s *priv)
+{
+ struct stm32_ep_s *privep = &priv->eplist[EP0];
+ switch (priv->devstate)
+ {
+ case DEVSTATE_RDREQUEST: /* Write request in progress */
+ case DEVSTATE_IDLE: /* No transfer in progress */
+ stm32_rdrequest(priv, privep);
+ break;
+
+ default:
+ /* Unexpected state OR host aborted the OUT transfer before it
+ * completed, STALL the endpoint in either case
+ */
+
+ priv->devstate = DEVSTATE_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 devstate 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->devstate == DEVSTATE_STALLED)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0SETUPSTALLED), priv->devstate);
+ 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;
+
+ /* 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);
+}
+
+/****************************************************************************
+ * 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 = irqsave();
+ 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;
+ }
+ }
+ }
+
+ irqrestore(flags);
+ return privep;
+}
+
+/****************************************************************************
+ * Name: stm32_epunreserve
+ ****************************************************************************/
+
+static inline void
+stm32_epunreserve(struct stm32_usbdev_s *priv, struct stm32_ep_s *privep)
+{
+ irqstate_t flags = irqsave();
+ priv->epavail |= STM32_ENDP_BIT(USB_EPNO(privep->ep.eplog));
+ irqrestore(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 = irqsave();
+ 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;
+ }
+ }
+
+ irqrestore(flags);
+ return bufno;
+}
+
+/****************************************************************************
+ * Name: stm32_epfreepma
+ ****************************************************************************/
+
+static inline void
+stm32_epfreepma(struct stm32_usbdev_s *priv, struct stm32_ep_s *privep)
+{
+ irqstate_t flags = irqsave();
+ priv->epavail |= STM32_ENDP_BIT(privep->bufno);
+ irqrestore(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 = irqsave();
+ 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);
+
+ irqrestore(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 *)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));
+
+ 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 = irqsave();
+
+ /* 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;
+ 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;
+ }
+ }
+
+ irqrestore(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;
+ struct stm32_usbdev_s *priv;
+ 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));
+ priv = privep->dev;
+
+ flags = irqsave();
+ stm32_cancelrequests(privep);
+ irqrestore(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 = USB_EPNO(ep->eplog);
+ 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 = irqsave();
+ 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);
+ priv->devstate = DEVSTATE_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;
+ (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);
+ }
+ }
+
+ irqrestore(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;
+ }
+ epno = USB_EPNO(privep->ep.eplog);
+
+ /* 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 = irqsave();
+ 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);
+ irqrestore(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->devstate = DEVSTATE_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();
+
+ /* Power up the USB controller, but leave it in the reset state */
+
+ stm32_hwsetup(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(STM32_IRQ_USBHPCANTX, stm32_hpinterrupt) != 0)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_IRQREGISTRATION),
+ (uint16_t)STM32_IRQ_USBHPCANTX);
+ goto errout;
+ }
+
+ if (irq_attach(STM32_IRQ_USBLPCANRX0, stm32_lpinterrupt) != 0)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_IRQREGISTRATION),
+ (uint16_t)STM32_IRQ_USBLPCANRX0);
+ 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 = irqsave();
+ usbtrace(TRACE_DEVUNINIT, 0);
+
+ /* Disable and detach the USB IRQs */
+
+ up_disable_irq(STM32_IRQ_USBHPCANTX);
+ up_disable_irq(STM32_IRQ_USBLPCANRX0);
+ irq_detach(STM32_IRQ_USBHPCANTX);
+ irq_detach(STM32_IRQ_USBLPCANRX0);
+
+ if (priv->driver)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DRIVERREGISTERED), 0);
+ usbdev_unregister(priv->driver);
+ }
+
+ /* Put the hardware in an inactive state */
+
+ stm32_hwshutdown(priv);
+ irqrestore(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);
+ priv->driver = NULL;
+ }
+ 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_USBHPCANTX);
+ up_enable_irq(STM32_IRQ_USBLPCANRX0);
+
+ /* Set the interrrupt priority */
+
+ up_prioritize_irq(STM32_IRQ_USBHPCANTX, CONFIG_USB_PRI);
+ up_prioritize_irq(STM32_IRQ_USBLPCANRX0, CONFIG_USB_PRI);
+
+ /* 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 = irqsave();
+ 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_USBHPCANTX);
+ up_disable_irq(STM32_IRQ_USBLPCANRX0);
+
+ /* 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;
+ irqrestore(flags);
+ return OK;
+}
+
+#endif /* CONFIG_USBDEV && CONFIG_STM32_USB */
diff --git a/nuttx/arch/arm/src/stm32/stm32_usbdev.h b/nuttx/arch/arm/src/stm32/stm32_usbdev.h
new file mode 100644
index 000000000..587107dc8
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_usbdev.h
@@ -0,0 +1,98 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_usbdev.h
+ *
+ * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <nuttx/usb/usbdev.h>
+#include <stdint.h>
+
+#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.
+ * Alternatively, if no pull-up GPIO the following EXTERN can be redefined to be
+ * NULL.
+ *
+ ************************************************************************************/
+
+EXTERN 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.
+ *
+ ************************************************************************************/
+
+EXTERN 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/nuttx/arch/arm/src/stm32/stm32_usbhost.h b/nuttx/arch/arm/src/stm32/stm32_usbhost.h
new file mode 100644
index 000000000..d9bce33f7
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_usbhost.h
@@ -0,0 +1,128 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_usbhost.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+#include <nuttx/usb/usbhost.h>
+#include <stdint.h>
+
+#include "chip.h"
+#include "chip/stm32_otgfs.h"
+
+#if defined(CONFIG_STM32_OTGFS) && defined(CONFIG_USBHOST)
+
+/************************************************************************************
+ * 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
+ * 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_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
+ *
+ ***********************************************************************************/
+
+EXTERN 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/nuttx/arch/arm/src/stm32/stm32_vectors.S b/nuttx/arch/arm/src/stm32/stm32_vectors.S
new file mode 100644
index 000000000..ab4dadb77
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_vectors.S
@@ -0,0 +1,427 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_vectors.S
+ * arch/arm/src/chip/stm32_vectors.S
+ *
+ * Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+
+#include <arch/irq.h>
+
+#include "chip.h"
+
+/************************************************************************************
+ * Configuration
+ ************************************************************************************/
+/* Check if common ARMv7 interrupt vectoring is used (see
+ * arch/arm/src/armv7-m/up_vectors.S)
+ */
+
+#ifndef CONFIG_ARMV7M_CMNVECTOR
+
+/************************************************************************************
+ * Preprocessor Definitions
+ ************************************************************************************/
+/* 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-4)
+
+/* The Cortex-M3 return from interrupt is unusual. We provide the following special
+ * address to the BX instruction. The particular value also forces a return to
+ * thread mode and covers state from the main stack point, the MSP (vs. the MSP).
+ */
+
+#define EXC_RETURN 0xfffffff9
+
+/************************************************************************************
+ * Global Symbols
+ ************************************************************************************/
+
+ .globl __start
+
+ .syntax unified
+ .thumb
+ .file "stm32_vectors.S"
+
+/************************************************************************************
+ * 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 stm32_common
+ .endm
+
+/************************************************************************************
+ * Vectors
+ ************************************************************************************/
+
+ .section .vectors, "ax"
+ .code 16
+ .align 2
+ .globl stm32_vectors
+ .type stm32_vectors, function
+
+stm32_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 */
+
+#undef VECTOR
+#define VECTOR(l,i) .word l
+
+#undef UNUSED
+#define UNUSED(i) .word stm32_reserved
+
+#if defined(CONFIG_STM32_STM32F10XX)
+# include "chip/chip/stm32f10xxx_vectors.h"
+#elif defined(CONFIG_STM32_STM32F20XX)
+# include "chip/chip/stm32f20xxx_vectors.h"
+#elif defined(CONFIG_STM32_STM32F40XX)
+# include "chip/chip/stm32f40xxx_vectors.h"
+#else
+# error "No vectors for STM32 chip"
+#endif
+ .size stm32_vectors, .-stm32_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 */
+
+#undef VECTOR
+#define VECTOR(l,i) HANDLER l, i
+
+#undef UNUSED
+#define UNUSED(i)
+
+#if defined(CONFIG_STM32_STM32F10XX)
+# include "chip/chip/stm32f10xxx_vectors.h"
+#elif defined(CONFIG_STM32_STM32F20XX)
+# include "chip/chip/stm32f20xxx_vectors.h"
+#elif defined(CONFIG_STM32_STM32F40XX)
+# include "chip/chip/stm32f40xxx_vectors.h"
+#else
+# error "No handlers for STM32 chip"
+#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
+ */
+
+stm32_common:
+
+ /* Complete the context save */
+
+#ifdef CONFIG_NUTTX_KERNEL
+ /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
+ * (handler mode) if the state is on the MSP. It can only be on the PSP if
+ * EXC_RETURN is 0xfffffffd (unprivileged thread)
+ */
+
+ adds r2, r14, #3 /* If R14=0xfffffffd, then r2 == 0 */
+ ite ne /* Next two instructions are conditional */
+ mrsne r1, msp /* R1=The main stack pointer */
+ mrseq r1, psp /* R1=The process stack pointer */
+#else
+ mrs r1, msp /* R1=The main stack pointer */
+#endif
+
+ /* r1 holds the value of the stack pointer AFTER the excption handling logic
+ * pushed the various registers onto the stack. Get r2 = the value of the
+ * stack pointer BEFORE the interrupt modified it.
+ */
+
+ mov r2, r1 /* R2=Copy of the main/process stack pointer */
+ add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
+ mrs r3, primask /* R3=Current PRIMASK setting */
+
+#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 r1, #(4*SW_FPU_REGS)
+#endif
+
+ /* Save the the remaining registers on the stack after the registers pushed
+ * by the exception handling logic. r2=SP and r3=primask, r4-r11,r14=register
+ * values.
+ */
+
+#ifdef CONFIG_NUTTX_KERNEL
+ stmdb r1!, {r2-r11,r14} /* Save the remaining registers plus the SP value */
+#else
+ stmdb r1!, {r2-r11} /* Save the remaining registers plus the SP value */
+#endif
+
+ /* 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 re-use the main stack for interrupt level processing.
+ */
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ ldr sp, =g_intstackbase
+ str r1, [sp, #-4]! /* Save the MSP on the interrupt stack */
+ bl up_doirq /* R0=IRQ, R1=register save (msp) */
+ ldr r1, [sp, #+4]! /* Recover R1=main stack pointer */
+#else
+ mov sp, r1 /* We are using the main stack pointer */
+ bl up_doirq /* R0=IRQ, R1=register save (msp) */
+ mov r1, sp /* 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 1f /* 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
+
+ /* Returning with a pending context switch is different from the normal
+ * return because in this case, the register save structure does not lie
+ * on the stack but, rather, are within a TCB structure. We'll have to
+ * copy somevalues to the new 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_NUTTX_KERNEL
+ 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 2f /* 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)
+ */
+1:
+#ifdef CONFIG_NUTTX_KERNEL
+ 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
+ * r4-r11 = restored register values
+ */
+2:
+#ifdef CONFIG_NUTTX_KERNEL
+ /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
+ * (handler mode) if the state is on the MSP. It can only be on the PSP if
+ * EXC_RETURN is 0xfffffffd (unprivileged thread)
+ */
+
+ adds r0, r14, #3 /* If R14=0xfffffffd, then r0 == 0 */
+ ite ne /* Next two instructions are condition */
+ msrne msp, r1 /* R1=The main stack pointer */
+ msreq psp, r1 /* R1=The process stack pointer */
+#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 /* Load the special value */
+#endif
+
+ /* Restore the interrupt state */
+
+ msr primask, r3 /* Restore interrupts */
+
+ /* 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: up_interruptstack/g_intstackbase
+ *
+ * Description:
+ * Shouldn't happen
+ *
+ ************************************************************************************/
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ .bss
+ .global g_intstackbase
+ .align 4
+up_interruptstack:
+ .skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
+g_intstackbase:
+ .size up_interruptstack, .-up_interruptstack
+#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_heapbase below.
+ */
+
+ .globl g_heapbase
+ .type g_heapbase, object
+g_heapbase:
+ .long _ebss+CONFIG_IDLETHREAD_STACKSIZE
+ .size g_heapbase, .-g_heapbase
+
+ .end
+
diff --git a/nuttx/arch/arm/src/stm32/stm32_waste.c b/nuttx/arch/arm/src/stm32/stm32_waste.c
new file mode 100644
index 000000000..a680b8b0f
--- /dev/null
+++ b/nuttx/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 <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <stdint.h>
+#include "stm32_waste.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+uint32_t idle_wastecounter = 0;
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void up_waste(void)
+{
+ idle_wastecounter++;
+}
diff --git a/nuttx/arch/arm/src/stm32/stm32_waste.h b/nuttx/arch/arm/src/stm32/stm32_waste.h
new file mode 100644
index 000000000..fa734f432
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_waste.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_waste.h
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Author: Uros Platise <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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).
+ **/
+
+EXTERN void up_waste(void);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32_STM32_RRC_H */
diff --git a/nuttx/arch/arm/src/stm32/stm32_wdg.h b/nuttx/arch/arm/src/stm32/stm32_wdg.h
new file mode 100644
index 000000000..fbb8128b5
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_wdg.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_wdg.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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 intialized 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
+EXTERN void stm32_iwdginitialize(FAR const char *devpath, uint32_t lsifreq);
+#endif
+
+/****************************************************************************
+ * Name: stm32_wwdginitialize
+ *
+ * Description:
+ * Initialize the WWDG watchdog time. The watchdog timer is intialized 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
+EXTERN 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/nuttx/arch/arm/src/stm32/stm32_wwdg.c b/nuttx/arch/arm/src/stm32/stm32_wwdg.c
new file mode 100644
index 000000000..4506fa4e0
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_wwdg.c
@@ -0,0 +1,807 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_wwdg.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <nuttx/arch.h>
+
+#include <stdint.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/watchdog.h>
+#include <arch/board/board.h>
+
+#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 atchdog 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.
+ * stawtus - 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 millisecnds.
+ *
+ * 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 explicity 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 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 = irqsave();
+ 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);
+ }
+
+ irqrestore(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 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 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 intialized 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)
+ {
+ uint32_t cr = getreg32(STM32_DBGMCU_CR);
+ cr |= DBGMCU_CR_WWDGSTOP;
+ putreg32(cr, STM32_DBGMCU_CR);
+ }
+#endif
+}
+
+#endif /* CONFIG_WATCHDOG && CONFIG_STM32_WWDG */
diff --git a/nuttx/arch/arm/src/stm32/stm32f10xxx_dma.c b/nuttx/arch/arm/src/stm32/stm32f10xxx_dma.c
new file mode 100644
index 000000000..89b279bea
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32f10xxx_dma.c
@@ -0,0 +1,615 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32f10xxx_dma.c
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "os_internal.h"
+#include "chip.h"
+#include "stm32_dma.h"
+#include "stm32_internal.h"
+
+/* Only for the STM32F10xx family for now */
+
+#ifdef CONFIG_STM32_STM32F10XX
+
+/****************************************************************************
+ * 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,
+#ifdef CONFIG_STM32_CONNECTIVITYLINE
+ .irq = STM32_IRQ_DMA2CH4,
+#else
+ .irq = STM32_IRQ_DMA2CH45,
+#endif
+ .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(3),
+ },
+ {
+ .chan = 4,
+#ifdef CONFIG_STM32_CONNECTIVITYLINE
+ .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
+#ifdef CONFIG_STM32_CONNECTIVITYLINE
+ 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(OSERR_INTERNAL);
+ }
+ dmach = &g_dma[chndx];
+
+ /* Get the interrupt status (for this channel only) -- not currently used */
+
+ isr = dmabase_getreg(dmach, STM32_DMA_ISR_OFFSET) & DMA_ISR_CHAN_MASK(dmach->chan);
+
+ /* Disable the DMA channel */
+
+ stm32_dmachandisable(dmach);
+
+ /* 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);
+
+ /* Set the interrrupt priority */
+
+ up_prioritize_irq(dmach->irq, CONFIG_DMA_PRI);
+ }
+}
+
+/****************************************************************************
+ * 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;
+
+ /* 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;
+
+ /* 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));
+ 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_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 = irqsave();
+ 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);
+ irqrestore(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/nuttx/arch/arm/src/stm32/stm32f10xxx_rcc.c b/nuttx/arch/arm/src/stm32/stm32f10xxx_rcc.c
new file mode 100644
index 000000000..10b8572cf
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32f10xxx_rcc.c
@@ -0,0 +1,562 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32f10xxx_rcc.c
+ *
+ * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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|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;
+
+#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
+
+#if defined(CONFIG_STM32_ETHMAC) && defined(CONFIG_STM32_CONNECTIVITYLINE)
+ /* Ethernet clock enable */
+
+ regval |= (RCC_AHBENR_ETHMACEN | RCC_AHBENR_ETHMACTXEN | RCC_AHBENR_ETHMACRXEN);
+#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_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_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
+ 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
+ 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!
+ ****************************************************************************/
+
+#ifndef 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 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 multipler */
+
+ 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);
+}
+#endif
+
+/****************************************************************************
+ * Name: rcc_enableperiphals
+ ****************************************************************************/
+
+static inline void rcc_enableperipherals(void)
+{
+ rcc_enableahb();
+ rcc_enableapb2();
+ rcc_enableapb1();
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
diff --git a/nuttx/arch/arm/src/stm32/stm32f10xxx_rtc.c b/nuttx/arch/arm/src/stm32/stm32f10xxx_rtc.c
new file mode 100644
index 000000000..e1d52ac09
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32f10xxx_rtc.c
@@ -0,0 +1,689 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32f10xxx_rtc.c
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Author: Uros Platise <uros.platise@isotel.eu>
+ *
+ * With extensions, modifications by:
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregroy Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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 <nuttx/config.h>
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/rtc.h>
+#include <arch/board/board.h>
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <errno.h>
+
+#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
+
+/* 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 oscilator.
+ * 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);
+}
+
+/************************************************************************************
+ * 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: up_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 up_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 up_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_rtcinitialize
+ *
+ * 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_rtcinitialize(void)
+{
+ /* Set access to the peripheral, enable the backup domain (BKP) and the lower power
+ * extern 32,768Hz (Low-Speed External, LSE) oscillator. Configure the LSE to
+ * drive the RTC.
+ */
+
+ stm32_pwr_enablebkp();
+ 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 */
+
+ 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
+ * intialization 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 interrrupted
+ * or the lower 16-bit counter could rollover between reads. Disabling
+ * interrupts will prevent suspensions and interruptions:
+ */
+
+ flags = irqsave();
+
+ /* 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);
+ irqrestore(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 interrrupted
+ * or the lower 16-bit counter could rollover between reads. Disabling
+ * interrupts will prevent suspensions and interruptions:
+ */
+
+ flags = irqsave();
+
+ /* 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);
+ irqrestore(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;
+
+ /* Break out the time values */
+
+ up_rtc_breakout(tp, &regvals);
+
+ /* Then write the broken out values to the RTC counter and BKP overflow register
+ * (hi-res mode only)
+ */
+
+ flags = irqsave();
+ stm32_rtc_beginwr();
+ putreg16(regvals.cnth, STM32_RTC_CNTH);
+ putreg16(regvals.cntl, STM32_RTC_CNTL);
+ stm32_rtc_endwr();
+
+#ifdef CONFIG_RTC_HIRES
+ putreg16(regvals.ovf, RTC_TIMEMSB_REG);
+#endif
+ irqrestore(flags);
+ return OK;
+}
+
+/************************************************************************************
+ * Name: up_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 up_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 */
+
+ up_rtc_breakout(tp, &regvals);
+
+ /* Enable RTC alarm */
+
+ cr = getreg16(STM32_RTC_CRH);
+ cr |= RTC_CRH_ALRIE;
+ putreg16(cr, STM32_RTC_CRH);
+
+ /* The set the alarm */
+
+ flags = irqsave();
+ stm32_rtc_beginwr();
+ putreg16(regvals.cnth, STM32_RTC_ALRH);
+ putreg16(regvals.cntl, STM32_RTC_ALRL);
+ stm32_rtc_endwr();
+ irqrestore(flags);
+
+ ret = OK;
+ }
+ return ret;
+}
+#endif
+
+/************************************************************************************
+ * Name: up_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 up_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 = irqsave();
+ stm32_rtc_beginwr();
+ putreg16(0xffff, STM32_RTC_ALRH);
+ putreg16(0xffff, STM32_RTC_ALRL);
+ stm32_rtc_endwr();
+ irqrestore(flags);
+
+ ret = OK;
+ }
+ return ret;
+}
+#endif
diff --git a/nuttx/arch/arm/src/stm32/stm32f20xxx_dma.c b/nuttx/arch/arm/src/stm32/stm32f20xxx_dma.c
new file mode 100644
index 000000000..55aab352f
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32f20xxx_dma.c
@@ -0,0 +1,904 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32f20xxx_dma.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "os_internal.h"
+#include "chip.h"
+#include "stm32_dma.h"
+#include "stm32_internal.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(4),
+ },
+ {
+ .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(OSERR_INTERNAL);
+ }
+
+ /* 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);
+
+ /* Set the interrrupt priority */
+
+ up_prioritize_irq(dmast->irq, CONFIG_DMA_PRI);
+ }
+}
+
+/****************************************************************************
+ * 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 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_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 = irqsave();
+ 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);
+ irqrestore(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/nuttx/arch/arm/src/stm32/stm32f20xxx_rcc.c b/nuttx/arch/arm/src/stm32/stm32f20xxx_rcc.c
new file mode 100644
index 000000000..335992524
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32f20xxx_rcc.c
@@ -0,0 +1,666 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32f20xxx_rcc.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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).
+ */
+
+/****************************************************************************
+ * 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);
+
+ /* Set the PLL dividers and multiplers 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 */
+
+ regval = (FLASH_ACR_LATENCY_5 | FLASH_ACR_ICEN | FLASH_ACR_DCEN);
+ 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);
+ }
+}
+#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/nuttx/arch/arm/src/stm32/stm32f20xxx_rtc.c b/nuttx/arch/arm/src/stm32/stm32f20xxx_rtc.c
new file mode 100644
index 000000000..b98276498
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32f20xxx_rtc.c
@@ -0,0 +1,842 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32f20xxx_rtc.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/rtc.h>
+
+#include <time.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "up_arch.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
+
+/* Constants ************************************************************************/
+
+#define SYNCHRO_TIMEOUT (0x00020000)
+#define INITMODE_TIMEOUT (0x00010000)
+#define RTC_MAGIC (0xfacefeed)
+#define RTC_PREDIV_S (0xff)
+#define RTC_PREDIV_A (0x7f)
+
+/* 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));
+ rtclldbg(" CALIBR: %08x\n", getreg32(STM32_RTC_CALIBR));
+ 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(" BK0: %08x\n", getreg32(STM32_RTC_BK0R));
+}
+#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)
+{
+ /* 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 reactivates the write protection.
+ */
+
+ putreg32(0xca, STM32_RTC_WPR);
+ putreg32(0x53, STM32_RTC_WPR);
+}
+
+/************************************************************************************
+ * Name: rtc_wprunlock
+ *
+ * Description:
+ * Enable RTC write protection
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ************************************************************************************/
+
+static inline void rtc_wprlock(void)
+{
+ /* Writing any wrong key reactivates the write protection. */
+
+ putreg32(0xff, STM32_RTC_WPR);
+}
+
+/************************************************************************************
+ * 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;
+
+ /* Enable the External Low-Speed (LSE) Oscillator setup the LSE as the RTC clock\
+ * source, and enable the RTC.
+ */
+
+ stm32_rcc_enablelse();
+
+ /* Wait for the RTC Time and Date registers to be synchronized with RTC APB
+ * clock.
+ */
+
+ ret = rtc_synchwait();
+ if (ret == OK)
+ {
+ /* 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 to the required, default values for
+ * use with the 32.768 KHz LSE clock:
+ */
+
+ putreg32(((uint32_t)0xff << RTC_PRER_PREDIV_S_SHIFT) |
+ ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT),
+ STM32_RTC_PRER);
+
+ /* 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 int rtc_resume(void)
+{
+#ifdef CONFIG_RTC_ALARM
+ uint32_t regval;
+#endif
+ int ret;
+
+ /* Wait for the RTC Time and Date registers to be syncrhonized with RTC APB
+ * clock.
+ */
+
+ ret = rtc_synchwait();
+
+ /* Clear the RTC alarm flags */
+
+#ifdef CONFIG_RTC_ALARM
+ 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
+ return ret;
+}
+
+/************************************************************************************
+ * 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.
+ *
+ ************************************************************************************/
+
+#if CONFIG_RTC_ALARM
+static int rtc_interrupt(int irq, void *context)
+{
+#warning "Missing logic"
+ return OK;
+}
+#endif
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: up_rtcinitialize
+ *
+ * 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_rtcinitialize(void)
+{
+ uint32_t regval;
+ int ret;
+
+ rtc_dumpregs("On reset");
+
+ /* 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 access to the backup domain (RTC registers, RTC backup data registers
+ * and backup SRAM).
+ */
+
+ stm32_pwr_enablebkp();
+
+ /* 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.
+ */
+
+ regval = getreg32(STM32_RTC_BK0R);
+ if (regval != RTC_MAGIC)
+ {
+ /* Perform the one-time setup of the LSE clocking to the RTC */
+
+ ret = rtc_setup();
+
+ /* Remember that the RTC is initialized */
+
+ putreg32(RTC_MAGIC, STM32_RTC_BK0R);
+ }
+ else
+ {
+ /* RTC already set-up, just resume normal operation */
+
+ ret = rtc_resume();
+ }
+
+ /* 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, rtc_interrupt);
+ up_enable_irq(STM32_IRQ_RTC);
+#endif
+
+ g_rtc_enabled = true;
+ rtc_dumpregs("After Initialzation");
+ 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
+ * intialization 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 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);
+ 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.
+ *
+ * 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;
+
+ 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 tr;
+ uint32_t dr;
+ int ret;
+
+ /* 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 */
+
+ /* 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(newtime.tm_sec) << RTC_TR_SU_SHIFT) |
+ (rtc_bin2bcd(newtime.tm_min) << RTC_TR_MNU_SHIFT) |
+ (rtc_bin2bcd(newtime.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.
+ *
+ * Issue: I am not sure what the STM32 years mean. Are these the
+ * years 2000-2099? I'll assume so.
+ */
+
+ dr = (rtc_bin2bcd(newtime.tm_mday) << RTC_DR_DU_SHIFT) |
+ ((rtc_bin2bcd(newtime.tm_mon + 1)) << RTC_DR_MU_SHIFT) |
+ ((rtc_bin2bcd(newtime.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_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 up_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback);
+{
+ irqstate_t flags;
+ 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/nuttx/arch/arm/src/stm32/stm32f40xxx_dma.c b/nuttx/arch/arm/src/stm32/stm32f40xxx_dma.c
new file mode 100644
index 000000000..dcbbf1856
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32f40xxx_dma.c
@@ -0,0 +1,904 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32f40xxx_dma.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "os_internal.h"
+#include "chip.h"
+#include "stm32_dma.h"
+#include "stm32_internal.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) */
+ 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(4),
+ },
+ {
+ .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(OSERR_INTERNAL);
+ }
+
+ /* 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);
+
+ /* Set the interrrupt priority */
+
+ up_prioritize_irq(dmast->irq, CONFIG_DMA_PRI);
+ }
+}
+
+/****************************************************************************
+ * 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 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);
+
+ /* "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_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 = irqsave();
+ 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);
+ irqrestore(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/nuttx/arch/arm/src/stm32/stm32f40xxx_rcc.c b/nuttx/arch/arm/src/stm32/stm32f40xxx_rcc.c
new file mode 100644
index 000000000..45980f288
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32f40xxx_rcc.c
@@ -0,0 +1,668 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32f40xxx_rcc.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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"
+
+/****************************************************************************
+ * 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_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|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);
+
+ /* Set the PLL dividers and multiplers 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 */
+
+ regval = (FLASH_ACR_LATENCY_5 | FLASH_ACR_ICEN | FLASH_ACR_DCEN);
+ 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);
+ }
+}
+#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/nuttx/arch/arm/src/stm32/stm32f40xxx_rtc.c b/nuttx/arch/arm/src/stm32/stm32f40xxx_rtc.c
new file mode 100644
index 000000000..c11748ae5
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32f40xxx_rtc.c
@@ -0,0 +1,842 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32f40xxx_rtc.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/rtc.h>
+
+#include <time.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "up_arch.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
+
+/* Constants ************************************************************************/
+
+#define SYNCHRO_TIMEOUT (0x00020000)
+#define INITMODE_TIMEOUT (0x00010000)
+#define RTC_MAGIC (0xfacefeed)
+#define RTC_PREDIV_S (0xff)
+#define RTC_PREDIV_A (0x7f)
+
+/* 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));
+ rtclldbg(" CALIBR: %08x\n", getreg32(STM32_RTC_CALIBR));
+ 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(" BK0: %08x\n", getreg32(STM32_RTC_BK0R));
+}
+#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)
+{
+ /* 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 reactivates the write protection.
+ */
+
+ putreg32(0xca, STM32_RTC_WPR);
+ putreg32(0x53, STM32_RTC_WPR);
+}
+
+/************************************************************************************
+ * Name: rtc_wprunlock
+ *
+ * Description:
+ * Enable RTC write protection
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ************************************************************************************/
+
+static inline void rtc_wprlock(void)
+{
+ /* Writing any wrong key reactivates the write protection. */
+
+ putreg32(0xff, STM32_RTC_WPR);
+}
+
+/************************************************************************************
+ * 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;
+
+ /* Enable the External Low-Speed (LSE) Oscillator setup the LSE as the RTC clock\
+ * source, and enable the RTC.
+ */
+
+ stm32_rcc_enablelse();
+
+ /* Wait for the RTC Time and Date registers to be synchronized with RTC APB
+ * clock.
+ */
+
+ ret = rtc_synchwait();
+ if (ret == OK)
+ {
+ /* 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 to the required, default values for
+ * use with the 32.768 KHz LSE clock:
+ */
+
+ putreg32(((uint32_t)0xff << RTC_PRER_PREDIV_S_SHIFT) |
+ ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT),
+ STM32_RTC_PRER);
+
+ /* 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 int rtc_resume(void)
+{
+#ifdef CONFIG_RTC_ALARM
+ uint32_t regval;
+#endif
+ int ret;
+
+ /* Wait for the RTC Time and Date registers to be syncrhonized with RTC APB
+ * clock.
+ */
+
+ ret = rtc_synchwait();
+
+ /* Clear the RTC alarm flags */
+
+#ifdef CONFIG_RTC_ALARM
+ 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
+ return ret;
+}
+
+/************************************************************************************
+ * 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.
+ *
+ ************************************************************************************/
+
+#if CONFIG_RTC_ALARM
+static int rtc_interrupt(int irq, void *context)
+{
+#warning "Missing logic"
+ return OK;
+}
+#endif
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: up_rtcinitialize
+ *
+ * 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_rtcinitialize(void)
+{
+ uint32_t regval;
+ int ret;
+
+ rtc_dumpregs("On reset");
+
+ /* 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 access to the backup domain (RTC registers, RTC backup data registers
+ * and backup SRAM).
+ */
+
+ stm32_pwr_enablebkp();
+
+ /* 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.
+ */
+
+ regval = getreg32(STM32_RTC_BK0R);
+ if (regval != RTC_MAGIC)
+ {
+ /* Perform the one-time setup of the LSE clocking to the RTC */
+
+ ret = rtc_setup();
+
+ /* Remember that the RTC is initialized */
+
+ putreg32(RTC_MAGIC, STM32_RTC_BK0R);
+ }
+ else
+ {
+ /* RTC already set-up, just resume normal operation */
+
+ ret = rtc_resume();
+ }
+
+ /* 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: 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
+ * intialization 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 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);
+ 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.
+ *
+ * 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;
+
+ 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 tr;
+ uint32_t dr;
+ int ret;
+
+ /* 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 */
+
+ /* 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(newtime.tm_sec) << RTC_TR_SU_SHIFT) |
+ (rtc_bin2bcd(newtime.tm_min) << RTC_TR_MNU_SHIFT) |
+ (rtc_bin2bcd(newtime.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.
+ *
+ * Issue: I am not sure what the STM32 years mean. Are these the
+ * years 2000-2099? I'll assume so.
+ */
+
+ dr = (rtc_bin2bcd(newtime.tm_mday) << RTC_DR_DU_SHIFT) |
+ ((rtc_bin2bcd(newtime.tm_mon + 1)) << RTC_DR_MU_SHIFT) |
+ ((rtc_bin2bcd(newtime.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_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 up_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback)
+{
+ irqstate_t flags;
+ 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/nuttx/arch/arm/src/str71x/Kconfig b/nuttx/arch/arm/src/str71x/Kconfig
new file mode 100644
index 000000000..0e9c87d54
--- /dev/null
+++ b/nuttx/arch/arm/src/str71x/Kconfig
@@ -0,0 +1,6 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+comment "STR71x Configuration Options"
diff --git a/nuttx/arch/arm/src/str71x/Make.defs b/nuttx/arch/arm/src/str71x/Make.defs
new file mode 100644
index 000000000..545ce1735
--- /dev/null
+++ b/nuttx/arch/arm/src/str71x/Make.defs
@@ -0,0 +1,60 @@
+##############################################################################
+# arch/arm/src/str71x/Make.defs
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (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_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
+ up_createstack.c up_dataabort.c up_mdelay.c up_udelay.c \
+ up_exit.c up_idle.c up_initialize.c up_initialstate.c \
+ up_interruptcontext.c up_prefetchabort.c up_releasepending.c \
+ up_releasestack.c up_reprioritizertr.c up_syscall.c up_unblocktask.c \
+ up_undefinedinsn.c up_usestack.c up_lowputs.c
+
+ifneq ($(CONFIG_DISABLE_SIGNALS),y)
+CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c
+endif
+
+CHIP_ASRCS =
+CHIP_CSRCS = str71x_prccu.c str71x_lowputc.c str71x_decodeirq.c str71x_irq.c \
+ str71x_timerisr.c str71x_serial.c
+
+ifeq ($(CONFIG_USBDEV),y)
+CHIP_CSRCS += str71x_usbdev.c
+endif
+ifeq ($(CONFIG_STR71X_XTI),y)
+CHIP_CSRCS += str71x_xti.c
+endif
+
diff --git a/nuttx/arch/arm/src/str71x/chip.h b/nuttx/arch/arm/src/str71x/chip.h
new file mode 100644
index 000000000..af1da9ea8
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#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/nuttx/arch/arm/src/str71x/str71x_adc12.h b/nuttx/arch/arm/src/str71x/str71x_adc12.h
new file mode 100644
index 000000000..1b982e0b1
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_apb.h b/nuttx/arch/arm/src/str71x/str71x_apb.h
new file mode 100644
index 000000000..5ceee8ec9
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_bspi.h b/nuttx/arch/arm/src/str71x/str71x_bspi.h
new file mode 100644
index 000000000..f876ebb2b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_can.h b/nuttx/arch/arm/src/str71x/str71x_can.h
new file mode 100644
index 000000000..a891b60dc
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_decodeirq.c b/nuttx/arch/arm/src/str71x/str71x_decodeirq.c
new file mode 100644
index 000000000..326abd763
--- /dev/null
+++ b/nuttx/arch/arm/src/str71x/str71x_decodeirq.c
@@ -0,0 +1,147 @@
+/********************************************************************************
+ * arch/arm/src/str71x/str71x_decodeirq.c
+ *
+ * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+/********************************************************************************
+ * Pre-procesor Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Types
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Funstions
+ ********************************************************************************/
+
+/********************************************************************************
+ * up_decodeirq()
+ *
+ * Description:
+ * Read the IRQ number from the IVR register. During intialization, 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
+ up_ledon(LED_INIRQ);
+ lib_lowprintf("Unexpected IRQ\n");
+ current_regs = regs;
+ PANIC(OSERR_ERREXCEPTION);
+#else
+ unsigned int irq;
+
+ /* Read the IRQ number from the IVR register (Could probably get the same
+ * info from CIC register without the setup).
+ */
+
+ up_ledon(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;
+
+ /* Mask and acknowledge the interrupt */
+
+ up_maskack_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;
+
+ /* Unmask the last interrupt (global interrupts are still disabled) */
+
+ up_enable_irq(irq);
+ }
+#if CONFIG_DEBUG
+ else
+ {
+ PANIC(OSERR_ERREXCEPTION); /* Normally never happens */
+ }
+#endif
+ up_ledoff(LED_INIRQ);
+#endif
+}
diff --git a/nuttx/arch/arm/src/str71x/str71x_eic.h b/nuttx/arch/arm/src/str71x/str71x_eic.h
new file mode 100644
index 000000000..c45cfaa6b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include <arch/irq.h>
+
+/************************************************************************************
+ * Pre-procesor 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 interrrupt 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/nuttx/arch/arm/src/str71x/str71x_emi.h b/nuttx/arch/arm/src/str71x/str71x_emi.h
new file mode 100644
index 000000000..ade4d1145
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_flash.h b/nuttx/arch/arm/src/str71x/str71x_flash.h
new file mode 100644
index 000000000..9b45fa3e9
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_gpio.h b/nuttx/arch/arm/src/str71x/str71x_gpio.h
new file mode 100644
index 000000000..16b325613
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_head.S b/nuttx/arch/arm/src/str71x/str71x_head.S
new file mode 100644
index 000000000..e83affa37
--- /dev/null
+++ b/nuttx/arch/arm/src/str71x/str71x_head.S
@@ -0,0 +1,629 @@
+/*****************************************************************************
+ * arch/arm/src/str71x/str71x_head.S
+ *
+ * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h> /* NuttX configuration settings */
+#include <arch/board/board.h> /* Board-specific settings */
+
+#include "arm.h" /* ARM-specific settings */
+#include "chip.h" /* Chip-specific settings */
+#include "up_internal.h"
+#include "up_arch.h"
+
+/*****************************************************************************
+ * 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 up_ledinit /* 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
+ * intialized.
+ */
+
+ 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 up_ledinit
+#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_heapbase
+ * 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_heapbase and is
+ * exported from here only because of its coupling to LCO
+ * above.
+ */
+
+ .data
+ .align 4
+ .globl g_heapbase
+ .type g_heapbase, object
+g_heapbase:
+ .long _ebss+CONFIG_IDLETHREAD_STACKSIZE
+ .size g_heapbase, .-g_heapbase
+
+ .end
+
diff --git a/nuttx/arch/arm/src/str71x/str71x_i2c.h b/nuttx/arch/arm/src/str71x/str71x_i2c.h
new file mode 100644
index 000000000..759c75e7e
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_internal.h b/nuttx/arch/arm/src/str71x/str71x_internal.h
new file mode 100644
index 000000000..6e60a671c
--- /dev/null
+++ b/nuttx/arch/arm/src/str71x/str71x_internal.h
@@ -0,0 +1,156 @@
+/************************************************************************************
+ * arch/arm/src/str71x/str71x_internal.h
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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_INTERNAL_H
+#define __ARCH_ARM_SRC_STR71X_STR71X_INTERNAL_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+
+#include <arch/board/board.h>
+
+/************************************************************************************
+ * Pre-procesor 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
+extern 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
+extern 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
+extern 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
+extern void str71x_disable_xtiirq(int irq);
+#else
+# define str71x_disable_xtiirq(irq)
+#endif /* CONFIG_STR71X_XTI */
+
+#endif /* __ARCH_ARM_SRC_STR71X_STR71X_INTERNAL_H */
diff --git a/nuttx/arch/arm/src/str71x/str71x_irq.c b/nuttx/arch/arm/src/str71x/str71x_irq.c
new file mode 100644
index 000000000..3bf870668
--- /dev/null
+++ b/nuttx/arch/arm/src/str71x/str71x_irq.c
@@ -0,0 +1,232 @@
+/****************************************************************************
+ * arch/arm/src/st71x/st71x_irq.c
+ *
+ * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <errno.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+
+#include "arm.h"
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+#include "str71x_internal.h"
+
+/****************************************************************************
+ * Pre-procesor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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
+ irqrestore(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_maskack_irq
+ *
+ * Description:
+ * Mask the IRQ and acknowledge it. No XTI support.. only used in
+ * interrupt handling logic.
+ *
+ ****************************************************************************/
+
+void up_maskack_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);
+
+ /* 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 interrrupts.
+ *
+ ****************************************************************************/
+
+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;
+}
+
diff --git a/nuttx/arch/arm/src/str71x/str71x_lowputc.c b/nuttx/arch/arm/src/str71x/str71x_lowputc.c
new file mode 100644
index 000000000..fde33adb4
--- /dev/null
+++ b/nuttx/arch/arm/src/str71x/str71x_lowputc.c
@@ -0,0 +1,319 @@
+/**************************************************************************
+ * arch/arm/src/str71x/str71x_lowputc.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+#include <stdint.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "str71x_internal.h"
+
+/**************************************************************************
+ * Pre-procesor 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}
+ */
+
+#if 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
+
+#if 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
+
+#if 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
+
+#if 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
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * 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 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)
+ */
+
+#if 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/nuttx/arch/arm/src/str71x/str71x_map.h b/nuttx/arch/arm/src/str71x/str71x_map.h
new file mode 100644
index 000000000..e61be9e3e
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_pcu.h b/nuttx/arch/arm/src/str71x/str71x_pcu.h
new file mode 100644
index 000000000..5e23204f0
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_prccu.c b/nuttx/arch/arm/src/str71x/str71x_prccu.c
new file mode 100644
index 000000000..5379b1164
--- /dev/null
+++ b/nuttx/arch/arm/src/str71x/str71x_prccu.c
@@ -0,0 +1,473 @@
+/********************************************************************************
+ * arch/arm/src/str71x/str71x_prccu.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "str71x_internal.h"
+
+/********************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_rccu.h b/nuttx/arch/arm/src/str71x/str71x_rccu.h
new file mode 100644
index 000000000..ed3114c2c
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_rtc.h b/nuttx/arch/arm/src/str71x/str71x_rtc.h
new file mode 100644
index 000000000..554123ff6
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_serial.c b/nuttx/arch/arm/src/str71x/str71x_serial.c
new file mode 100644
index 000000000..d9e9cc348
--- /dev/null
+++ b/nuttx/arch/arm/src/str71x/str71x_serial.c
@@ -0,0 +1,1049 @@
+/****************************************************************************
+ * arch/arm/src/str71x/str71x_serial.c
+ *
+ * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <arch/serial.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+#include "os_internal.h"
+
+#include "str71x_internal.h"
+
+/****************************************************************************
+ * Pre-procesor 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 CONFIG_STR71X_UART1
+# define TTYS1_DEV g_uart1port /* UART1 is tty1 */
+# if CONFIG_STR71X_UART2
+# define TTYS2_DEV g_uart2port /* UART2 is tty2 */
+# if CONFIG_STR71X_UART3
+# define TTYS3_DEV g_uart3port /* UART3 is tty3 */
+# endif
+# elif 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 CONFIG_STR71X_UART3
+# define TTYS2_DEV g_uart3port /* UART3 is tty2 */
+# endif
+# elif 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 CONFIG_STR71X_UART3
+# define TTYS3_DEV g_uart3port /* UART3 is tty3 */
+# endif
+# elif 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 CONFIG_STR71X_UART3
+# define TTYS2_DEV g_uart3port /* UART3 is tty2 */
+# endif
+# elif 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 CONFIG_STR71X_UART1
+# define TTYS2_DEV g_uart1port /* UART1 is tty2 */
+# if CONFIG_STR71X_UART3
+# define TTYS3_DEV g_uart3port /* UART3 is tty3 */
+# endif
+# elif CONFIG_STR71X_UART3
+# define TTYS2_DEV g_uart3port /* UART3 is tty2 */
+# endif
+# elif CONFIG_STR71X_UART1
+# define TTYS1_DEV g_uart1port /* UART1 is tty1 */
+# if CONFIG_STR71X_UART3
+# define TTYS2_DEV g_uart3port /* UART3 is tty2 */
+# endif
+# elif 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 CONFIG_STR71X_UART1
+# define TTYS2_DEV g_uart1port /* UART1 is tty2 */
+# if CONFIG_STR71X_UART2
+# define TTYS3_DEV g_uart2port /* UART2 is tty3 */
+# endif
+# elif CONFIG_STR71X_UART2
+# define TTYS2_DEV g_uart2port /* UART2 is tty2 */
+# endif
+# elif CONFIG_STR71X_UART1
+# define TTYS1_DEV g_uart1port /* UART1 is tty1 */
+# if CONFIG_STR71X_UART2
+# define TTYS2_DEV g_uart2port /* UART2 is tty2 */
+# endif
+# elif 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 Variables
+ ****************************************************************************/
+
+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,
+ .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);
+
+ /* Set the uart interrupt priority (the default value is one) */
+
+ up_prioritize_irq(priv->irq, CONFIG_UART_PRI);
+ }
+ 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(OSERR_INTERNAL);
+ }
+
+ 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)
+{
+ struct inode *inode = filep->f_inode;
+ struct uart_dev_s *dev = inode->i_private;
+ int ret = OK;
+
+ switch (cmd)
+ {
+ 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;
+
+ 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/nuttx/arch/arm/src/str71x/str71x_timer.h b/nuttx/arch/arm/src/str71x/str71x_timer.h
new file mode 100644
index 000000000..7712009c2
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_timerisr.c b/nuttx/arch/arm/src/str71x/str71x_timerisr.c
new file mode 100644
index 000000000..e55e1f21a
--- /dev/null
+++ b/nuttx/arch/arm/src/str71x/str71x_timerisr.c
@@ -0,0 +1,213 @@
+/****************************************************************************
+ * arch/arm/src/str71x/str71x_timerisr.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <time.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "clock_internal.h"
+#include "up_internal.h"
+
+#include "str71x_internal.h"
+
+/****************************************************************************
+ * Pre-procesor 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global 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_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize
+ * the timer interrupt.
+ *
+ ****************************************************************************/
+
+void up_timerinit(void)
+{
+ irqstate_t flags;
+
+ /* Make sure that timer0 is disabled */
+
+ flags = irqsave();
+ 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);
+
+ /* Set the timer interrupt priority */
+
+ up_prioritize_irq(STR71X_IRQ_SYSTIMER, CONFIG_TIM_PRI);
+
+ /* 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);
+ irqrestore(flags);
+}
diff --git a/nuttx/arch/arm/src/str71x/str71x_uart.h b/nuttx/arch/arm/src/str71x/str71x_uart.h
new file mode 100644
index 000000000..3073e0053
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_usb.h b/nuttx/arch/arm/src/str71x/str71x_usb.h
new file mode 100644
index 000000000..24ddd8a6b
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_wdog.h b/nuttx/arch/arm/src/str71x/str71x_wdog.h
new file mode 100644
index 000000000..81caf6a25
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_xti.c b/nuttx/arch/arm/src/str71x/str71x_xti.c
new file mode 100644
index 000000000..3ef0a803d
--- /dev/null
+++ b/nuttx/arch/arm/src/str71x/str71x_xti.c
@@ -0,0 +1,321 @@
+/********************************************************************************
+ * arch/arm/src/str71x/str71x_xti.c
+ *
+ * Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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/config.h>
+
+#include <stdint.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+#include "str71x_internal.h"
+
+#ifdef CONFIG_STR71X_XTI
+
+/********************************************************************************
+ * Pre-procesor 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/nuttx/arch/arm/src/str71x/str71x_xti.h b/nuttx/arch/arm/src/str71x/str71x_xti.h
new file mode 100644
index 000000000..638ab4f87
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <nuttx/config.h>
+
+#include "str71x_map.h"
+
+/************************************************************************************
+ * Pre-procesor 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 */