Merge branch 'master' of bitbucket.org:AVyhovanec/nuttx
This commit is contained in:
commit
872adef2dc
384
ChangeLog
384
ChangeLog
@ -3130,7 +3130,7 @@
|
||||
point numbers.
|
||||
* lib/stdio/lib_libdtoa.c and lib_libvsprintf.c: Correct some floating
|
||||
point options.
|
||||
* arch/arm/lpc43xx/lpc32_usb0dev.c: Add framework for development of
|
||||
* arch/arm/lpc43xx/lpc43_usb0dev.c: Add framework for development of
|
||||
an USB0, device-side driver for the LPC43XX. The initial check-in,
|
||||
however, is simply for the LPC31xx driver with name changes. The
|
||||
LPC31xx has the same USB IP, but will require some additional initialization
|
||||
@ -4440,7 +4440,7 @@
|
||||
* binfmt/binfmt_execmodule.c: Here is a place where I forget
|
||||
to update the call to sched_releasetcb() to pass the thread
|
||||
type as the second parameter (2013-03-23).
|
||||
* arch/arm/src/lm, kinetis, lpc32, and nuc1xx: Add kernel build
|
||||
* arch/arm/src/lm, kinetis, lpc43, and nuc1xx: Add kernel build
|
||||
support to all ARMv7-M and ARMv6-M chips. There are no
|
||||
configurations in place to to verify these additions!
|
||||
(2013-03-24).
|
||||
@ -10964,7 +10964,7 @@
|
||||
(2015-09-09).
|
||||
* configs/nucleo-f303re: Support for the STMicro Nucleo F303RE board
|
||||
from Paul Alexander Patience (2015-09-10).
|
||||
* arch/arm/src/lpc43xx/lpc32_ehci.c and .h: LPC43xx EHCI driver from
|
||||
* arch/arm/src/lpc43xx/lpc43_ehci.c and .h: LPC43xx EHCI driver from
|
||||
Ilya Averyanov (2015-09-10).
|
||||
* ARMv7-M, all "lazy" interrupt stack logic. Assembly instruction
|
||||
that fetches the saved value is incorrect; replace with more
|
||||
@ -12348,7 +12348,7 @@
|
||||
adds DEBUGASSERT for invalid geometry and additional memory debug
|
||||
logic. Also fixes the dangling pointer on error bug. From Ken
|
||||
Pettit (2016-07-14).
|
||||
* arch/arm/src/lpc32xx: Extend LPC43xx EMC code to support SDRAM on a
|
||||
* arch/arm/src/lpc43xx: Extend LPC43xx EMC code to support SDRAM on a
|
||||
dynamic memory interface. From Vytautas Lukenskas (2016-07-19).
|
||||
* arch/sim/src: Add the simulated QSPI (N25Q) flash to the simulation
|
||||
and modify sim up_spiflash.c to enable it to run with different MTD
|
||||
@ -12772,6 +12772,9 @@
|
||||
* STM32 DMA2D: fix an error in up_dma2dcreatelayer where an invalid
|
||||
pointer was returned when a certain underlying function failed. From
|
||||
Jens Gräf (2016-10-07).
|
||||
|
||||
7.19 2016-12-26 Gregory Nutt <gnutt@nuttx.org>
|
||||
|
||||
* include/nuttx/fs/nxffs.h: Needs forward reference to struct mtd_dev_s
|
||||
and needs to include stdbool.h (2016-10-09).
|
||||
* STM32F103 Minimum: Note in Kconfig that the board supports buttons.
|
||||
@ -12844,16 +12847,16 @@
|
||||
(2016-10-19).
|
||||
* libc/locale: Allows c++ code to compile with or without
|
||||
CONFIG_LIBC_LOCALE and will generate a link error if CONFIG_LIBC_LOCALE
|
||||
is not defined and setlocale is referneced. With CONFIG_LIBC_LOCALE
|
||||
is not defined and setlocale is referenced. With CONFIG_LIBC_LOCALE
|
||||
defined setlocale will act as if MB string is not supported and return
|
||||
"C" for POSIX. C and "". From David Sidrane (2016-10-19).
|
||||
* Add vectors for interrupt levels 2-6 (2016-10-20).
|
||||
* strtof: Add strtof() as simply a copy of strtod with types and
|
||||
* Xtensa ESP32: Add vectors for interrupt levels 2-6 (2016-10-20).
|
||||
* strtof(): Add strtof() as simply a copy of strtod with types and
|
||||
limits changed (2016-10-20).
|
||||
* arch/arm/src/stm32v7: Register the watchdog device at the configured
|
||||
device path CONFIG_WATCHDOG_DEVPATH vs. hard-coded /dev/wdt. From Frank
|
||||
Benkert (2016-10-21).
|
||||
* configs/*/defdonf The buttons example was changed to archbuttons. As
|
||||
* configs/*/defconfig: The buttons example was changed to archbuttons. As
|
||||
a result all of the button configurations are broken and need some
|
||||
renaming in the defconfig files. Noted by Frank Berkert (2016-10-21).
|
||||
* configs/stm32f103-minimum: Add support to PWM on STM32F103-Minimum
|
||||
@ -12909,7 +12912,7 @@
|
||||
found in the F4. From David Sidrane (2016-10-26).
|
||||
* arch/arm/src/stm32f7: stm32f76xx77xx_pinmap.h Missed one. From
|
||||
David Sidrane (2016-10-26).
|
||||
* LPC32xx serial: Fix a typo in ioctl TIOCSRS485 ioctl. From Vytautas
|
||||
* LPC43xx serial: Fix a typo in ioctl TIOCSRS485 ioctl. From Vytautas
|
||||
Lukenskas (2016-10-27).
|
||||
* sched/clock: Correct clock initialization. The correct range for
|
||||
the month is 0-11 but is entered as 1-12 in the .config file
|
||||
@ -12919,7 +12922,7 @@
|
||||
* sched/Kconfig: Add ranges to START_YEAR, MONTH, and DAY (2016-10-28).
|
||||
* configs/nucleo-f303re: Add STM32 F303RE hello configuration; remove
|
||||
duplicate setting from board.h. From Marc Rechté (2016-10-18).
|
||||
* arch/arm/src/lpc32xx: Restore RS485 mode on serial port open (if
|
||||
* arch/arm/src/lpc43xx: Restore RS485 mode on serial port open (if
|
||||
RS485 is enabled via menuconfig). From Vytautas Lukenskas (2016-10-28).
|
||||
* arch/arm/src/stm32f7: otgdev fixed typo. From David Sidrane
|
||||
(2016-10-28).
|
||||
@ -12949,14 +12952,12 @@
|
||||
From Paul A. Patience (2016-11-02).
|
||||
* drivers/ and drivers/spi: Fix Kconfig warning. This commit moves the
|
||||
ARCH_HAVE_SPI options outside the check for SPI. Those options don't
|
||||
depend on SPI, and Kconfig files in arch/ enable them even if SPI isn't
|
||||
enabled.
|
||||
|
||||
Sourcing the driver's Kconfig in drivers/Kconfig only if support for
|
||||
the driver is enabled prevents us from defining these ARCH_HAVE options
|
||||
in the driver's Kconfig. We should probably remove the other checks in
|
||||
drivers/Kconfig and check if the drivers are enabled only in their
|
||||
Kconfig. From Paul A. Patience (2016-11-02).
|
||||
depend on SPI, and Kconfig files in arch/ enable them even if SPI
|
||||
isn't enabled. Source the driver's Kconfig in drivers/Kconfig only
|
||||
if support for the driver is enabled prevents us from defining these
|
||||
ARCH_HAVE options in the driver's Kconfig. We should probably remove
|
||||
the other checks in drivers/Kconfig and check if the drivers are
|
||||
enabled only in their Kconfig. From Paul A. Patience (2016-11-02).
|
||||
* Move protoypes for the non-standard include/semaphore.h file to the
|
||||
non-standard include/nuttx/semaphore.h with the other non-standard
|
||||
semaphore interfaces (2016-11-02).
|
||||
@ -13100,7 +13101,7 @@
|
||||
argument so that there can be additional usage. From Sebastien Lorquet
|
||||
(2016-11-17).
|
||||
* All timer lower half drivers. Port Sebastien's changes to all all
|
||||
other implementations of the timer lower half. Very many just and
|
||||
other implementations of the timer lower half. Many changes and
|
||||
untested. Expect some problems. (2016-11-17).
|
||||
* sched/irq: irq_csection() has a bad assumption in the SMP case. It
|
||||
assumed that the state of certain variables. That was true on entry
|
||||
@ -13130,5 +13131,348 @@
|
||||
So this change adds locking (via enter_critical section) to wdog
|
||||
expiration logic for the the case if the SMP configuration
|
||||
(2016-11-18).
|
||||
* SAM3/4: Add delay between setting and clearing the endpoint RESET bit
|
||||
in sam_ep_resume(). We need to add a delay between setting and
|
||||
clearing the endpoint reset bit in SAM_UDP_RSTEP. Without the delay the
|
||||
USB controller will (may?) not reset the endpoint. If the endpoint is
|
||||
not being reset, the Data Toggle (DTGLE) bit will not to be cleared
|
||||
which will cause the next transaction to fail if DTGLE is 1. If that
|
||||
happens the host will time-out and reset the bus. Adding this delay
|
||||
may also fix the USBMSC_STALL_RACEWAR in usbmsc_scsi.c, however this
|
||||
has not been verified yet. From Wolfgang Reißnegger (2016-11-18).
|
||||
* SAM3/4: Remove unused 'halted' flag in UDP driver. From Wolfgang
|
||||
Reißnegger (2016-11-18).
|
||||
* SAM3/4: Remove 'stalled' flag in UDP driver. The flag is not necessary.
|
||||
The state of the endpoint can be determined using 'epstate' instead.
|
||||
From Wolfgang Reißnegger (2016-11-18).
|
||||
* USBMSC: Fix length of mode6 sense reply packet. From Wolfgang
|
||||
Reißnegger (2016-11-18).
|
||||
* configs/dk-tm4c129x: Typo fix. From Wolfgang Reißnegger (2016-11-18).
|
||||
* Typo fix in sam_udp.c. From Wolfgang Reißnegger (2016-11-18).
|
||||
* STM32: STM32F303xB and STM32F303xC chips have 4 ADCs. From Paul A.
|
||||
Patience (2016-11-19).
|
||||
* vfork(): Fix a race condition in the SMP case. Existing logic
|
||||
depended on the fact that the child would not run until waitpid was
|
||||
called because the child had the same priority as the parent. BUT
|
||||
in the SMP case that is not true... the child may run immediately on
|
||||
a different CPU (2016-11-19).
|
||||
* arch/: Add option to use low-priority work queue to all Ethernet
|
||||
drivers in arch that support CONFIG_NET_NOINTS (2016-11-19).
|
||||
* sched/clock: Correct calculation for the case of Tickless mode with
|
||||
a 32-bit timer. In that case, the calculation was returning
|
||||
millisecond accuracy. That is not good when the timer accuracy is < 1
|
||||
msec. From Rajan Gill (2016-11-19).
|
||||
* sched/task: task_restart() test not supported on SMP systems. This is
|
||||
not fully implemented (2016-11-19).
|
||||
* This commit adds a new internal interfaces and fixes a problem with
|
||||
three APIs in the SMP configuration. The new internal interface is
|
||||
sched_cpu_pause(tcb). This function will pause a CPU if the task
|
||||
associated with 'tcb' is running on that CPU. This allows a different
|
||||
CPU to modify that OS data stuctures associated with the CPU. When the
|
||||
other CPU is resumed, those modifications can safely take place. The
|
||||
three fixes are to handle cases in the SMP configuration where one CPU
|
||||
does need to make modifications to TCB and data structures on a task
|
||||
that could be running running on another CPU. Those three cases are
|
||||
task_delete(), task_restart(), and execution of signal handles. In
|
||||
all three cases the solutions is basically the same: (1) Call
|
||||
sched_cpu_pause(tcb) to pause the CPU on which the task is running,
|
||||
(2) perform the necessary operations, then (3) call up_cpu_resume() to
|
||||
restart the paused CPU (2016-11-20).
|
||||
* task_restart: Make sure new task starts with pre-emption disabled and
|
||||
not in a critical section (2016-11-21).
|
||||
* Fix a typo in a spinlock macro (2016-11-21).
|
||||
* Spinlocks: Added capability to provide architecture-specific memory
|
||||
barriers. This was for i.MX6 but does not help with the SMP problems.
|
||||
It is still a good feature (2016-11-21).
|
||||
* Remove a assertion condition that appears to rarely cause false-alarm
|
||||
assertions. Teported by Petteri Aimonen (2016-11-21).
|
||||
* The examples/qencoder app was trying to init the encoder by a direct
|
||||
call into the board, cheating in a local header to declare the normally
|
||||
unavailable function prototype. From Sebastien Lorquet (2016-11-22).
|
||||
* configs: All QE encoder files. Last change made timer hard-coded to 3.
|
||||
Make configurable (2016-11-22).
|
||||
* configs: Remove all traces of the no-longer existent ARCHBUTTONS
|
||||
example. Remove all button configurations that depended on the
|
||||
obsoleted ARCHBUTTON example (2016-11-22).
|
||||
* nucleo-l476rg: Add better selection of timer (2016-11-22).
|
||||
* implementation of dumpgpio for stm32l4, was required for pwm debug.
|
||||
From Sebastien Lorquet (2016-11-22).
|
||||
* SMP: Add logic to avoid a deadlock condition when CPU1 is hung waiting
|
||||
for g_cpu_irqlock and CPU0 is waitin for g_cpu_paused (2016-11-22).
|
||||
* Misoc: Add timer driver. From Ramtin Amin (2016-11-22).
|
||||
* Misoc: Add commits and warnings about missing caculation of the timer
|
||||
reload value (2016-11-22).
|
||||
* SAM3/4: Name of method is now setcallback, not sethandler (2016-11-22).
|
||||
* sam4s-xplained-pro/nsh: Configuration uses old, improper timer interface.
|
||||
CONFIG_TIMER disabled in configuration. (2016-11-22).
|
||||
* sam4s-xplained-pro: Remove obsolete timer initialization logic
|
||||
(2016-11-22).
|
||||
* Misoc LM32: Make system timer configurable via CONFIG_USEC_PER_TICK.
|
||||
From Ramtin Amin (2016-11-23).
|
||||
* LPC43xx: Add timer driver; configs/bambino-200e: Add support for timer
|
||||
driver. From Alan Carvalho de Assis (2016-11-23).
|
||||
* SMP: Fix backward condition in test (2016-11-23).
|
||||
* ARMv7-A SMP: Add a little logic to signal handling (2016-11-24).
|
||||
* Misoc LM32: Add signal handling logic. From Ramtin Amin (2016-11-24).
|
||||
* SMP: Add spin_trylock(). Use this in conditions where other CPUs need
|
||||
to stopped but we cannot call enter_critical_section (2016-11-24).
|
||||
* Fix for F1 RTC Clock, tested on F103. From Maciej Wójcik (2016-11-25).
|
||||
* SMP: Fix yet another potential deadlock (2016-11-25).
|
||||
* Enable CONFIG_RTC in the hymini-stm32v/nsh2 (kitchensink) config.
|
||||
From Maciej Wójcik (2016-11-26).
|
||||
* This adds support for keeping i.MX6 inter-processor communication data
|
||||
in a non-cached address region (2016-11-26).
|
||||
* i.MX6: Disable non-cached region support. Add SCU register definitions
|
||||
(2016-11-26).
|
||||
* i.MX6: Add some controls to enable SMP cache coherency in SMP mode
|
||||
(2016-11-26).
|
||||
* ARMv7-A: Fix some SCU SMP logic (2016-11-26).
|
||||
* ARMv7-A/i.MX6: Modify handling of the SMP cache coherency
|
||||
configuration so that it is identical to the steps from the TRM.
|
||||
Makes no differenct, however (2016-11-27).
|
||||
* The Smoothie project needs to compile C++ inside config/boardname/src/
|
||||
to use with High Priority Interruption, then I modified the board
|
||||
configs Makefile to support it. It works fine for the first time
|
||||
compilation, but if we execute "touch config/boardname/src/Pin.cxx"
|
||||
and execute "make" it will not detect that Pin.cxx was modified. I
|
||||
think there is some other place I should modify, but I didn't find
|
||||
it. From Alan Carvalho de Assis (2016-11-27).
|
||||
* ARMv7-A/i.MX6 SMP: Move SMP coherent cache setup to earlier in
|
||||
initialization of CPUn, n>0 (2016-11-27).
|
||||
* ARMv7 GIC: SGIs are non-maskable but go through the same path as other,
|
||||
maskable interrupts. Added logic to serialize SGI processing when
|
||||
necessary (2016-11-27).
|
||||
* sched_note: Extend OS instrumentation to include some SMP events
|
||||
(2016-11-27).
|
||||
* sched_note: Add spinlock instrumentation; In SMP configurations,
|
||||
select to log only notes from certain CPUs (2016-11-28).
|
||||
* Misoc LM3: Add Misoc Ethernet driver. Integrate network support into
|
||||
configs/misoc/hello. Remove configs/misoc/include/generated directory.
|
||||
I suppose the the intent now is that this is a symbolic link? DANGER!
|
||||
This means that you cannot compile this code with first generating
|
||||
these files a providing a symbolic link to this location! From Ramtin
|
||||
Amin (2016-11-28).
|
||||
* Add tools/showsize.sh (2016-11-28).
|
||||
* configs/misoc: Add a sample directory containing generated sources.
|
||||
This is really only useful for performing test builds. You really
|
||||
must generate the Misoc architecture for a real-life build. From
|
||||
Ramtin Amin (2016-11-28).
|
||||
* sched_note: Permit spinlock and critical section notes in in-memory
|
||||
buffer iff sched_not_get() interfaces is disabled (2016-11-28).
|
||||
* STM32 DAC: Fix shift value whenever there are is a DAC2 and, hence,
|
||||
up to three interfaces. From Marc Rechté (2016-11-29).
|
||||
* Back out a debug change that was included in commit (2016-11-29).
|
||||
* i.MX6: Don't output the alphabet if CONFIG_DEBUG_FEATURES is not set
|
||||
(2016-11-29).
|
||||
* Misoc LM32: Add logic to flush/invalidate caches. From Ramtin Amin
|
||||
(2016-11-29).
|
||||
* drivers/net/: Adapt all Ethernet drivers to work as though
|
||||
CONFIG_NET_MULTIBUFFER were set. Remove all references to
|
||||
CONFIG_NET_MULTIBUFFER (2016-11-29).
|
||||
* stm32_otghshost: if STM32F446 increase number of channels to 16. From
|
||||
Janne Rosberg (2016-11-30).
|
||||
* usbhost_composite: fix end offset in usbhost_copyinterface(). From
|
||||
Janne Rosberg (2016-11-30).
|
||||
* usbhost_cdcacm: add CDC_SUBCLASS_ACM and CDC_PROTO_ATM to supported
|
||||
class and proto. From Janne Rosberg (2016-11-30).
|
||||
* LPC43 SD/MMC: Correct some git definitions on SMMC control register
|
||||
in lpc43_sdmmc.h. From Alan Carvalho de Assis (2016-11-30).
|
||||
* STM32L4: Correct USART1/2 definitions. Use default mbed UART4
|
||||
settings. From Sebastien Lorquet (2016-12-01).
|
||||
* boardctl: Add new boardctl() command ,BOARDIOC_NX_START, to start the
|
||||
NX server as a kernel thread (2016-12-01).
|
||||
* GPDMA driver for the LPC43xx. The GPDMA block is basically the same
|
||||
as the LPC17xx. Only the clock configuration is different and LPC43xx
|
||||
has four different DMA request sources, where LPC17xx has only two.
|
||||
From Alan Carvalho de Assis (2016-12-01).
|
||||
* Remove RGMP and RGMP drivers (2016-12-02).
|
||||
* i.MX6: Add an untested SPI driver taken directly from the i.MX1 port
|
||||
(2016-12-02).
|
||||
* Eliminate CONFIG_NO_NOINTS. There is no longer any support for
|
||||
interrupt level processing of the network stack. Lots of files changed
|
||||
-> lots of testing needed (2016-12-03).
|
||||
* Fix DEBUGASSERT() in group_signal.c. From Masayuki Ishikawa
|
||||
(2016-12-04).
|
||||
* Add support for the SAM5CMP-DB board. From Masayuki Ishikawa
|
||||
(2016-12-04).
|
||||
* SAM3/4: Add SMP support for the dual-core SAM4CM. From Masayuki
|
||||
Ishikawa (2016-12-04).
|
||||
* C Library: Allow option to enable IP address conversions even when the
|
||||
IP address family is not supported (2016-12-04).
|
||||
* SSD1306: Fix errors in SPI mode configuration. From Gong Darcy
|
||||
(2016-12-04).
|
||||
* SAMA5 does not build when executing from SDRAM before board
|
||||
frequencies are not constant. Rather, the bootloader configures the
|
||||
clocking and we must derive the clocking from the MCK left by the
|
||||
bootloader. This means lots more computations. This is untested on
|
||||
initial commit because I don't have a good PWM test setup right now
|
||||
(2016-12-04).
|
||||
* Olimex-LPC1766-STK: Enable procfs in NSH configuration. Automount
|
||||
/proc on startup (2016-12-05).
|
||||
* SAM4CMP-DB: Add hooks to auto-mount the procfs file system on startup
|
||||
in board bring-up logic (2016-12-05).
|
||||
* Remove all references to BOARDIOC_PWMSETUP and board_pwm_setup()
|
||||
(2016-12-05).
|
||||
* Remove all references to BOARDIOC_ADCSETUP and board_adc_setup()
|
||||
(2016-12-05).
|
||||
* Added Timers 2-5 and control of SAI and I2S PLLs. From David Sidrane
|
||||
(2016-12-05).
|
||||
* Added support for stmf469 SAI and I2S PLL configuration and STM446
|
||||
fixes. From David Sidrane (2016-12-05).
|
||||
* Expanded otgfs support to stm32F469 and stm32f446. Added missing bits
|
||||
definitions, Used stm32F469 and stm32f446 bit definitions, Removed
|
||||
unsed header file. From David Sidrane (2016-12-05).
|
||||
* Remove BOARDIOC_CAN_INITIALIZE. CAN initialization is now done in the
|
||||
board initialization logic just like every other device driver
|
||||
(2016-12-06).
|
||||
* STM32F7: Allow the config to override the clock edge setting. From
|
||||
David Sidrane (2016-12-06).
|
||||
* For Cortex-A9, should also set ACTLR.FW in SMP mode to enble TLB and
|
||||
cache broadcasts. Does not fix SMP cache problem (2016-12-07).
|
||||
* sched notes: Add additional note to see if/when CPU is started in SMP
|
||||
mode (2016-12-07).
|
||||
* EFM32: Fix a compilation error. From Pierre-noel Bouteville
|
||||
(2016-12-07).
|
||||
* pthreads: Add pthread_cleanup_push() and pthread_cleanup_pop()
|
||||
(2016-12-08).
|
||||
* BUGFIX:STM32F427 was rebooting. Over reached family. From David
|
||||
Sidrane (2016-12-08).
|
||||
* Add pthread_setcanceltype() and pthread_testcancel() (2016-12-09).
|
||||
* Added STM32F469 RAM size and deliberated STM32F446 size. From David
|
||||
Sidrane (2016-12-09).
|
||||
* Typo in stm32f76xx77xx_pinmap.h edited online with Bitbucket. From
|
||||
David Sidrane (2016-12-09).
|
||||
* stm32_allocateheap.c edited online with Bitbucket. From David Sidrane
|
||||
(2016-12-09).
|
||||
* LPC43xx SD card: Correct pin configuration options needed for SD card
|
||||
pins. From Alan Carvalho de Assis (2016-12-09).
|
||||
* pthread_mutex_destroy(): Fix an error in destroying a mutex which can
|
||||
occur after a pthread has been canceled while holding the mutex
|
||||
(2016-12-09).
|
||||
* Add support for cancellation points (2016-12-09).
|
||||
* Forgot to add some files in the last commit (2016-12-10).
|
||||
* Correct some default font IDs. From Pierre-Noel Bouteville
|
||||
(2016-12-10).
|
||||
* task_delete() now obeys all cancellation point semantics (2016-12-10).
|
||||
* Add task_setcancelstate(), task_setcanceltype(), and task_testcancel().
|
||||
These are non-standard interfaces analogous to the correponding pthread_
|
||||
interfaces that provide cancellation controls for tasks (2016-12-10).
|
||||
* i.MX6 interrupt handling: Additional logic needed to handle nested
|
||||
interrupts when an interrupt stack is used (2016-12-13).
|
||||
* SAMV7 MCAN: Prevent Interrupt-Flooding of ACKE when not connected to
|
||||
CAN-BUS. An Acknowledge-Error will occur every time no other CAN Node
|
||||
acknowledges the message sent. This will also occur if the device is
|
||||
not connected to the can-bus. The CAN-Standard declares, that the Chip
|
||||
has to retry a given message as long as it is not sent successfully (or
|
||||
it is not cancelled by the application). Every time the chip tries to
|
||||
resend the message an Acknowledge-Error-Interrupt is generated. At high
|
||||
baud rates this can lead in extremely high CPU load just for handling
|
||||
the interrupts (and possibly the error handling in the application). To
|
||||
prevent this Interrupt-Flooding we disable the ACKE once it is seen as
|
||||
long we didn't transfer at least one message successfully. From Frank
|
||||
Benkert (2016-12-13).
|
||||
* i.MX6: Remove non-cached, inter-cpu memory region. Not a useful
|
||||
concept (2016-12-13).
|
||||
* minnsh Configurations: Remove minnsh configurations and support logic:
|
||||
up_getc() and lowinstream. This was an interesting exercise to see
|
||||
just how small you could get NuttX, but otherwise it was not useful:
|
||||
(1) the NSH code violated the OS interface layer by callup up_getc and
|
||||
up_putc directly, and (2) while waiting for character input, NSH would
|
||||
call up_getc() which would hog all of the CPU. Not a reasonable
|
||||
solution other than as a proof of concept (2016-12-13).
|
||||
* Calypso Boards: Remove all Calypso board configurations (2016-12-13).
|
||||
* Calypso: Remove Calypso architecture support and support for Calypso
|
||||
SERCOMM driver (2016-12-13).
|
||||
* ESP32 core v2: Two changes (1) flushes the UART TX buffer in the esp32
|
||||
serial shutdown routine. The ROM bootloader does not flush the FIFO
|
||||
before handing over to user code, so some of this output is not
|
||||
currently seen when the UART is reconfigured in early stages of
|
||||
startup. And changes the openocd config file's default flash voltage
|
||||
from 1.8V to 3.3V. This is not necessary right now, but may save some
|
||||
hard-to-debug moments down the track (3.3V-only flash running at 1.8V
|
||||
often half-works and does weird things...). From Angus Gratton
|
||||
(2016-12-14).
|
||||
* Xtensa ESP32: Add missing ENTRY() and RET() macros in C callable
|
||||
assembly language. At one time I though the that the ESP32 support the
|
||||
CALL0 ABI. I was mistaken so there may be a few more like this
|
||||
(2016-12-14).
|
||||
* Xtensa ESP32: Fix a couple of bugs associated with handling of CPU
|
||||
interrupts (2016-12-14).
|
||||
* Xtensa ESP32: Fix several build-related issues associated with vector
|
||||
section (2016-12-15).
|
||||
* Xtensa ESP32: Fix missing CALL0 ABI condition (2016-12-15).
|
||||
* Xtensa EPS32: Make sure that all C callable assembly functions includes
|
||||
ENTRY prologue and RET epilogue (2016-12-15).
|
||||
* Xtensa ESP32: Fix windowspill register handling + Use r6, not r2 when
|
||||
passing paramters with call4 (2016-12-16).
|
||||
* Xtensa ESP32: Use r6, not r2 when passing paramters with call4
|
||||
(2016-12-16).
|
||||
* Xtensa ESP32: Correct a logic problem the prevented dumping the IDLE
|
||||
thread's stack on an assertion (2016-12-16).
|
||||
* Xtensa ESP32: Fix some missing SMP logic (2016-12-16).
|
||||
* Xtensa ESP32: Basically a redesign of the interrupt dispatch logic
|
||||
(2016-12-16).
|
||||
* Xtensa ESP32: Level 1 interrupts should return via RFE (2016-12-17).
|
||||
* Xtensa ESP32: One register getting clobber on context save (2016-12-17).
|
||||
* STM32 F7: Fix some STM32F7 copy paste errors. From David Sidrane
|
||||
(2016-12-17).
|
||||
* CDC/ACM Device Class: uart_ops_s portion of cdcacm will not be
|
||||
initalized with correct functions if CONFIG_SERIAL_DMA is lit
|
||||
(2016-12-17).
|
||||
* Xtensa ESP32: Using wrong register to disable interrupts (2016-12-17).
|
||||
* Xtensa ESP32: Fix clobbered a9 in co-processor context save/restore
|
||||
(2016-12-17).
|
||||
* Xtensa ESP32: Need to clone some logic for synchronous context switch.
|
||||
Window spill logic in the conmon restores logic is inappropriate in
|
||||
this context (2016-12-17).
|
||||
* sscanf(): Add scansets to the scanf function. Enabled
|
||||
CONFIG_LIBC_SCANSET option. From Aleksandr Vyhovanec (2016-12-17).
|
||||
* Xtensa ESP32: Fix context save logic when called in window ABI
|
||||
configuration. Add an IDLE stack. Don't depend on the mystery stack
|
||||
received from the bootloader (2016-12-18).
|
||||
* Xtensa ESP32: Need to spill registers to memory as the last dying
|
||||
action before switching to a new thread (2016-12-18).
|
||||
* ESP32 Serial: Add logic to prevent infinite loops in interrupt handler
|
||||
(2016-12-18).
|
||||
* Xtensa ESP32: Automatically mount /proc at start-up (2016-12-19).
|
||||
* Xtensa ESP32: Corrects timer initialization and timer input frequency
|
||||
(2016-12-19).
|
||||
* Tiva PWM: Support PWM_PULSECOUNT feature for TI tiva. From Young.Mu
|
||||
(2016-12-20).
|
||||
* Xtensa ESP32: Missing prologue/epilogue macros on C callable function
|
||||
(2016-12-20).
|
||||
* Xtensa ESP32: Update APP CPU startup logic to match current Expressif
|
||||
example code. Fix errors APP CPU startup (2016-12-20).
|
||||
* fs/procfs: Fix procfs status for SMP case (2016-12-20).
|
||||
* Xtensa ESP32: Clock frequency is different if running from IRAM or is
|
||||
booting from FLASH. This is a booltloader issue (2016-12-20).
|
||||
* Xtensa ESP32: Basic port is function in both single CPU and dual CPU
|
||||
SMP configurations. There is an NSH configuration for each CPU
|
||||
configuration (2016-12-21).
|
||||
* STM32 F4: Merge in support for the Olimex STM32 P407 board (2016-12-21).
|
||||
* Xtensa ESP32: Add an OS test to verify the port (2016-12-22).
|
||||
* Xtensa ESP32: Corrects a problem with dispatching to signal handlers:
|
||||
Cannot vector directly to the signal handling function as in other ABIs
|
||||
under the Xtensa Window ABI. In that case, we need to go through a
|
||||
tiny hook when performs the correct window call (call4) otherwise
|
||||
registers will be scrambled in the signal handler (2016-12-22).
|
||||
* SAMV7 CAN: Make delete_filter functions more robust. From Frank
|
||||
Benkert (2016-12-23).
|
||||
* Xtensa ESP32: Add stack checking logic (2016-12-23).
|
||||
* sched note: record ID enumeration now results on constant values; ID
|
||||
values do not change with configuration. This makes writing
|
||||
post-processing software much easier (2016-12-24).
|
||||
* STM32 F3: Forgot to update chip.h for STM32F303x[BC]'s 4 ADCs
|
||||
(2016-12-24).
|
||||
* STM32 F4: Allow dma in 1 bit mode in STM32F4xxx. From David Sidrane
|
||||
(2016-12-24).
|
||||
* termios.h: Fix CRTSCTS define to include input and output flow.
|
||||
From Lorenz Meier (2016-12-26).
|
||||
* SMP: Enforce this rule: Tasks which are normally restored when
|
||||
sched_unlock() is called must remain pending (1) if we are in a
|
||||
critical section, i.e., g_cpu_irqlock is locked , or (2) other CPUs
|
||||
still have pre-emption disabled, i.e., g_cpu_schedlock is locked. In
|
||||
those cases, the release of the pending tasks must be deferred until
|
||||
those conditions are met (2016-12-26).
|
||||
|
||||
7.19 2016-xx-xx Gregory Nutt <gnutt@nuttx.org>
|
||||
7.20 2017-xx-xx Gregory Nutt <gnutt@nuttx.org>
|
||||
|
@ -8,7 +8,7 @@
|
||||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
||||
<p>Last Updated: October 8, 2016</p>
|
||||
<p>Last Updated: December 26, 2016</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -317,7 +317,7 @@
|
||||
<td><br></td>
|
||||
<td>
|
||||
<p>
|
||||
<li>POSIX/ANSI-like task controls, named message queues, counting semaphores, clocks/timers, signals, pthreads, environment variables, filesystem.</li>
|
||||
<li>POSIX/ANSI-like task controls, named message queues, counting semaphores, clocks/timers, signals, pthreads, cancellation points, environment variables, filesystem.</li>
|
||||
</p>
|
||||
</tr>
|
||||
|
||||
@ -1339,11 +1339,11 @@
|
||||
<h2>Released Versions</h2>
|
||||
<p>
|
||||
In addition to the ever-changing GIT repository, there are frozen released versions of NuttX available.
|
||||
The current release is NuttX 7.18.
|
||||
NuttX 7.18 is the 118<sup>th</sup> release of NuttX.
|
||||
It was released on October 8, 2016, and is available for download from the
|
||||
The current release is NuttX 7.19.
|
||||
NuttX 7.19 is the 119<sup>th</sup> release of NuttX.
|
||||
It was released on December 26, 2016, and is available for download from the
|
||||
<a href="https://bitbucket.org/nuttx/nuttx/downloads/">Bitbucket.org</a> website.
|
||||
Note that the release consists of two tarballs: <code>nuttx-7.18.tar.gz</code> and <code>apps-7.18.tar.gz</code>.
|
||||
Note that the release consists of two tarballs: <code>nuttx-7.19.tar.gz</code> and <code>apps-7.19.tar.gz</code>.
|
||||
Both may be needed (see the top-level <code>nuttx/README.txt</code> file for build information).
|
||||
</p>
|
||||
|
||||
@ -1352,7 +1352,7 @@
|
||||
<ul>
|
||||
<li><b>nuttx</b>.
|
||||
<ul><p>
|
||||
Release notes for NuttX 7.18 are available <a href="https://bitbucket.org/nuttx/nuttx/downloads/">here</a>.
|
||||
Release notes for NuttX 7.19 are available <a href="https://bitbucket.org/nuttx/nuttx/downloads/">here</a>.
|
||||
Release notes for all released versions on NuttX are available in the <a href="https://bitbucket.org/nuttx/nuttx/src/master/ReleaseNotes" target="_blank">Bitbucket GIT</a>.
|
||||
The ChangeLog for all releases of NuttX is available in the ChangeLog file that can viewed in the <a href="https://bitbucket.org/nuttx/nuttx/src/master/ChangeLog" target="_blank">Bitbucket GIT</a>.
|
||||
The ChangeLog for the current release is at the bottom of that file.
|
||||
@ -1360,7 +1360,7 @@
|
||||
</li></ul>
|
||||
<li><b>apps</b>.
|
||||
<ul><p>
|
||||
Release notes for NuttX 7.18 are available <a href="https://bitbucket.org/nuttx/apps/downloads/">here</a>.
|
||||
Release notes for NuttX 7.19 are available <a href="https://bitbucket.org/nuttx/apps/downloads/">here</a>.
|
||||
Release notes for all released versions on NuttX are available in the <a href="https://bitbucket.org/nuttx/nuttx/src/master/ReleaseNotes" target="_blank">Bitbucket GIT</a>
|
||||
The ChangeLog for the all releases of <code>apps/</code> is available in the ChangeLog file that can viewed in the <a href="https://bitbucket.org/nuttx/apps/src/master/ChangeLog.txt" target="_blank">Bitbucket GIT</a>.
|
||||
The ChangeLog for the current release is at the bottom of that file.
|
||||
@ -1408,7 +1408,7 @@
|
||||
<li><a href="#linuxusermode">Linux/Cygwin user mode simulation</a> (1)</li>
|
||||
<li>ARM
|
||||
<ul>
|
||||
<li><a href="#arm7tdmi">ARM7TDMI</b></a> (5)</li>
|
||||
<li><a href="#arm7tdmi">ARM7TDMI</b></a> (4)</li>
|
||||
<li><a href="#arm920t">ARM920T</a> (1)</li>
|
||||
<li><a href="#arm926ejs">ARM926EJS</a> (4)</li>
|
||||
<li><a href="#armv4">Other ARMv4</a> (1)</li>
|
||||
@ -1418,7 +1418,7 @@
|
||||
<li><a href="#armcortexr4">ARM Cortex-R4</a> (1)</li>
|
||||
<li><a href="#armcortexm0">ARM Cortex-M0/M0+</a> (7)</li>
|
||||
<li><a href="#armcortexm3">ARM Cortex-M3</a> (35)</li>
|
||||
<li><a href="#armcortexm4">ARM Cortex-M4</a> (31)</li>
|
||||
<li><a href="#armcortexm4">ARM Cortex-M4</a> (32)</li>
|
||||
<li><a href="#armcortexm7">ARM Cortex-M7</a> (7)</li>
|
||||
</ul>
|
||||
<li>Atmel AVR
|
||||
@ -1445,6 +1445,10 @@
|
||||
<li><a href="#pic32mzmips">PIC32MZ</a> (MIPS M14K) (1)</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Misoc
|
||||
<ul>
|
||||
<li><a href="#misoclm32">LM32</a> (1)</li>
|
||||
</ul>
|
||||
<li>Renesas/Hitachi:
|
||||
<ul>
|
||||
<li><a href="#superh">Renesas/Hitachi SuperH</a> (1/2)</li>
|
||||
@ -1453,6 +1457,15 @@
|
||||
</li>
|
||||
</td>
|
||||
<td bgcolor="#e4e4e4" valign="top" width="33%">
|
||||
<li><a href="#riscv">RISC-V</a> (1)
|
||||
<ul>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Xtensa LX6:
|
||||
<ul>
|
||||
<li><a href="#esp32">ESP32</a> (1)</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>ZiLOG
|
||||
<ul>
|
||||
<li><a href="#zilogz16f">ZiLOG ZNEO Z16F</a> (2)</li>
|
||||
@ -1502,6 +1515,11 @@
|
||||
<li><a href="#at91sama5d4">Atmel SAMA5D4</a> <small>(ARM Cortex-A5)</small></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Expressif
|
||||
<ul>
|
||||
<li><a href="#esp32">ESP32</a> <small>(Dual Xtensa LX6)</small</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Freescale
|
||||
<ul>
|
||||
<li><a href="#m68hcs12">M68HCS12</a></li>
|
||||
@ -1533,13 +1551,13 @@
|
||||
<li><a href="#pic32mzec">PIC32MZEC Family</a> <small>(MIPS32 M14K)</small></li>
|
||||
</ul>
|
||||
</li>
|
||||
</td>
|
||||
<td bgcolor="#e4e4e4" valign="top" width="33%">
|
||||
<li>Moxa
|
||||
<ul>
|
||||
<li><a href="#moxart">Moxa NP51x0</a> <small>(ARMv4)</small></li>
|
||||
</ul>
|
||||
</li>
|
||||
</td>
|
||||
<td bgcolor="#e4e4e4" valign="top" width="33%">
|
||||
<li>nuvoTon
|
||||
<ul>
|
||||
<li><a href="#nuvotonnu120">nuvoTon NUC120</a> <small>(ARM Cortex-M0)</small></li>
|
||||
@ -1604,7 +1622,6 @@
|
||||
<li>Texas Instruments (some formerly Luminary)
|
||||
<ul>
|
||||
<li><a href="#tms320c5471">TI TMS320-C5471</a> <small>(ARM7TDMI)</small></li>
|
||||
<li><a href="#ticalypso">TI Calypso</a> <small>(ARM7TDMI)</small></li>
|
||||
<li><a href="#titms320dm320">TI TMS320-DM320</a> <small>(ARM9E6JS)</small></li>
|
||||
<li><a href="#tilms6432">TI/Stellaris LM3S6432</a> <small>(ARM Cortex-M3)</small></li>
|
||||
<li><a href="#tilm3s6432s2e">TI/Stellaris LM3S6432S2E</a> <small>(ARM Cortex-M3)</small></li>
|
||||
@ -1695,31 +1712,6 @@
|
||||
<td><br></td>
|
||||
<td><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><br></td>
|
||||
<td>
|
||||
<p>
|
||||
<a name="ticalypso"><b>TI Calypso</b>.</a>
|
||||
This port supports the TI "Calypso" MCU used in various cell phones (and, in particular,
|
||||
by the <a href="http://bb.osmocom.org/trac/">Osmocom-bb project</a>).
|
||||
Like the c5471, NuttX operates on the ARM7 of this dual core processor.
|
||||
Board support is available for the Motorola C139, C155 and W220 phones and for the Pirelli DP-L10 phone.
|
||||
</p>
|
||||
<ul>
|
||||
<p>
|
||||
<b>STATUS:</b>
|
||||
This port was contributed by Denis Carilki and includes the work of Denis Carikli, Alan Carvalho de Assis, and Stefan Richter.
|
||||
Calypso support first appeared in NuttX-6.17 with LCD drivers.
|
||||
Support for the Calypso keyboard was added in NuttX-6.24 by Denis Carilki.
|
||||
Refer to the NuttX board README files for the <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/compal_e88/README.txt" target="_blank">Compal E88</a>, <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/compal_e99/README.txt" target="_blank">Compal E99</a> and <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/pirelli_dpl10/README.txt" target="_blank">Pirelli DP-L10</a> phones for further information.
|
||||
</p>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><br></td>
|
||||
<td><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><br></td>
|
||||
<td>
|
||||
@ -3160,7 +3152,7 @@ nsh>
|
||||
<li>
|
||||
<p>
|
||||
<b>Kamami STM32 Butterfly 2</b>
|
||||
Support for the <a href="https://kamami.pl/zestawy-uruchomieniowe-stm32/178507-stm32butterfly2.html">Kamami STM32 Butterfly 2</a> was contributed by Michał Łyszczek in NuttX-7/18. That port features the STMicro STM32F107VC MCU.
|
||||
Support for the <a href="https://kamami.pl/zestawy-uruchomieniowe-stm32/178507-stm32butterfly2.html">Kamami STM32 Butterfly 2</a> was contributed by Michał Łyszczek in NuttX-7.18. That port features the STMicro STM32F107VC MCU.
|
||||
</p>
|
||||
<p>
|
||||
<b>STATUS:</b>
|
||||
@ -3743,11 +3735,14 @@ nsh>
|
||||
<li><b>NuttX-7.3</b>
|
||||
Support for the Olimex STM32 H405 board was added in NuttX-7.3.
|
||||
</li>
|
||||
<li>
|
||||
Refer to the NuttX board <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/stm3240g-eval/README.txt" target="_blank">README</a> file for further information.
|
||||
<li><b>NuttX-7.19</b>
|
||||
Support for the Olimex STM32 P405 board was added in NuttX-7.19.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
Refer to the STM3240G-EVAL board <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/stm3240g-eval/README.txt" target="_blank">README</a> file for further information.
|
||||
</p>
|
||||
<p>
|
||||
<b>STMicro STM32F4-Discovery</b>.
|
||||
This port uses the STMicro STM32F4-Discovery board featuring the STM32F407VGT6 MCU.
|
||||
@ -3817,6 +3812,11 @@ nsh>
|
||||
Networking configurations were added in NuttX-7.18.
|
||||
See the NuttX board <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/olimex-stm32-e407/README.txt" target="_blank">README</a> file for further information about the NuttX port.
|
||||
</p>
|
||||
<p>
|
||||
<b>Olimex STM32 P407</b>.
|
||||
Support for the Olimex STM32 P407 development board appeared in NuttX-7.19.
|
||||
See the NuttX board <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/olimex-stm32-p407/README.txt" target="_blank">README</a> file for further information about the NuttX port.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -4332,7 +4332,7 @@ Mem: 29232 5920 23312 23312
|
||||
<td><br></td>
|
||||
<td>
|
||||
<p>
|
||||
<a name="at91sam4c"><b>Atmel SAM4C</b>.</a>
|
||||
<a name="at91sam4c"><b>Atmel SAM4CM</b>.</a>
|
||||
General architectural support was provided for SAM4CM family in NuttX 7.3
|
||||
This was <i>architecture-only</i> support, meaning that support for the boards with these chips is available, but no support for any publicly available boards was included.
|
||||
The SAM4CM port should be compatible with most of the SAM3/4 drivers (like HSMCI, DMAC, etc.) but those have not be verified on hardware as of this writing.
|
||||
@ -4340,6 +4340,18 @@ Mem: 29232 5920 23312 23312
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><br></td>
|
||||
<td>
|
||||
<p>
|
||||
<b>Atmel SAM4CMP-DB</b>.
|
||||
Support for the SAM4CMP-DB board was contributed to NuttX by Masayuki Ishikawa in NuttX-7.19.
|
||||
The SAM4CM is a dual-CPU part and SMP was included for the ARMv7-M and SAM3/4 families.
|
||||
The SAM4CMP-DB board support includes an NSH configuration that operates in an SMP configuration.
|
||||
Refer to the NuttX board <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/sam4cmp-db/README.txt" target="_blank">README</a> file for further information.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><br></td>
|
||||
<td><hr></td>
|
||||
@ -4856,6 +4868,23 @@ Mem: 29232 5920 23312 23312
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><img height="20" width="20" src="favicon.ico"></td>
|
||||
<td bgcolor="#5eaee1">
|
||||
<a name="misoclm32"><b>Misoc LM32</b>.</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><br></td>
|
||||
<td>
|
||||
<p>
|
||||
<b>Misoc LM32 Architectural Support</b>.
|
||||
Architectural support for the Misoc LM32 was contributed by Ramtin Amin in NuttX 7.19. Driver support is basic in this initial release: Serial, Timer, and Ethernet. "Board" support is a available for developing with Misoc LM32 under Qemu or on your custom FPGA.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><img height="20" width="20" src="favicon.ico"></td>
|
||||
<td bgcolor="#5eaee1">
|
||||
@ -5222,6 +5251,53 @@ BFD_ASSERT (*plt_offset != (bfd_vma) -1);
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td valign="top"><img height="20" width="20" src="favicon.ico"></td>
|
||||
<td bgcolor="#5eaee1">
|
||||
<a name="riscv"><b>RISC-V</b>.</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><br></td>
|
||||
<td>
|
||||
<p>
|
||||
<b>RISC-V Architectural Support</b>.
|
||||
Basic support for the RISC-V architecture was contributed by Ken Pettit in NuttX-7.19. The initial release is <i>thin</i> but a great starting point for anyone interested in RISC-V development with NuttX.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><img height="20" width="20" src="favicon.ico"></td>
|
||||
<td bgcolor="#5eaee1">
|
||||
<a name="esp32"><b>ESP32 <small>(Dual Xtensa LX6)</small></b>.</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><br></td>
|
||||
<td>
|
||||
<p>
|
||||
<b>Xtensa LX6 ESP32 Architectural Support</b>.
|
||||
Basic architectural support for Xtensa LX6 processors and the port for the Expressif ESP32 were added in NuttX-7.19.
|
||||
The basic ESP32 port is function in both single CPU and dual CPU SMP configurations.
|
||||
</p>
|
||||
<p>
|
||||
<b>Expressif ESP32 Core v2 Board</b>
|
||||
The NuttX release includes support for Expressif ESP32 Core v2 board.
|
||||
There is an NSH configuration for each CPU configuration and an OS test configuration for verificatin of the port.
|
||||
</p>
|
||||
<p>
|
||||
<b>STATUS</b>.
|
||||
ESP32 support in NuttX-7.19 is functional, but very preliminary.
|
||||
There is little yet in the way of device driver support.
|
||||
Outstanding issues include missing clock configuration logic, missing partition tables to support correct configuration from FLASH, and some serial driver pin configuration issues.
|
||||
The configuration is usable despite these limitations.
|
||||
Refer to the NuttX board <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/esp32-core/README.txt" target="_blank">README</a> file for further information.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><img height="20" width="20" src="favicon.ico"></td>
|
||||
<td bgcolor="#5eaee1">
|
||||
|
@ -1008,10 +1008,6 @@ drivers/
|
||||
| |-- Kconfig
|
||||
| |-- Make.defs
|
||||
| `-- <i>(Common sensor driver source files)</i>
|
||||
|-- sercomm/
|
||||
| |-- Kconfig
|
||||
| |-- Make.defs
|
||||
| `-- <i>(Files for the Calypso SERCOMM driver)</i>
|
||||
|-- serial/
|
||||
| |-- Kconfig
|
||||
| |-- Make.defs
|
||||
@ -1170,8 +1166,6 @@ include/
|
||||
| | `-- <i>(Power management header files)</i>
|
||||
| |-sensors/
|
||||
| | `-- <i>(Sensor device driver header files)</i>
|
||||
| |-sercomm/
|
||||
| | `-- <i>(SERCOMM driver header files)</i>
|
||||
| |-serial/
|
||||
| | `-- <i>(Serial driver header files)</i>
|
||||
| |-spi/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@
|
||||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX README Files</i></font></big></h1>
|
||||
<p>Last Updated: December 4, 2016</p>
|
||||
<p>Last Updated: December 21, 2016</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -70,12 +70,6 @@ nuttx/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/cc3200-launchpad/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- cloudctrl/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/cloudctrl/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- compal_e86/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/compal_e86/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- compal_e88/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/compal_e88/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- compal_e99/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/compal_e99/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- demo9s12ne64/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/demo9s12ne64/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- dk-tm4c129x/
|
||||
@ -183,6 +177,8 @@ nuttx/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/olimex-stm32-p107/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- olimex-stm32-p207/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/olimex-stm32-p207/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- olimex-stm32-p407/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/olimex-stm32-p407/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- olimex-strp711/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/olimex-strp711/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- open1788/
|
||||
@ -199,8 +195,6 @@ nuttx/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/pic32mx7mmb/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- pic32mz-starterkit/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/pic32mz-starterkit/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- pirelli_dpl10/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/pirelli_dpl10/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- qemu-i486/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/qemu-i486/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- sabre-6quad/
|
||||
@ -328,8 +322,6 @@ nuttx/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/drivers/mtd/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- sensors/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/drivers/sensors/README.txt" target="_blank">README.txt</a>
|
||||
| |- sercomm/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/drivers/sercomm/README.txt" target="_blank">README.txt</a>
|
||||
| |- syslog/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/drivers/syslog/README.txt" target="_blank">README.txt</a>
|
||||
| `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/drivers/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
|
12
README.txt
12
README.txt
@ -1287,12 +1287,6 @@ nuttx/
|
||||
| | `- README.txt
|
||||
| |- cloudctrl
|
||||
| | `- README.txt
|
||||
| |- compal_e86
|
||||
| | `- README.txt
|
||||
| |- compal_e88
|
||||
| | `- README.txt
|
||||
| |- compal_e99
|
||||
| | `- README.txt
|
||||
| |- demo0s12ne64/
|
||||
| | `- README.txt
|
||||
| |- dk-tm4c129x/
|
||||
@ -1399,6 +1393,8 @@ nuttx/
|
||||
| | `- README.txt
|
||||
| |- olimex-stm32-p207/
|
||||
| | `- README.txt
|
||||
| |- olimex-stm32-p407/
|
||||
| | `- README.txt
|
||||
| |- olimex-strp711/
|
||||
| | `- README.txt
|
||||
| |- open1788/
|
||||
@ -1415,8 +1411,6 @@ nuttx/
|
||||
| | `- README.txt
|
||||
| |- pic32mz-starterkit/
|
||||
| | `- README.txt
|
||||
| |- pirelli_dpl10/
|
||||
| | `- README.txt
|
||||
| |- qemu-i486/
|
||||
| | `- README.txt
|
||||
| |- sabre-6quad/
|
||||
@ -1544,8 +1538,6 @@ nuttx/
|
||||
| | `- README.txt
|
||||
| |- sensors/
|
||||
| | `- README.txt
|
||||
| |- sercomm/
|
||||
| | `- README.txt
|
||||
| |- syslog/
|
||||
| | `- README.txt
|
||||
| `- README.txt
|
||||
|
791
ReleaseNotes
791
ReleaseNotes
@ -12294,3 +12294,794 @@ detailed bugfix information):
|
||||
|
||||
- apps/examples/oneshot: If the requested delay is > max_delay, then
|
||||
break the delay up into several pieces.
|
||||
|
||||
NuttX-7.19 Release Notes
|
||||
------------------------
|
||||
|
||||
The 119th release of NuttX, Version 7.19, was made on December 26, 2016,
|
||||
and is available for download from the Bitbucket.org website. Note
|
||||
that release consists of two tarballs: nuttx-7.19.tar.gz and
|
||||
apps-7.19.tar.gz. These are available from:
|
||||
|
||||
https://bitbucket.org/nuttx/nuttx/downloads
|
||||
https://bitbucket.org/nuttx/apps/downloads
|
||||
|
||||
Both may be needed (see the top-level nuttx/README.txt file for build
|
||||
information).
|
||||
|
||||
Additional new features and extended functionality:
|
||||
|
||||
* Core OS:
|
||||
|
||||
- sched/semaphore, sched/phread/, libc/semaphore, libc/pthread: Add
|
||||
pthread_mutexattr_get/set_protocol and non-standard
|
||||
sem_get/set_protocol. These may use to enable or disable priority
|
||||
inheritance on a single semaphore.
|
||||
- Spinlocks: Added capability to provide architecture-specific memory
|
||||
barriers.
|
||||
- SMP: Add spin_trylock(). Use this in conditions where other CPUs need
|
||||
to stopped but we cannot call enter_critical_section().
|
||||
- sched note: Extend OS instrumentation to include some SMP events.
|
||||
Also add spinlock instrumentation; In SMP configurations, add a
|
||||
filter mask to log only notes from certain CPUs.
|
||||
- sched note: Permit spinlock and critical section notes in in-memory
|
||||
buffer iff sched_not_get() interfaces is disabled.
|
||||
- sched note: Add additional note to see if/when CPU is started in SMP
|
||||
mode.
|
||||
- sched note: Record ID enumeration now results on constant values; ID
|
||||
values do not change with configuration. This makes writing post-processing software much easier.
|
||||
- boardctl: Add new boardctl() command, BOARDIOC_NX_START, to start the
|
||||
NX server as a kernel thread.
|
||||
- pthreads: Add pthread_cleanup_push() and pthread_cleanup_pop().
|
||||
- pthreads: Added pthread_setcanceltype() and pthread_testcancel().
|
||||
- pthreads: Add support for cancellation points.
|
||||
- task_delete() now obeys all cancellation point semantics.
|
||||
- Add task_setcancelstate(), task_setcanceltype(), and
|
||||
task_testcancel(). These are non-standard interfaces analogous to the
|
||||
correponding pthread_ interfaces that provide cancellation controls
|
||||
for tasks.
|
||||
|
||||
* Graphics/Display Drivers:
|
||||
|
||||
- boardctl: Add new boardctl() command, BOARDIOC_NX_START, to start the
|
||||
NX server as a kernel thread.
|
||||
|
||||
* Networking/Network Drivers:
|
||||
|
||||
- Network drivers: Add option to use low-priority work queue to all
|
||||
Ethernet and MAC level drivers.
|
||||
- Network Drivers: Adapt all Ethernet (and other MAC) drivers to work
|
||||
as though CONFIG_NET_MULTIBUFFER were set. Remove all references to
|
||||
CONFIG_NET_MULTIBUFFER.
|
||||
- Eliminate CONFIG_NO_NOINTS. There is no longer any support for
|
||||
interrupt level processing of the network stack. Lots of files changed.
|
||||
|
||||
* Other Common Device Drivers:
|
||||
|
||||
- Vishay VEML6070: Add Vishay VEML6070 driver. From Alan Carvalho de
|
||||
Assis.
|
||||
|
||||
* ARMv7-A
|
||||
|
||||
- ARMv7-A/i.MX6: Add SCU register definitions. Add some controls to
|
||||
enable SMP cache coherency in SMP mode. Makes no difference, however
|
||||
-- cache still incoherent on i.MX6.
|
||||
- ARMv7 GIC: SGIs are non-maskable but go through the same path as
|
||||
other, maskable interrupts. Added logic to serialize SGI processing
|
||||
when necessary.
|
||||
|
||||
* Atmel SAM3/4:
|
||||
|
||||
- SAM3/4: Add SMP support for the dual-core SAM4CM. From Masayuki
|
||||
Ishikawa.
|
||||
|
||||
* Atmel SAM3/4 Drivers:
|
||||
|
||||
- Add support for the SAM5CMP-DB board. From Masayuki Ishikawa.
|
||||
|
||||
* Atmel SAM3/4 Boards:
|
||||
|
||||
- SAM4CMP-DB: Add support for the Atmel SAM4CMP-DB board running in an
|
||||
SMP configuration. From Masayuki Ishikawa.
|
||||
- SAM4CMP-DB: Add hooks to auto-mount the procfs file system on startup
|
||||
in board bring-up logic.
|
||||
|
||||
* Atmel SAMV7 Drivers:
|
||||
|
||||
- SAMv7: Register the watchdog device at the configured device path
|
||||
CONFIG_WATCHDOG_DEVPATH vs. hard-coded /dev/wdt. From Frank Benkert.
|
||||
|
||||
* Calypso
|
||||
|
||||
- Calyps: Remove all Calypso board configurations. Remove Calypso
|
||||
architecture support and support for Calypso SERCOMM driver.
|
||||
|
||||
* Misoc LM32:
|
||||
|
||||
- Misoc LM32: Adds basic support for the Misoc procoessors and the LM32
|
||||
in particular. From Ramtin Amin.
|
||||
- Misoc LM32: Add signal handling logic. From Ramtin Amin.
|
||||
- Misoc LM32: Add logic to flush/invalidate caches. From Ramtin Amin.
|
||||
|
||||
* Misoc LM32 Drivers:
|
||||
|
||||
- Misoc LM32 Serial: Add interrupting Misoc serial driver. From Ramtin
|
||||
Amin.
|
||||
- Misoc LM32 Timer: Add timer driver. From Ramtin Amin.
|
||||
- Misoc LM32: Add Misoc Ethernet driver From Ramtin Amin.
|
||||
|
||||
* Misoc LM32 Boards:
|
||||
|
||||
- Misoc LM32 Qemu: Board support for testing Misoc LM32 with Qemu. From
|
||||
Ramtin Amin.
|
||||
- Misoc LM32 Qemu: Integrate network support into configs/misoc/hello.
|
||||
From Ramtin Amin.
|
||||
- Misoc LM32 Qemu: Remove configs/misoc/include/generated directory. I
|
||||
suppose the the intent now is that this is a symbolic link? DANGER!
|
||||
This means that you cannot compile this code with first generating
|
||||
these files a providing a symbolic link to this location! There is a
|
||||
sample directory containing generated sources. This is really only
|
||||
useful for performing test builds. You really must generate the Misoc
|
||||
architecture for a real-life build. From Ramtin Amin.
|
||||
|
||||
* NXP Freescale i.MX6 Drivers:
|
||||
|
||||
- i.MX6: Add an untested SPI driver taken directly from the i.MX1 port.
|
||||
|
||||
* NXP Freescale Kinetis:
|
||||
|
||||
- Kinetis: Added missing headers. Kinetis broke out SPI to
|
||||
kinetis/kinetis_spi.h. Broke out DMA to use the modern Nuttx chip
|
||||
inclusion - still STUBS. Add Kinetis support for ARMV7-M Common
|
||||
Vector and FPU. Allow CONFIG_ARMV7M_CMNVECTOR,
|
||||
CONFIG_STACK_COLORATION, CONFIG_ARCH_FPU. Fix i2c driver offset
|
||||
swapped for value in kinetis_i2c_putreg. From David Sidrane.
|
||||
|
||||
* NXP Freescale Kinetis Drivers:
|
||||
|
||||
- Kinetis: Add UID Unique ID. From Neil Hancock.
|
||||
|
||||
* NXP Freescale Kinetis Boards:
|
||||
|
||||
- Freedom-K64F board: Add support for UID Unique ID. From Neil Hancock.
|
||||
|
||||
* NXP Freescale LPC17xx Boards:
|
||||
|
||||
- Olimex-LPC1766-STK: Enable procfs in NSH configuration. Automount
|
||||
/proc on startup.
|
||||
|
||||
* NXP Freescale LPC43xx Drivers:
|
||||
|
||||
- LPC43xx: Add timer driver: From Alan Carvalho de Assis.
|
||||
- LPC43xx GPDMA driver: The GPDMA block is basically the same as the
|
||||
LPC17xx. Only the clock configuration is different and LPC43xx has
|
||||
four different DMA request sources, where LPC17xx has only two. From
|
||||
Alan Carvalho de Assis.
|
||||
|
||||
* NXP Freescale LPC43xx Boards:
|
||||
|
||||
- Bambino 200E: Add basic support to Micromint Bambino 200E board.
|
||||
This includes contributions from Jim Wolfman. From Alan Carvalho de
|
||||
Assis.
|
||||
- Bambino 200E: Add support for timer driver. From Alan Carvalho de
|
||||
Assis.
|
||||
|
||||
* RGMP:
|
||||
|
||||
- Remove RGMP and RGMP drivers.
|
||||
|
||||
* RISC-V:
|
||||
|
||||
- RISC-V: Add support for the RISC-V architecture and
|
||||
configs/nr5m100-nexys4 board. The board support on this is pretty
|
||||
thin, but it seems like maybe a good idea to get the base RISC-V stuff
|
||||
in since there are people interested in it. From Ken Pettit.
|
||||
|
||||
* STMicro STM32 Drivers:
|
||||
|
||||
- STM32 F3: Implemention of the STM32 F37xx SDADC module. There are
|
||||
also changes to ADC, DAC modules. SDADC has only been tested in DMA
|
||||
mode and does not support external TIMER triggers. This is a work in
|
||||
progress. From Marc Rechté.
|
||||
- STM32 F3: Add PWM driver support for STMF37xx. The changes have been
|
||||
tested successfuly for TIM4 and TIM17 (different IPs). From Marc
|
||||
Rechté.
|
||||
- STM32 F4: Support oversampling by 8 for the STM32 F4. From David
|
||||
Sidrane.
|
||||
- STM32 F4: Added Timers 2-5 and control of SAI and I2S PLLs. Added
|
||||
support for stmf469 SAI and I2S PLL configuration and STM446 fixes.
|
||||
From David Sidrane.
|
||||
- STM32 F4: Expanded OTGFS support to stm32F469 and stm32f446. Added
|
||||
missing bit definitions, Used stm32F469 and stm32f446 bit
|
||||
definitions, Removed unsed header file. From David Sidrane.
|
||||
- STM32 F4: Allow dma in 1 bit mode in STM32F4xxx. From David Sidrane.
|
||||
- STM32 F7: Allow the config to override the clock edge setting. From
|
||||
David Sidrane.
|
||||
- STM32 L4: Support Complementary PWM outputs on STM32L4. From
|
||||
Sebastien Lorquet.
|
||||
- STM32 L4: Add implementation of dumpgpio for stm32l4, was required
|
||||
for pwm debug. From Sebastien Lorquet.
|
||||
|
||||
* STMicro STM32 Boards:
|
||||
|
||||
- STM32F103 Minimum: Add button support. From Alan Carvalho de Assis.
|
||||
- STM32F103 Minimum: Add support to PWM on STM32F103-Minimum board.
|
||||
From Alan Carvalho de Assis.
|
||||
- STM32F103 Minimum: Add RGB LED support on STM32F103 Minimum board.
|
||||
From Alan Carvalho de Assis.
|
||||
- STM32F103 Minimum: Add Vishay VEML6070 driver support to the
|
||||
STM32F103-Minimum board. From Alan Carvalho de Assis.
|
||||
- Nucleo-F303RE: Add STM32 F303RE hello configuration. From Marc
|
||||
Rechté.
|
||||
- Nucleo-L476: Support PWM testing on board Nucleo L476. From
|
||||
Sebastien Lorquet.
|
||||
- Nucleo L476: Add support for timers to Nucleo L476. From Sebastien
|
||||
Lorquet.
|
||||
- Hymini STM32v: Enable CONFIG_RTC in the hymini-stm32v/nsh2
|
||||
(kitchensink) config. From Maciej Wójcik.
|
||||
- Olimex STM32-p407: Add support for the Olimex STM32 P407 board.
|
||||
|
||||
* TI Tiva Drivers:
|
||||
|
||||
- Tiva PWM: Support PWM_PULSECOUNT feature for TI tiva. From Young.Mu.
|
||||
|
||||
* Xtensa/ESP32
|
||||
|
||||
- Xtensa ESP32: Basic architectural support for Xtensa processors and
|
||||
the Expressif. ESP32 added.
|
||||
- Xtensa ESP32: Add EXPERIMENTAL hooks to support lazy Xtensa
|
||||
co-processor state restore in the future.
|
||||
- Xtensa ESP32: Basic port is function in both single CPU and dual CPU
|
||||
SMP configurations. There is an NSH configuration for each CPU
|
||||
configuration. Outstanding issues include missing clock configuration
|
||||
logic, missing partition tables to support correct configuration from
|
||||
FLASH, and some serial driver pin configuration issues.
|
||||
- Xtensa ESP32: Add stack checking logic.
|
||||
|
||||
* Xtensa/ESP32 Boards:
|
||||
|
||||
- ESP32 Core v2: Basic support for Expressif ESP32 Core v2 board
|
||||
added. The initial release includes an NSH and an SMP test
|
||||
configuration.
|
||||
- ESP32 Core v2: Add configuration to support linking NuttX for
|
||||
execution out of IRAM.
|
||||
- ESP32 Core v2: Automatically mount /proc at start-up.
|
||||
- ESP32 Core v2: Add an OS test to verify the port.
|
||||
|
||||
* C Library/Header Files:
|
||||
|
||||
- libc/locale: Add a dummy setlocale() function to avoid drawing the
|
||||
function from newlib. Add clocale header file.
|
||||
- include/locale.h: Modify locale.h to add localeconv() and lconv
|
||||
structure. From Alan Carvalho de Assis.
|
||||
- libc/locale: Allows c++ code to compile with or without
|
||||
CONFIG_LIBC_LOCALE and will generate a link error if
|
||||
CONFIG_LIBC_LOCALE is not defined and setlocale is referenced. With
|
||||
CONFIG_LIBC_LOCALE defined setlocale will act as if MB string is not
|
||||
supported and return "C" for POSIX. C and "". From David Sidrane.
|
||||
- libc/wchar: Add wcslen, wmemchr, wmemcmp, wmemcpy wmemset, btowc,
|
||||
mbrtowc, mbtowc, wcscmp, wcscoll, and wmemmove to NuttX. From Alan
|
||||
Carvalho de Assis.
|
||||
- libc/wctype: Add functions wcrtomb, wcslcpy, wcsxfrm, wctob, wctomb,
|
||||
wctype, localeconv, strcoll, strxfrm, swctype, towlower, towupper and
|
||||
wcsftime. Add wctype.h; Move lib_wctype.c to libc/wctype. From Alan
|
||||
Carvalho de Assis.
|
||||
- include/ctype.h : Add isblank() macro to ctype.h. From Alan Carvalho
|
||||
de Assis.
|
||||
- lic/stdlib: Add strtof() and strtold() as simply a copy of strtod
|
||||
with types and limits changed.
|
||||
- sscanf(): Use strtof() instead of strtod() if a short floating point
|
||||
value was requested. The should help performance with MCUs with
|
||||
32-bit FPU support with some additional code size.
|
||||
- sscanf(): Add scansets to the scanf function. Enabled
|
||||
CONFIG_LIBC_SCANSET option. From Aleksandr Vyhovanec.
|
||||
- include/inttypes.h: Add architecture-specific inttypes.h. From Paul
|
||||
A. Patience.
|
||||
- C Library: Allow option to enable IP address conversions even when
|
||||
the IP address family is not supported.
|
||||
|
||||
* Build/Configuration System:
|
||||
|
||||
- The Smoothie project needs to compile C++ inside config/boardname/src/
|
||||
to use with High Priority Interruption, then I modified the board
|
||||
configs Makefile to support it. It works fine for the first time
|
||||
compilation, but if we execute "touch config/boardname/src/Pin.cxx"
|
||||
and execute "make" it will not detect that Pin.cxx was modified. I
|
||||
think there is some other place I should modify, but I didn't find
|
||||
it. From Alan Carvalho de Assis.
|
||||
|
||||
* Tools:
|
||||
|
||||
- tools/: Add tools/showsize.sh.
|
||||
|
||||
* NSH: apps/nshlib:
|
||||
|
||||
- NSH: dd command will show statistics. From Masayuki Ishikawa.
|
||||
|
||||
* Applications: apps/system:
|
||||
|
||||
- apps/system/sched_note: Extend to include additions to instumentation
|
||||
for SMP.
|
||||
- apps/system/sched_note: Add support for spinlock notes.
|
||||
- apps/system/sched_note: Add support for new scheduler instrumentation.
|
||||
|
||||
* Platforms: apps/platform:
|
||||
|
||||
- ESP32 Core v2: Add platform support for the ESP32 core v2 board.
|
||||
- Olimex STM32-p407: Add platform support for the Olimex STM32 P407.
|
||||
|
||||
* Graphics: apps/graphics
|
||||
|
||||
- graphics/traveler/tcledit and libwld: Add an X11 Tcl/Tk tool that can
|
||||
be used to edit Traveler world files.
|
||||
- Graphics: Remove all NX server taks. Instead, call boardctl() to the
|
||||
NX server kernel thread.
|
||||
|
||||
* Applications: apps/examples:
|
||||
|
||||
- examples/buttons: Add a new buttons example that uses the button
|
||||
character driver instead of the architecture buttons directly. From
|
||||
Alan Carvalho de Assis.
|
||||
- examples/cctype: Add an example to verify cctype functions.
|
||||
- Remove RGMP example.
|
||||
- examples/ostest: Extend the pthread cancellation test to exercise
|
||||
pthread_cleanup_push() (and pthread_cleanup_pop() indirectly via
|
||||
pthread_cancel() and pthread_exit().
|
||||
- examples/ostest: enhance pthread cancellation test some.
|
||||
|
||||
Works-In-Progress:
|
||||
|
||||
* IEEE802.14.5/6LowPAN. Hooks and framework for this effort were
|
||||
introduced in NuttX-7.15. Work has continued on this effort on
|
||||
forks from the main repositories, albeit with many interruptions.
|
||||
The completion of this wireless feature will postponed until at
|
||||
least NuttX-7.20.
|
||||
|
||||
Bugfixes. Only the most critical bugfixes are listed here (see the
|
||||
ChangeLog for the complete list of bugfixes and for additional, more
|
||||
detailed bugfix information):
|
||||
|
||||
* Core OS:
|
||||
|
||||
- sched/semaphore: Within the OS, when a thread obtains a semaphore
|
||||
count it must call sem_addholder() if CONFIG_PRIORITY_INHERITANCE is
|
||||
enabled. If a count is available, then sem_wait() calls
|
||||
sem_addholder(), otherwise it waited for the semaphore and called
|
||||
sem_addholder() when it eventually received the count. This caused a
|
||||
problem when the thread calling sem_wait() was very low priority.
|
||||
When it received the count, there may be higher priority threads
|
||||
"hogging" the CPU that prevent the lower priority task from running
|
||||
and, as a result, the sem_addholder() may be delayed indefinitely.
|
||||
The fix was to have sem_post() call sem_addholder() just before
|
||||
restarting the thread waiting for the semaphore count. This problem
|
||||
was noted by Benix Vincent who also suggested the solution.
|
||||
- Many files: Make sure that priority inheritance is not enabled for
|
||||
semaphores whose primary use is signaling (vs locking of resources) by
|
||||
calling sem_setprotocol().
|
||||
- sched/semaphore: sem_trywait() no longer modifies the errno value
|
||||
UNLESS an error occurs. This allows these functions to be used
|
||||
internally without clobbering the errno value. From Freddie Chopin.
|
||||
- sched/clock: Correct clock initialization. The correct range for the
|
||||
month is 0-11 but is entered as 1-12 in the .config file. Add ranges
|
||||
to START_YEAR, MONTH, and DAY in sched/Kconfig.
|
||||
- sched/clock: Correct calculation for the case of Tickless mode with a
|
||||
32-bit timer. In that case, the calculation was returning millisecond
|
||||
accuracy. That is not good when the timer accuracy is < 1 msec. From
|
||||
Rajan Gill.
|
||||
- Work Queue: When queuing new LP work, don't signal any threads if
|
||||
they are all busy. From Heesub Shin.
|
||||
- Work Queue: Signal sent from work_signal() may interrupt the low
|
||||
priority worker thread that is already running. For example, the
|
||||
worker thread that is waiting for a semaphore could be woken up by the
|
||||
signal and break any synchronization assumption as a result. It also
|
||||
does not make any sense to send signal if it is already running and
|
||||
busy. This change fixes it. From Heesub Shin.
|
||||
- Fix DEBUGASSERT() in group_signal.c. From Masayuki Ishikawa.
|
||||
- Eliminate bad boardctl() commands: Remove all references to
|
||||
BOARDIOC_PWMSETUP and board_pwm_setup(). Remove all references to
|
||||
BOARDIOC_ADCSETUP and board_adc_setup(). Remove
|
||||
BOARDIOC_CAN_INITIALIZE. CAN initialization is now done in the board
|
||||
initialization logic just like every other device driver.
|
||||
- pthreads: Fix an error in pthread_mutex_destroy(). An error could
|
||||
occur while destroying a mutex after a pthread has been canceled while
|
||||
holding the mutex.
|
||||
- task_restart: Make sure new task starts with pre-emption disabled and
|
||||
not in a critical section.
|
||||
- Enter/leave Critical Sections. Major redeign to
|
||||
enter/leave_critical_section logic to deal with the case where
|
||||
interrupts are disabled only on the local CPU. In this case, some
|
||||
rather complex spinlocks must be used to maintain the critical section
|
||||
accross all CPUs.
|
||||
- SMP Critical Sections: Fixes for the SMP case: (1) Change order for
|
||||
SMP case in enter_critical_section: (1) Disable local interrupts
|
||||
BEFORE taking spinlock and (2) If SMP is enabled, if any interrupt
|
||||
handler calls enter_critical_section(), it should take the spinlock.
|
||||
- SMP wdogs: Wdog timers use a tasking interface that to manipulate
|
||||
wdogs, and a different interface in the timer interrupt handling logic
|
||||
to manage wdog expirations. In the single CPU case, this is fine.
|
||||
Since the tasking level code calls enter_critical_section, interrupts
|
||||
are disabled and no conflicts can occur. But that may not be the case
|
||||
in the SMP case. Most architectures do not permit disabling
|
||||
interrupts on other CPUs so enter_critical_section must work
|
||||
differently: Locks are required to protect code. this change adds
|
||||
locking (via enter_critical section) to wdog expiration logic for the
|
||||
the case if the SMP configuration.
|
||||
- SMP vfork(): Fix a race condition in the SMP case. Existing logic
|
||||
depended on the fact that the child would not run until waitpid was
|
||||
called because the child had the same priority as the parent. BUT in
|
||||
the SMP case that is not true... the child may run immediately on a
|
||||
different CPU.
|
||||
- SMP: This change adds a new internal interfaces and fixes a problem
|
||||
with three APIs in the SMP configuration. The new internal interface
|
||||
is sched_cpu_pause(tcb). This function will pause a CPU if the task
|
||||
associated with 'tcb' is running on that CPU. This allows a different
|
||||
CPU to modify that OS data stuctures associated with the CPU. When
|
||||
the other CPU is resumed, those modifications can safely take place.
|
||||
The three fixes are to handle cases in the SMP configuration where one
|
||||
CPU does need to make modifications to TCB and data structures on a
|
||||
task that could be running running on another CPU. Those three cases
|
||||
are task_delete(), task_restart(), and execution of signal handlers.
|
||||
In all three cases the solutions is basically the same: (1) Call
|
||||
sched_cpu_pause(tcb) to pause the CPU on which the task is running,
|
||||
(2) perform the necessary operations, then (3) call up_cpu_resume() to
|
||||
restart the paused CPU.
|
||||
- SMP: Add logic to avoid a deadlock condition when CPU1 is hung waiting
|
||||
for g_cpu_irqlock with interrupts interrupts and CPU0 is waiting for
|
||||
g_cpu_paused.
|
||||
- SMP: Enforce this rule: Tasks which are normally restored when
|
||||
sched_unlock() is called must remain pending (1) if we are in a
|
||||
critical section, i.e., g_cpu_irqlock is locked , or (2) other CPUs
|
||||
still have pre-emption disabled, i.e., g_cpu_schedlock is locked. In
|
||||
those cases, the release of the pending tasks must be deferred until
|
||||
those conditions are met.
|
||||
|
||||
* File System/Block Drivers/MTD Drivers:
|
||||
|
||||
- AT24XX EEPROM MTD driver: Added EEPROM timeout. Fromo Aleksandr
|
||||
Vyhovanec.
|
||||
- fs/procfs: Fix procfs status for SMP case.
|
||||
|
||||
* Graphics/Graphic Drivers:
|
||||
|
||||
- Fonts: Correct some default font IDs. From Pierre-Noel Bouteville.
|
||||
|
||||
* Common Drivers:
|
||||
|
||||
- usbhost/enumerate: Fix possible buffer overwrite. From Janne Rosberg.
|
||||
- usbhost/composite: Fix compile; missing semicolons. From Jann Rosberg.
|
||||
- syslog: Fixes required for file syslog output. From Max Kriegleder.
|
||||
- SPI configuration: Fix Kconfig warning. This change moves the
|
||||
ARCH_HAVE_SPI options outside the check for SPI. Those options don't
|
||||
depend on SPI, and Kconfig files in arch/ enable them even if SPI
|
||||
isn't enabled. Source the driver's Kconfig in drivers/Kconfig only
|
||||
if support for the driver is enabled prevents us from defining these
|
||||
ARCH_HAVE options in the driver's Kconfig. We should probably remove
|
||||
the other checks in drivers/Kconfig and check if the drivers are
|
||||
enabled only in their Kconfig. From Paul A. Patience.
|
||||
- drivers/timer: Remove the timer driver TIOC_SETHANDLER IOCTL call.
|
||||
This calls directly from the timer driver into application code. That
|
||||
is non-standard, non-portable, and cannot be supported. Instead, add
|
||||
timer driver hooks to support signal notification of timer
|
||||
expiration. Signal notification logic added by Sebastien Lorquet.
|
||||
- All timer lower half drivers. Port Sebastien's changes to all other
|
||||
implementations of the timer lower half.
|
||||
- USB MSC Device: Fix length of mode6 sense reply packet. From
|
||||
Wolfgang Reißnegger.
|
||||
- USB Composite Host: Fix end offset in usbhost_copyinterface(). From
|
||||
Janne Rosberg.
|
||||
- USB CDC/ACM Host: Add CDC_SUBCLASS_ACM and CDC_PROTO_ATM to
|
||||
supported class and proto. From Janne Rosberg.
|
||||
- SSD1306: Fix errors in SPI mode configuration. From Gong Darcy.
|
||||
- CDC/ACM Device Class: uart_ops_s portion of cdcacm will not be
|
||||
initalized with correct functions if CONFIG_SERIAL_DMA is selected.
|
||||
|
||||
* Networking/Network Drivers:
|
||||
|
||||
- drivers/net/tun.c: Fix bug in TUN interface driver. From Max Nekludov.
|
||||
|
||||
* ARMv7-A:
|
||||
|
||||
- ARMv7-A SMP: Add SMP logic to signal handling.
|
||||
|
||||
* ARMv7-M:
|
||||
|
||||
- ARMv7-M: Fix double allocation of MPU region in mmu.h.
|
||||
|
||||
* ARMv7-R:
|
||||
|
||||
- ARMv7-R: Fix compilation error. This change fixes compilation errors
|
||||
on MPU support for ARMv7-R. From Heesub Shin.
|
||||
- ARMv7-R: fix invalid drbar handling. In ARMv7-R, [31:5] bits of DRBAR
|
||||
is physical base address and other bits are reserved and SBZ. Thus,
|
||||
there is no point in passing other than the base address. From Heesub
|
||||
Shin.
|
||||
- ARMv7-R: Remove the redundant update on SCTLR. mpu_control() is
|
||||
invoking cp15_wrsctlr() around SCTLR update redundantly. From Heesub
|
||||
Shin.
|
||||
- ARMv7-R: add new Kconfig entries for d/i-cache. Unlike in ARMv7-A/M,
|
||||
Kconfig entries for data and instruction caches are currently missing
|
||||
in ARMv7-R. This change adds those missing Kconfig entries. Actual
|
||||
implmenetation for those functions will be added in the subsequent
|
||||
patches. From Heesub Shin.
|
||||
- ARMv7-R: Add cache handling functions. This change adds functions for
|
||||
enabling and disabling d/i-caches which were missing for ARMv7-R.
|
||||
From Heesub Shin.
|
||||
- ARMv7-R: Fix typo in mpu support. s/ARMV7M/ARMV7R/g. From Heesub Shin.
|
||||
- ARMv7-R: Fix CPSR corruption after exception handling. A sporadic
|
||||
hang with consequent crash was observed when booting. It seemed to be
|
||||
caused by the corrupted or wrong CPSR restored on return from
|
||||
exception. NuttX restores the context using code like this: msr spsr,
|
||||
r1. GCC translates this to: msr spsr_fc, r1. As a result, not all
|
||||
SPSR fields are updated on exception return. This should be: msr
|
||||
spsr_fsxc, r1. On some evaluation boards, spsr_svc may have totally
|
||||
invalid value at power-on-reset. As it is not initialized at boot, the
|
||||
code above may result in the corruption of cpsr and thus unexpected
|
||||
behavior. From Heesub Shin.
|
||||
- ARMv7-R: Fix to restore the Thumb flag in CPSR. Thumb flag in CPSR is
|
||||
not restored back when the context switch occurs while executing thumb
|
||||
instruction. From Heesub Shin.
|
||||
|
||||
* Atmel SAM3/4 Drivers:
|
||||
|
||||
- SAM3/4 UDP: Add delay between setting and clearing the endpoint RESET
|
||||
bit in sam_ep_resume(). We need to add a delay between setting and
|
||||
clearing the endpoint reset bit in SAM_UDP_RSTEP. Without the delay
|
||||
the USB controller will (may?) not reset the endpoint. If the
|
||||
endpoint is not being reset, the Data Toggle (DTGLE) bit will not to
|
||||
be cleared which will cause the next transaction to fail if DTGLE is
|
||||
1. If that happens the host will time-out and reset the bus. Adding
|
||||
this delay may also fix the USBMSC_STALL_RACEWAR in usbmsc_scsi.c,
|
||||
however this has not been verified yet. From Wolfgang Reißnegger.
|
||||
- SAM3/4: Remove unused 'halted' flag from UDP driver. From Wolfgang
|
||||
Reißnegger.
|
||||
- SAM3/4: Remove 'stalled' flag from the UDP driver. This flag is not
|
||||
necessary because the state of the endpoint can be determined using
|
||||
'epstate' instead. From Wolfgang Reißnegger.
|
||||
|
||||
* Atmel SAM3/4 Boards:
|
||||
|
||||
- SAM4S Xplained Pro: Configuration uses old, improper timer interface.
|
||||
CONFIG_TIMER disabled in configuration. Remove obsolete timer
|
||||
initialization logic.
|
||||
|
||||
* Atmel SAMV7 Drivers:
|
||||
|
||||
- SAMv7 USBDEVHS: A problem occurred with the SAMV7 USBDEVHS driver if
|
||||
the USB cable is unplugged while a large amount of data is send over
|
||||
an IN endpoint using DMA. If the USB cable is plugged in again after a
|
||||
few seconds it is not possible to send data over this IN endpoint
|
||||
again, all other endpoints work as expected. The problem occurs
|
||||
because if the USB cable is unplugged while an DMA transfer is in
|
||||
flight the transfer is canceled but the register SAM_USBHS_DEVDMACTRL
|
||||
is left in an undefined state. The problem was fixed the problem by
|
||||
resetting the register SAM_USBHS_DEVDMACTRL to a known state.
|
||||
Additionally all pending interrupts are cleared. From Stefan Kolb.
|
||||
- SAMV7 MCAN: Prevent Interrupt-Flooding of ACKE when not connected to
|
||||
CAN-BUS. An Acknowledge-Error will occur every time no other CAN Node
|
||||
acknowledges the message sent. This will also occur if the device is
|
||||
not connected to the can-bus. The CAN-Standard declares, that the Chip
|
||||
has to retry a given message as long as it is not sent successfully
|
||||
(or it is not cancelled by the application). Every time the chip tries
|
||||
to resend the message an Acknowledge-Error-Interrupt is generated. At
|
||||
high baud rates this can lead in extremely high CPU load just for
|
||||
handling the interrupts (and possibly the error handling in the
|
||||
application). To prevent this Interrupt-Flooding we disable the ACKE
|
||||
once it is seen as long we didn't transfer at least one message
|
||||
successfully. From Frank Benkert.
|
||||
- SAMV7 MCAN: Make delete_filter functions more robust. From Frank
|
||||
Benkert.
|
||||
|
||||
* Atmel SAMA5 Drivers:
|
||||
|
||||
- SAMA5 PWM: Driver does not build when executing from SDRAM before
|
||||
board frequencies are not constant. Rather, the bootloader configures
|
||||
the clocking and we must derive the clocking from the MCK left by the
|
||||
bootloader. This means lots more computations. This is untested on
|
||||
initial change because I don't have a good PWM test setup right now.
|
||||
|
||||
* Misoc LM32:
|
||||
|
||||
- Misoc LM32: Corrects a bug that never occured in qemu on simulation or
|
||||
real fpga. The error was that the r1 register was being modified out
|
||||
of context switching and not restoring it. From Ramtin Amin
|
||||
|
||||
* NXP Freescale i.MX6:
|
||||
|
||||
- i.MX6 interrupt handling: Additional logic needed to handle nested
|
||||
interrupts when an interrupt stack is used. Nesting can occur because
|
||||
SGI interrupts are non-maskable.
|
||||
|
||||
* NXP Freescale LPC43xx Drivers:
|
||||
|
||||
- LPC43xx serial: Fix a typo in ioctl TIOCSRS485 ioctl. From Vytautas
|
||||
Lukenskas.
|
||||
- LPC43xx serial: Restore RS485 mode on serial port open (if RS485 is
|
||||
enabled via menuconfig). From Vytautas Lukenskas.
|
||||
- LPC43xx SD/MMC: Correct some definitions on SMMC control register in
|
||||
lpc43_sdmmc.h. From Alan Carvalho de Assis.
|
||||
- LPC43xx SD card: Correct pin configuration options needed for SD card
|
||||
pins. From Alan Carvalho de Assis.
|
||||
|
||||
* SiLabs EFM32:
|
||||
|
||||
- EFM32: Fix a compilation error. From Pierre-noel Bouteville.
|
||||
|
||||
* STMicro STM32 Drivers:
|
||||
|
||||
- STM32 CHxN channels are always outputs. From Sebastien Lorquet.
|
||||
- STM32 DAC: Fix shift value whenever there are is a DAC2 and, hence,
|
||||
up to three interfaces. From Marc Rechté.
|
||||
- STM32 F1: Add TIM8 to STM32F103V pinmap. From Maciej Wójcik.
|
||||
- STM32 F1: Fix for F1 RTC Clock, tested on F103. From Maciej Wójcik.
|
||||
- STM32 F3: STM32F303xB and STM32F303xC chips have 4 ADCs. From Paul
|
||||
A. Patience.
|
||||
- STM32 F4: A new implementation of the STM32 F4 I2C bottom half. The
|
||||
common I2C as this did not handled correctly in the current
|
||||
implementation (see also https://github.com/PX4/NuttX/issues/54). The
|
||||
changes almost exclusively affect the ISR. From Max Kriegleder.
|
||||
- STM32 F4 OTGHS Host: If STM32F446 increase number of channels to
|
||||
16. From Janne Rosberg.
|
||||
- STM32 F4: I think, that Size is (highest address+1 - Base address).
|
||||
Base address has been removed and if address+count >= size we are
|
||||
outside of the Flash. From David Sidrane.
|
||||
- STM32 F4: Fix ADC compilation error when DMA isn't enabled. From Paul
|
||||
A. Patience.
|
||||
- STM32 F4: STM32F427 was rebooting. Over reached family. From David
|
||||
Sidrane.
|
||||
- STM32 F4: Added STM32F469 RAM size and deliberated STM32F446 size.
|
||||
From David Sidrane.
|
||||
- STM32 F4: Typo in stm32f76xxxx_pinmap.h edited online with
|
||||
Bitbucket. From David Sidrane.
|
||||
- STM32 F7: stm32_i2c.c Dejavu. Fixes a bug previously found in the
|
||||
F4. From David Sidrane.
|
||||
- STM32 F7: OTGDEV fixed typo. From David Sidrane.
|
||||
- STM32 F7: Fix to SPI-Master driver. Without this the chip select
|
||||
decoding feature will not work properly. From Michael Spahlinger.
|
||||
- STM32 F7: STM32F7 SD/MMC driver depends on CONFIG_SDIO_DMA which is
|
||||
only defined in stm32/Kconfig. Changed to CONFIG_STM32F7_SDMMC_DMA
|
||||
and defined in stm32f7/Kconfig.
|
||||
- STM32 F7: Fix some STM32F7 copy paste errors. From David Sidrane.
|
||||
- STM32 L4: Complementary PWM outputs on STM32L4" (1) too many
|
||||
parentheses when calculating max chan count and (2) channel 4 does not
|
||||
have a complementary output. From Sebastien Lorquet.
|
||||
- STM32 L4: Fix I2C devices RCC registers. From Sebastien Lorquet.
|
||||
- STM32 L4: Enable and renaming for 32l4 UARTs 4 and 5. From Sebastien
|
||||
Lorquet.
|
||||
- STM32 L4: Change the way to configure quadrature encoder prescalers.
|
||||
From Sebastien Lorquet.
|
||||
- STM32 L4: Correct USART1/2 definitions. Use default mbed UART4
|
||||
settings. From Sebastien Lorquet.
|
||||
|
||||
* STMicro STM32 Boards:
|
||||
|
||||
- STM32F103 Minimum: Fix Timers 2 to 7 clock frequencies. From Alan
|
||||
Carvalho de Assis.
|
||||
- Nucleo-F303RE: Remove duplicate setting from board.h. From Marc
|
||||
Rechté.
|
||||
- Nucleo F303RE: Various fixes to get the ADC configuration building
|
||||
again after PR. Refresh all configurations.
|
||||
- Nucleo L476RG: Add better selection of timer.
|
||||
|
||||
* TI Tiva Boards:
|
||||
|
||||
- DK-TM4C129x: Typo fix. From Wolfgang Reißnegger.
|
||||
|
||||
* Xtensa ESP32:
|
||||
|
||||
- ESP32 core v2: Flush the UART TX buffer in the esp32 serial shutdown
|
||||
routine. The ROM bootloader does not flush the FIFO before handing
|
||||
over to user code, so some of this output is not currently seen when
|
||||
the UART is reconfigured in early stages of startup. From Angus
|
||||
Gratton.
|
||||
- Xtensa ESP32: Corrects a problem with dispatching to signal
|
||||
handlers: Cannot vector directly to the signal handling function as
|
||||
in other ABIs under the Xtensa Window ABI. In that case, we need to
|
||||
go through a tiny hook when performs the correct window call (call4)
|
||||
otherwise registers will be scrambled in the signal handler.
|
||||
|
||||
* Xtensa ESP32 Boards:
|
||||
|
||||
- ESP32 core v2: Changes the openocd config file's default flash
|
||||
voltage from 1.8V to 3.3V. This is not necessary right now, but may
|
||||
save some hard-to-debug moments down the track (3.3V-only flash
|
||||
running at 1.8V often half-works and does weird things...). From
|
||||
Angus Gratton.
|
||||
|
||||
* C Library/Header Files:
|
||||
|
||||
- libc/stdio: Fixes sscanf() %sn where strlen(data) < n. From David
|
||||
Sidrane.
|
||||
- libc/stdio: Include wchar.h in lib_libvsprintf.c to fix compilation
|
||||
error. From Alan Carvalho de Assis.
|
||||
- include/sys/time.h: timersub macro modified per recommendations of
|
||||
phreakuencies.
|
||||
- include/ctype.h and cxx/cctype: Implement ctype.h functions as inline
|
||||
if possible. cctype can then properly select namespace.
|
||||
- include/: Fix a number of header files with mismatched 'extern C {'
|
||||
and '}'.
|
||||
- libc/unisted: Change brings strtol() and related functions more
|
||||
conformant with POSIX. Corner cases like strtol(-2147483648, NULL,
|
||||
10) now pass clang -fsanitize=integer without warnings. From Juha
|
||||
Niskanen.
|
||||
- libc/unistd: sleep() was returning remaining nanoseconds (kind of),
|
||||
instead the remaining seconds. From Eunbong Song.
|
||||
- termios.h: Fix CRTSCTS define to include input and output flow. From
|
||||
Lorenz Meier.
|
||||
|
||||
* Build/Configuration System:
|
||||
|
||||
- configs/*/defconfig: The buttons example was changed to archbuttons.
|
||||
As a result all of the button configurations are broken and need some
|
||||
renaming in the defconfig files. Noted by Frank Berkert.
|
||||
- config/*/defconfgs: More fallout from name change of
|
||||
apps/examples/buttons to archbuttons.
|
||||
- configs: All QE encoder files. Last change made timer hard-coded to
|
||||
3. Make configurable.
|
||||
- configs: Remove all traces of the no-longer existent ARCHBUTTONS
|
||||
example. Remove all button configurations that depended on the
|
||||
obsoleted ARCHBUTTON example.
|
||||
- minnsh Configurations: Remove minnsh configurations and support
|
||||
logic: up_getc() and lowinstream. This was an interesting exercise
|
||||
to see just how small you could get NuttX, but otherwise it was not
|
||||
useful: (1) the NSH code violated the OS interface layer by callup
|
||||
up_getc() and up_putc() directly, and (2) while waiting for character
|
||||
input, NSH would call up_getc() which would hog all of the CPU. Not a
|
||||
reasonable solution other than as a proof of concept.
|
||||
|
||||
* Application Build/Configuration System:
|
||||
|
||||
- Make.defs: Using wrong link script if native window tool used with
|
||||
Cygwin.
|
||||
|
||||
* apps/platform:
|
||||
|
||||
- ESP32 Core v2 Platform: Fix some naming that prevented building the
|
||||
C++ support.
|
||||
|
||||
* apps/nshlib:
|
||||
|
||||
- NSH Library: nsh_getdirpath(), use snprint instead of sprintf to
|
||||
avoid possibility of buffer overrun. Noted by Chung Hwan Kim.
|
||||
|
||||
* apps/system:
|
||||
|
||||
- Remove std_readline(). This called up_getc() and up_putc() directly,
|
||||
violating the POSIX OS interface.
|
||||
|
||||
* apps/netutils:
|
||||
|
||||
- FTPD: Fixed bug that didn't free ftpd ressources on exit. From Pascal
|
||||
Speck.
|
||||
- NTP client: Fix missing left parenthesis. From Pierre-Noel Bouteville.
|
||||
- cJSON: Import patch to fix:cJSON_PrintUnformatted() behaves unexpected
|
||||
if an empty array shall be printed to text. from Jerome Lang
|
||||
2012-04-19. From Pierre-Noel Bouteville.
|
||||
- esp8266 update cosmetic and many bug fix. From Pierre-Noel Bouteville.
|
||||
- FTPD: Fix bug un ftpd file or socket may be not closed. From
|
||||
Pierre-Noel Bouteville.
|
||||
|
||||
* apps/modbus:
|
||||
|
||||
- Modbus Master is missing many files and doesn't compile at all. More
|
||||
details in
|
||||
https://groups.yahoo.com/neo/groups/nuttx/conversations/topics/13734.
|
||||
From Vytautas Lukenskas.
|
||||
|
||||
* apps/examples:
|
||||
|
||||
- The examples/qencoder app was trying to init the encoder by a direct
|
||||
call into the board, cheating in a local header to declare the
|
||||
normally unavailable function prototype. From Sebastien Lorquet.
|
||||
- apps/examples/timer: Should detach signal handler before exiting.
|
||||
- examples/qencode: The examples/qencoder app was trying to init the
|
||||
encoder by a direct call into the board, cheating in a local header to
|
||||
declare the normally unavailable function prototype. From Sebastien
|
||||
Lorquet.
|
||||
- apps/examples/archbuttons: Removed becaue it violates OS interface
|
||||
principles.
|
||||
- examples/adc, pwm, can: Remove all usage of BOARDIOC_ADCTEST_SETUP,
|
||||
BIOARDIOC_PWMSETUP. Remove BOARDIOC_CAN_INITIALIZE. CAN
|
||||
initialization is now done in the board initialization logic just like
|
||||
every other device driver.
|
||||
- examples/ostest: Add some delays to the pthread cancellation test.
|
||||
With deferred cancellation enabled, things happen more asynchronously.
|
||||
|
111
TODO
111
TODO
@ -1,4 +1,4 @@
|
||||
NuttX TODO List (Last updated December 3, 2016)
|
||||
NuttX TODO List (Last updated December 11, 2016)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This file summarizes known NuttX bugs, limitations, inconsistencies with
|
||||
@ -9,7 +9,7 @@ issues related to each board port.
|
||||
|
||||
nuttx/:
|
||||
|
||||
(13) Task/Scheduler (sched/)
|
||||
(12) Task/Scheduler (sched/)
|
||||
(1) SMP
|
||||
(1) Memory Management (mm/)
|
||||
(1) Power Management (drivers/pm)
|
||||
@ -22,7 +22,7 @@ nuttx/:
|
||||
(12) Network (net/, drivers/net)
|
||||
(4) USB (drivers/usbdev, drivers/usbhost)
|
||||
(0) Other drivers (drivers/)
|
||||
(11) Libraries (libc/, libm/)
|
||||
(12) Libraries (libc/, libm/)
|
||||
(11) File system/Generic drivers (fs/, drivers/)
|
||||
(9) Graphics Subsystem (graphics/)
|
||||
(2) Build system / Toolchains
|
||||
@ -101,16 +101,37 @@ o Task/Scheduler (sched/)
|
||||
Status: Open
|
||||
Priority: Medium Low for now
|
||||
|
||||
Title: ISSUES WITH atexit() AND on_exit()
|
||||
Title: ISSUES WITH atexit(), on_exit(), AND pthread_cleanup_pop()
|
||||
Description: These functions execute with the following bad properties:
|
||||
|
||||
1. They run with interrupts disabled,
|
||||
2. They run in supervisor mode (if applicable), and
|
||||
3. They do not obey any setup of PIC or address
|
||||
environments. Do they need to?
|
||||
4. In the case of task_delete() and pthread_cancel(), these
|
||||
callbacks will run on the thread of execution and address
|
||||
context of the caller of task. That is very bad!
|
||||
|
||||
The fix for all of these issues it to have the callbacks
|
||||
run on the caller's thread (as with signal handlers).
|
||||
run on the caller's thread as is currently done with
|
||||
signal handlers. Signals are delivered differently in
|
||||
PROTECTED and KERNEL modes: The deliver is involes a
|
||||
signal handling trampoline function in the user address
|
||||
space and two signal handlers: One to call the signal
|
||||
handler trampoline in user mode (SYS_signal_handler) and
|
||||
on in with the signal handler trampoline to return to
|
||||
supervisor mode (SYS_signal_handler_return)
|
||||
|
||||
The primary difference is in the location of the signal
|
||||
handling trampoline:
|
||||
|
||||
- In PROTECTED mode, there is on a single user space blob
|
||||
with a header at the beginning of the block (at a well-
|
||||
known location. There is a pointer to the signal handler
|
||||
trampoline function in that header.
|
||||
- In the KERNEL mode, a special process signal handler
|
||||
trampoline is used at a well-known location in every
|
||||
process address space (ARCH_DATA_RESERVE->ar_sigtramp).
|
||||
Status: Open
|
||||
Priority: Medium Low. This is an important change to some less
|
||||
important interfaces. For the average user, these
|
||||
@ -144,20 +165,6 @@ o Task/Scheduler (sched/)
|
||||
incompatibilities could show up in porting some code).
|
||||
Priority: Low
|
||||
|
||||
Title: REMOVE TASK_DELETE
|
||||
Description: Need to remove or fix task delete. This interface is non-
|
||||
standard and not safe. Arbitrary deleting tasks can cause
|
||||
serious problems such as memory leaks. Better to remove it
|
||||
than to retain it as a latent bug.
|
||||
|
||||
Currently used within the OS and also part of the
|
||||
implementation of pthread_cancel() and task_restart() (which
|
||||
should also go for the same reasons). It is used in
|
||||
NxWM::CNxConsole to terminate console tasks and also in
|
||||
apps/netutils/thttpd to kill CGI tasks that timeout.
|
||||
Status: Open
|
||||
Priority: Low and not easily removable.
|
||||
|
||||
Title: RELEASE SEMAPHORES HELD BY CANCELED THREADS:
|
||||
Description: Commit: fecb9040d0e54baf14b729e556a832febfe8229e: "In
|
||||
case a thread is doing a blocking operation (e.g. read())
|
||||
@ -491,12 +498,6 @@ o Signals (sched/signal, arch/)
|
||||
o pthreads (sched/pthreads)
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Title: CANCELLATION POINTS
|
||||
Description: pthread_cancel(): Should implement cancellation points and
|
||||
pthread_testcancel()
|
||||
Status: Open. No changes are planned.
|
||||
Priority: Low, probably not that useful
|
||||
|
||||
Title: PTHREAD_PRIO_PROTECT
|
||||
Description: Extend pthread_mutexattr_setprotocol() support PTHREAD_PRIO_PROTECT:
|
||||
|
||||
@ -557,6 +558,44 @@ o pthreads (sched/pthreads)
|
||||
solution. So I discarded a few hours of programming. Not a
|
||||
big loss from the experience I gained."
|
||||
|
||||
Title: ISSUES WITH CANCELLATION POINTS
|
||||
Description: According to POIX cancellation points must occur when a thread is executing
|
||||
the following functions. There are some execptions as noted:
|
||||
|
||||
accept() mq_timedsend() NA putpmsg() sigtimedwait()
|
||||
04 aio_suspend() NA msgrcv() pwrite() NA sigwait()
|
||||
NA clock_nanosleep() NA msgsnd() read() sigwaitinfo()
|
||||
close() NA msync() NA readv() 01 sleep()
|
||||
connect() nanosleep() recv() 02 system()
|
||||
-- creat() open() recvfrom() NA tcdrain()
|
||||
fcntl() pause() NA recvmsg() 01 usleep()
|
||||
NA fdatasync() poll() select() -- wait()
|
||||
fsync() pread() sem_timedwait() waitid()
|
||||
NA getmsg() NA pselect() sem_wait() waitpid()
|
||||
NA getpmsg() pthread_cond_timedwait() send() write()
|
||||
NA lockf() pthread_cond_wait() NA sendmsg() NA writev()
|
||||
mq_receive() pthread_join() sendto()
|
||||
mq_send() pthread_testcancel() 03 sigpause()
|
||||
mq_timedreceive() NA putmsg() sigsuspend()
|
||||
|
||||
NA Not supported
|
||||
-- Doesn't need instrumentation. Handled by lower level calls.
|
||||
nn See note nn
|
||||
|
||||
NOTE 01: sleep() and usleep() are user-space functions in the C library and cannot
|
||||
serve as cancellation points. They are, however, simple wrappers around nanosleep
|
||||
which is a true cancellation point.
|
||||
NOTE 02: system() is actually implemented in apps/ as part of NSH. It cannot be
|
||||
a cancellation point either.
|
||||
NOTE 03: sigpause() is a user-space function in the C library and cannot serve as
|
||||
cancellation points. It is, however, a simple wrapper around sigsuspend()
|
||||
which is a true cancellation point.
|
||||
NOTE 04: aio_suspend() is a user-space function in the C library and cannot serve as
|
||||
cancellation points. It does call around sigtimedwait() which is a true cancellation
|
||||
point.
|
||||
Status: Not really open. This is just the way it is.
|
||||
Priority: Nothing additional is planned.
|
||||
|
||||
o Message Queues (sched/mqueue)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@ -1451,10 +1490,28 @@ o Libraries (libc/, libm/)
|
||||
2016-07-30: Numerous fixes and performance improvements from
|
||||
David Alessio.
|
||||
|
||||
Status: Open
|
||||
Priority: Low for casual users but clearly high if you need care about
|
||||
Status: Open
|
||||
Priority: Low for casual users but clearly high if you need care about
|
||||
these incorrect corner case behaviors in the math libraries.
|
||||
|
||||
Title: Repartition libc functionality.
|
||||
Description: There are many things implemented within the kernel (for example
|
||||
under sched/pthread) that probably should be migrated in the
|
||||
C library where it belongs.
|
||||
|
||||
I would really like to see a little flavor of a micro-kernel
|
||||
at the OS interface: I would like to see more primitive OS
|
||||
system calls with more higher level logic in the C library.
|
||||
|
||||
One awkard thing is the incompatibility of KERNEL vs FLAT
|
||||
builds: In the kernel build, it would be nice to move many
|
||||
of the thread-specific data items out of the TCB and into
|
||||
the process address environment where they belong. It is
|
||||
difficult to make this compatible with the FLAT build,
|
||||
however.
|
||||
Status: Open
|
||||
Priority: Low
|
||||
|
||||
o File system / Generic drivers (fs/, drivers/)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -77,6 +77,8 @@ config ARCH_X86
|
||||
|
||||
config ARCH_XTENSA
|
||||
bool "Xtensa"
|
||||
select ARCH_HAVE_STACKCHECK
|
||||
select ARCH_HAVE_CUSTOMOPT
|
||||
---help---
|
||||
Cadence® Tensilica® Xtensa® actictures.
|
||||
|
||||
|
@ -158,7 +158,6 @@ arch/arm - ARM-based micro-controllers
|
||||
MCU support
|
||||
arch/arm/include/a1x and arch/arm/src/a1x
|
||||
arch/arm/include/c5471 and arch/arm/src/c5471
|
||||
arch/arm/include/calypso and arch/arm/src/calypso
|
||||
arch/arm/include/dm320 and arch/arm/src/dm320
|
||||
arch/arm/include/efm32 and arch/arm/src/efm32
|
||||
arch/arm/include/imx1 and arch/arm/src/imx1
|
||||
|
@ -31,16 +31,6 @@ config ARCH_CHIP_C5471
|
||||
---help---
|
||||
TI TMS320 C5471, A180, or DA180 (ARM7TDMI)
|
||||
|
||||
config ARCH_CHIP_CALYPSO
|
||||
bool "Calypso"
|
||||
select ARCH_ARM7TDMI
|
||||
select ARCH_HAVE_HEAP2
|
||||
select ARCH_HAVE_LOWVECTORS
|
||||
select OTHER_UART_SERIALDRIVER
|
||||
select ARCH_HAVE_POWEROFF
|
||||
---help---
|
||||
TI Calypso-based cell phones (ARM7TDMI)
|
||||
|
||||
config ARCH_CHIP_DM320
|
||||
bool "TMS320 DM320"
|
||||
select ARCH_ARM926EJS
|
||||
@ -409,7 +399,6 @@ config ARCH_CHIP
|
||||
string
|
||||
default "a1x" if ARCH_CHIP_A1X
|
||||
default "c5471" if ARCH_CHIP_C5471
|
||||
default "calypso" if ARCH_CHIP_CALYPSO
|
||||
default "dm320" if ARCH_CHIP_DM320
|
||||
default "efm32" if ARCH_CHIP_EFM32
|
||||
default "imx1" if ARCH_CHIP_IMX1
|
||||
@ -625,9 +614,6 @@ endif
|
||||
if ARCH_CHIP_C5471
|
||||
source arch/arm/src/c5471/Kconfig
|
||||
endif
|
||||
if ARCH_CHIP_CALYPSO
|
||||
source arch/arm/src/calypso/Kconfig
|
||||
endif
|
||||
if ARCH_CHIP_DM320
|
||||
source arch/arm/src/dm320/Kconfig
|
||||
endif
|
||||
|
@ -36,25 +36,4 @@
|
||||
#ifndef __ARCH_ARM_INCLUDE_ARMV7_A_SPINLOCK_H
|
||||
#define __ARCH_ARM_INCLUDE_ARMV7_A_SPINLOCK_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Not a useful feature */
|
||||
|
||||
#undef SMP_INTERCPU_NONCACHED
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* In SMP configurations, save spinlocks and other inter-CPU communications
|
||||
* data in a non-cached memory region.
|
||||
*/
|
||||
|
||||
# define SP_SECTION __attribute__((section(".nocache")))
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM_INCLUDE_ARMV7_A_SPINLOCK_H */
|
||||
|
@ -1,67 +0,0 @@
|
||||
#ifndef __ARCH_ARM_INCLUDE_CALYPSO_CLOCK_H
|
||||
#define __ARCH_ARM_INCLUDE_CALYPSO_CLOCK_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 /* __ARCH_ARM_INCLUDE_CALYPSO_CLOCK_H */
|
@ -1,31 +0,0 @@
|
||||
#ifndef __ARCH_ARM_INCLUDE_CALYPSO_DEBUG_H
|
||||
#define __ARCH_ARM_INCLUDE_CALYPSO_DEBUG_H
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check at compile time that something is of a particular type.
|
||||
* Always evaluates to 1 so you may use it easily in comparisons.
|
||||
*/
|
||||
#define typecheck(type,x) \
|
||||
({ type __dummy; \
|
||||
typeof(x) __dummy2; \
|
||||
(void)(&__dummy == &__dummy2); \
|
||||
1; \
|
||||
})
|
||||
|
||||
#ifdef DEBUG
|
||||
#define dputchar(x) putchar(x)
|
||||
#define dputs(x) puts(x)
|
||||
#define dphex(x,y) phex(x,y)
|
||||
#define printd(x, ...) printf(x, ##__VA_ARGS__)
|
||||
#else
|
||||
#define dputchar(x)
|
||||
#define dputs(x)
|
||||
#define dphex(x,y)
|
||||
#define printd(x, args ...)
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM_INCLUDE_CALYPSO_DEBUG_H */
|
@ -1,17 +0,0 @@
|
||||
#ifndef __ARCH_ARM_INCLUDE_CALYPSO_DEFINES_H
|
||||
#define __ARCH_ARM_INCLUDE_CALYPSO_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 /* !__ARCH_ARM_INCLUDE_CALYPSO_DEFINES_H */
|
@ -1,81 +0,0 @@
|
||||
/****************************************************************************
|
||||
* 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 __ARCH_ARM_INCLUDE_CALYPSO_IRQ_H
|
||||
#define __ARCH_ARM_INCLUDE_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 /* __ARCH_ARM_INCLUDE_CALYPSO_IRQ_H */
|
@ -1,28 +0,0 @@
|
||||
#ifndef __ARCH_ARM_INCLUDE_CALYPSO_MEMORY_H
|
||||
#define __ARCH_ARM_INCLUDE_CALYPSO_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 /* __ARCH_ARM_INCLUDE_CALYPSO_MEMORY_H */
|
@ -1,25 +0,0 @@
|
||||
#ifndef __ARCH_ARM_INCLUDE_CALYPSO_TIMER_H
|
||||
#define __ARCH_ARM_INCLUDE_CALYPSO_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 /* __ARCH_ARM_INCLUDE_CALYPSO_TIMER_H */
|
@ -1,6 +0,0 @@
|
||||
#ifndef __ARCH_ARM_INCLUDE_CALYPSO_UWIRE_H
|
||||
#define __ARCH_ARM_INCLUDE_CALYPSO_UWIRE_H
|
||||
void uwire_init(void);
|
||||
int uwire_xfer(int cs, int bitlen, const void *dout, void *din);
|
||||
#endif
|
||||
|
@ -1374,7 +1374,7 @@
|
||||
# define STM32_NLCD 0 /* (0) No LCD */
|
||||
# define STM32_NUSBOTG 0 /* USB FS device, but no USB OTG FS/HS */
|
||||
# define STM32_NGPIO 37 /* GPIOA-F */
|
||||
# define STM32_NADC 3 /* (3) 12-bit ADC1-3 */
|
||||
# define STM32_NADC 4 /* (3) 12-bit ADC1-4 */
|
||||
# define STM32_NDAC 2 /* (2) 12-bit DAC1-2 */
|
||||
# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */
|
||||
# define STM32_NCRC 1 /* (1) CRC calculation unit */
|
||||
@ -1414,7 +1414,7 @@
|
||||
# define STM32_NLCD 0 /* (0) No LCD */
|
||||
# define STM32_NUSBOTG 0 /* USB FS device, but no USB OTG FS/HS */
|
||||
# define STM32_NGPIO 52 /* GPIOA-F */
|
||||
# define STM32_NADC 3 /* (3) 12-bit ADC1-3 */
|
||||
# define STM32_NADC 4 /* (3) 12-bit ADC1-4 */
|
||||
# define STM32_NDAC 2 /* (2) 12-bit DAC1-2 */
|
||||
# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */
|
||||
# define STM32_NCRC 1 /* (1) CRC calculation unit */
|
||||
@ -1494,7 +1494,7 @@
|
||||
# define STM32_NLCD 0 /* (0) No LCD */
|
||||
# define STM32_NUSBOTG 0 /* USB FS device, but no USB OTG FS/HS */
|
||||
# define STM32_NGPIO 87 /* GPIOA-F */
|
||||
# define STM32_NADC 3 /* (3) 12-bit ADC1-3 */
|
||||
# define STM32_NADC 4 /* (3) 12-bit ADC1-4 */
|
||||
# define STM32_NDAC 2 /* (2) 12-bit DAC1-2 */
|
||||
# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */
|
||||
# define STM32_NCRC 1 /* (1) CRC calculation unit */
|
||||
|
@ -75,7 +75,7 @@
|
||||
* This function must be provided via the architecture-specific logoic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* lock - The address of spinlock object.
|
||||
* lock - The address of spinlock object (r0).
|
||||
*
|
||||
* Returned Value:
|
||||
* The spinlock is always locked upon return. The value of previous value
|
||||
@ -84,6 +84,8 @@
|
||||
* obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked
|
||||
* (meaning that we successfully obtained the lock)
|
||||
*
|
||||
* Modifies: r1, r2, and lr
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_testset
|
||||
@ -98,7 +100,7 @@ up_testset:
|
||||
1:
|
||||
ldrexb r2, [r0] /* Test if spinlock is locked or not */
|
||||
cmp r2, r1 /* Already locked? */
|
||||
beq 2f /* If alrady locked, return SP_LOCKED */
|
||||
beq 2f /* If already locked, return SP_LOCKED */
|
||||
|
||||
/* Not locked ... attempt to lock it */
|
||||
|
||||
|
@ -64,6 +64,10 @@ g_fiqtmp:
|
||||
.word 0 /* Saved lr */
|
||||
.word 0 /* Saved spsr */
|
||||
#endif
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3 && defined(CONFIG_ARMV7A_HAVE_GICv2)
|
||||
g_nestlevel:
|
||||
.word 0 /* Interrupt nesting level */
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Private Functions
|
||||
@ -172,13 +176,53 @@ arm_vectorirq:
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
#ifdef CONFIG_ARMV7A_HAVE_GICv2
|
||||
/* We will switch to the interrupt stack, UNLESS we are processing a
|
||||
* nested interrupt in which case we are already using the interrupt
|
||||
* stack. SGI interrupts may be nested because they are non-maskable.
|
||||
*/
|
||||
|
||||
ldr r5, .Lirqnestlevel /* r1=Points to interrupt nesting level */
|
||||
ldr r1, [r5] /* Get r1= nesting level */
|
||||
add r1, r1, #1 /* Increment nesting level */
|
||||
str r1, [r5] /* Save r1= nesting level */
|
||||
|
||||
cmp r1, #1 /* r1>1 if nested */
|
||||
bgt .Lintnested /* Use current SP if nested */
|
||||
#endif
|
||||
|
||||
/* Call arm_decodeirq() on the interrupt stack */
|
||||
|
||||
ldr sp, .Lirqstackbase /* SP = interrupt stack base */
|
||||
str r0, [sp] /* Save the user stack pointer */
|
||||
mov r4, sp /* Save the SP in a preserved register */
|
||||
bic sp, sp, #7 /* Force 8-byte alignment */
|
||||
bl arm_decodeirq /* Call the handler */
|
||||
ldr sp, [r4] /* Restore the user stack pointer */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_HAVE_GICv2
|
||||
b .Lintreturn
|
||||
|
||||
/* Call arm_decodeirq() on whatever stack is in place */
|
||||
|
||||
.Lintnested:
|
||||
mov r4, sp /* Save the SP in a preserved register */
|
||||
bic sp, sp, #7 /* Force 8-byte alignment */
|
||||
bl arm_decodeirq /* Call the handler */
|
||||
mov sp, r4 /* Restore the possibly unaligned stack pointer */
|
||||
|
||||
/* Decrement the nesting level (r5 should be preserved) */
|
||||
|
||||
.Lintreturn:
|
||||
ldr r1, [r5] /* Get r1= nesting level */
|
||||
cmp r1, #0 /* A sanity check*/
|
||||
subgt r1, r1, #1 /* Decrement nesting level */
|
||||
strgt r1, [r5] /* Save r1= nesting level */
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* Call arm_decodeirq() on the user stack */
|
||||
|
||||
mov r4, sp /* Save the SP in a preserved register */
|
||||
bic sp, sp, #7 /* Force 8-byte alignment */
|
||||
bl arm_decodeirq /* Call the handler */
|
||||
@ -227,6 +271,10 @@ arm_vectorirq:
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.Lirqstackbase:
|
||||
.word g_intstackbase
|
||||
#ifdef CONFIG_ARMV7A_HAVE_GICv2
|
||||
.Lirqnestlevel:
|
||||
.word g_nestlevel
|
||||
#endif
|
||||
#endif
|
||||
.size arm_vectorirq, . - arm_vectorirq
|
||||
.align 5
|
||||
@ -937,7 +985,7 @@ arm_vectorfiq:
|
||||
.word g_fiqtmp
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.Lfiqstackbase:
|
||||
.word g_intstackbase
|
||||
.word g_fiqstackbase
|
||||
#endif
|
||||
|
||||
#else
|
||||
@ -965,5 +1013,21 @@ g_intstackbase:
|
||||
.size g_intstackbase, 4
|
||||
.size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
|
||||
.globl g_fiqstackalloc
|
||||
.type g_fiqstackalloc, object
|
||||
.globl g_fiqstackbase
|
||||
.type g_fiqstackbase, object
|
||||
|
||||
/************************************************************************************
|
||||
* Name: g_fiqstackalloc/g_fiqstackbase
|
||||
************************************************************************************/
|
||||
|
||||
g_fiqstackalloc:
|
||||
.skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4)
|
||||
g_fiqstackbase:
|
||||
.skip 4
|
||||
.size g_fiqstackbase, 4
|
||||
.size g_fiqstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
|
||||
#endif /* CONFIG_ARCH_INTERRUPTSTACK > 3 */
|
||||
.end
|
||||
|
@ -605,9 +605,6 @@
|
||||
#define MMU_L2_VECTROFLAGS (PTE_TYPE_SMALL | PTE_WRITE_THROUGH | PTE_AP_R1)
|
||||
#define MMU_L2_VECTORFLAGS MMU_L2_VECTRWFLAGS
|
||||
|
||||
#define MMU_L1_INTERCPUFLAGS (PMD_TYPE_PTE | PMD_PTE_PXN | PMD_PTE_DOM(0))
|
||||
#define MMU_L2_INTERCPUFLAGS (PTE_TYPE_SMALL | PTE_DEVICE | PTE_AP_RW1)
|
||||
|
||||
/* Mapped section size */
|
||||
|
||||
#define SECTION_SHIFT (20)
|
||||
|
@ -50,22 +50,6 @@
|
||||
#include "up_arch.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -46,18 +46,6 @@
|
||||
#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
|
||||
defined(CONFIG_BUILD_KERNEL)) && !defined(CONFIG_DISABLE_SIGNALS)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -1,115 +0,0 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
comment "Calypso Configuration Options"
|
||||
|
||||
menu "Modem UART Configuration"
|
||||
|
||||
config UART_MODEM_BAUD
|
||||
int "Modem UART BAUD"
|
||||
default 115200
|
||||
|
||||
config UART_MODEM_PARITY
|
||||
int "Modem UART parity"
|
||||
default 0
|
||||
---help---
|
||||
Modem UART parity. 0=None, 1=Odd, 2=Even. Default: None
|
||||
|
||||
config UART_MODEM_BITS
|
||||
int "Modem UART number of bits"
|
||||
default 8
|
||||
---help---
|
||||
Modem UART number of bits. Default: 8
|
||||
|
||||
config UART_MODEM_2STOP
|
||||
int "Modem UART two stop bits"
|
||||
default 0
|
||||
---help---
|
||||
0=1 stop bit, 1=Two stop bits. Default: 1 stop bit
|
||||
|
||||
config UART_MODEM_RXBUFSIZE
|
||||
int "Modem UART Rx buffer size"
|
||||
default 256
|
||||
---help---
|
||||
Modem UART Rx buffer size. Default: 256
|
||||
|
||||
config UART_MODEM_TXBUFSIZE
|
||||
int "Modem UART Tx buffer size"
|
||||
default 256
|
||||
---help---
|
||||
Modem UART Tx buffer size. Default: 256
|
||||
|
||||
config UART_MODEM_HWFLOWCONTROL
|
||||
bool "Hardware flow control"
|
||||
default n
|
||||
---help---
|
||||
Enabled Modem UART hardware flow control. Default: n
|
||||
|
||||
endmenu
|
||||
|
||||
menu "IrDA UART Configuration"
|
||||
|
||||
config UART_IRDA_BAUD
|
||||
int "IrDA UART BAUD"
|
||||
default 115200
|
||||
|
||||
config UART_IRDA_PARITY
|
||||
int "IrDA UART parity"
|
||||
default 0
|
||||
---help---
|
||||
IrDA UART parity. 0=None, 1=Odd, 2=Even. Default: None
|
||||
|
||||
config UART_IRDA_BITS
|
||||
int "IrDA UART number of bits"
|
||||
default 8
|
||||
---help---
|
||||
IrDA UART number of bits. Default: 8
|
||||
|
||||
config UART_IRDA_2STOP
|
||||
int "IrDA UART two stop bits"
|
||||
default 0
|
||||
---help---
|
||||
0=1 stop bit, 1=Two stop bits. Default: 1 stop bit
|
||||
|
||||
config UART_IRDA_RXBUFSIZE
|
||||
int "IrDA UART Rx buffer size"
|
||||
default 256
|
||||
---help---
|
||||
IrDA UART Rx buffer size. Default: 256
|
||||
|
||||
config UART_IRDA_TXBUFSIZE
|
||||
int "IrDA UART Tx buffer size"
|
||||
default 256
|
||||
---help---
|
||||
IrDA UART Tx buffer size. Default: 256
|
||||
|
||||
config UART_IRDA_HWFLOWCONTROL
|
||||
bool "Hardware flow control"
|
||||
default n
|
||||
---help---
|
||||
Enabled IrDA UART hardware flow control. Default: n
|
||||
|
||||
endmenu
|
||||
|
||||
choice
|
||||
prompt "Serial Console Selection"
|
||||
default SERIAL_CONSOLE_NONE
|
||||
depends on DEV_CONSOLE
|
||||
|
||||
# See drivers/Kconfig
|
||||
config USE_SERCOMM_CONSOLE
|
||||
bool "SERCOMM console"
|
||||
select SERCOMM_CONSOLE
|
||||
|
||||
config SERIAL_MODEM_CONSOLE
|
||||
bool "Serial console on modem UART"
|
||||
|
||||
config SERIAL_IRDA_CONSOLE
|
||||
bool "Serial console on IrDA UART"
|
||||
|
||||
config SERIAL_CONSOLE_NONE
|
||||
bool "No serial console"
|
||||
|
||||
endchoice
|
@ -1,71 +0,0 @@
|
||||
############################################################################
|
||||
# calypso/Make.defs
|
||||
#
|
||||
# Copyright (C) 2007, 2013-2015 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
|
||||
CMN_ASRCS += up_nommuhead.S vfork.S
|
||||
CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c
|
||||
CMN_CSRCS += up_createstack.c up_dataabort.c up_mdelay.c up_udelay.c
|
||||
CMN_CSRCS += up_doirq.c up_exit.c up_idle.c up_initialstate.c up_initialize.c
|
||||
CMN_CSRCS += up_interruptcontext.c up_prefetchabort.c up_releasepending.c
|
||||
CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c
|
||||
CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_syscall.c up_unblocktask.c
|
||||
CMN_CSRCS += up_undefinedinsn.c up_usestack.c calypso_power.c up_vfork.c
|
||||
|
||||
ifeq ($(CONFIG_ELF),y)
|
||||
CMN_CSRCS += up_elf.c
|
||||
else ifeq ($(CONFIG_MODULE),y)
|
||||
CMN_CSRCS += up_elf.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_STACK_COLORATION),y)
|
||||
CMN_CSRCS += up_checkstack.c
|
||||
endif
|
||||
|
||||
CHIP_ASRCS = calypso_lowputc.S
|
||||
CHIP_CSRCS = calypso_irq.c calypso_heap.c calypso_serial.c clock.c
|
||||
CHIP_CSRCS += calypso_uwire.c calypso_armio.c calypso_keypad.c
|
||||
|
||||
ifeq ($(CONFIG_SPI),y)
|
||||
CHIP_CSRCS += calypso_spi.c
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_SCHED_TICKLESS),y)
|
||||
CHIP_CSRCS += calypso_timer.c
|
||||
endif
|
@ -1,103 +0,0 @@
|
||||
/****************************************************************************
|
||||
* 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) (BASE_ADDR_ARMIO + (x))
|
||||
|
||||
enum armio_reg {
|
||||
LATCH_IN = 0x00,
|
||||
LATCH_OUT = 0x02,
|
||||
IO_CNTL = 0x04,
|
||||
CNTL_REG = 0x06,
|
||||
LOAD_TIM = 0x08,
|
||||
KBR_LATCH_REG = 0x0a,
|
||||
KBC_REG = 0x0c,
|
||||
BUZZ_LIGHT_REG = 0x0e,
|
||||
LIGHT_LEVEL = 0x10,
|
||||
BUZZER_LEVEL = 0x12,
|
||||
GPIO_EVENT_MODE = 0x14,
|
||||
KBD_GPIO_INT = 0x16,
|
||||
KBD_GPIO_MASKIT = 0x18,
|
||||
GPIO_DEBOUNCING = 0x1a,
|
||||
GPIO_LATCH = 0x1c,
|
||||
};
|
||||
|
||||
#define KBD_INT (1 << 0)
|
||||
#define GPIO_INT (1 << 1)
|
||||
|
||||
/****************************************************************************
|
||||
* ARMIO interrupt handler
|
||||
* forward keypad events
|
||||
* forward GPIO events
|
||||
****************************************************************************/
|
||||
|
||||
static int kbd_gpio_irq(int irq, uint32_t *regs)
|
||||
{
|
||||
return calypso_kbd_irq(irq, regs);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Initialize ARMIO
|
||||
****************************************************************************/
|
||||
|
||||
void calypso_armio(void)
|
||||
{
|
||||
/* Enable ARMIO clock */
|
||||
|
||||
putreg16(1 << 5, ARMIO_REG(CNTL_REG));
|
||||
|
||||
/* Mask GPIO interrupt and keypad interrupt */
|
||||
|
||||
putreg16(KBD_INT | GPIO_INT, ARMIO_REG(KBD_GPIO_MASKIT));
|
||||
|
||||
/* Attach and enable the interrupt */
|
||||
|
||||
irq_attach(IRQ_KEYPAD_GPIO, (xcpt_t)kbd_gpio_irq);
|
||||
up_enable_irq(IRQ_KEYPAD_GPIO);
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
/* 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
|
@ -1,357 +0,0 @@
|
||||
/****************************************************************************
|
||||
* 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 <arch/calypso/clock.h>
|
||||
|
||||
#include "arm.h"
|
||||
#include "up_internal.h"
|
||||
#include "up_arch.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define BASE_ADDR_IRQ 0xfffffa00
|
||||
#define BASE_ADDR_IBOOT_EXC 0x0080001C
|
||||
|
||||
enum irq_reg
|
||||
{
|
||||
IT_REG1 = 0x00,
|
||||
IT_REG2 = 0x02,
|
||||
MASK_IT_REG1 = 0x08,
|
||||
MASK_IT_REG2 = 0x0a,
|
||||
IRQ_NUM = 0x10,
|
||||
FIQ_NUM = 0x12,
|
||||
IRQ_CTRL = 0x14,
|
||||
};
|
||||
|
||||
#define ILR_IRQ(x) (0x20 + (x*2))
|
||||
#define IRQ_REG(x) (BASE_ADDR_IRQ + (x))
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* g_current_regs[] holds a references to the current interrupt level
|
||||
* register storage structure. If is non-NULL only during interrupt
|
||||
* processing. Access to g_current_regs[] must be through the macro
|
||||
* CURRENT_REGS for portability.
|
||||
*/
|
||||
|
||||
volatile uint32_t *g_current_regs[1];
|
||||
extern uint32_t _exceptions;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static uint8_t default_irq_prio[] =
|
||||
{
|
||||
[IRQ_WATCHDOG] = 0xff,
|
||||
[IRQ_TIMER1] = 0xff,
|
||||
[IRQ_TIMER2] = 0xff,
|
||||
[IRQ_TSP_RX] = 0,
|
||||
[IRQ_TPU_FRAME] = 3,
|
||||
[IRQ_TPU_PAGE] = 0xff,
|
||||
[IRQ_SIMCARD] = 0xff,
|
||||
[IRQ_UART_MODEM] = 8,
|
||||
[IRQ_KEYPAD_GPIO] = 4,
|
||||
[IRQ_RTC_TIMER] = 9,
|
||||
[IRQ_RTC_ALARM_I2C] = 10,
|
||||
[IRQ_ULPD_GAUGING] = 2,
|
||||
[IRQ_EXTERNAL] = 12,
|
||||
[IRQ_SPI] = 0xff,
|
||||
[IRQ_DMA] = 0xff,
|
||||
[IRQ_API] = 0xff,
|
||||
[IRQ_SIM_DETECT] = 0,
|
||||
[IRQ_EXTERNAL_FIQ] = 7,
|
||||
[IRQ_UART_IRDA] = 2,
|
||||
[IRQ_ULPD_GSM_TIMER] = 1,
|
||||
[IRQ_GEA] = 0xff,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void _irq_enable(enum irq_nr nr, int enable)
|
||||
{
|
||||
uintptr_t reg = IRQ_REG(MASK_IT_REG1);
|
||||
uint16_t val;
|
||||
|
||||
if (nr > 15)
|
||||
{
|
||||
reg = IRQ_REG(MASK_IT_REG2);
|
||||
nr -= 16;
|
||||
}
|
||||
|
||||
val = getreg16(reg);
|
||||
if (enable)
|
||||
{
|
||||
val &= ~(1 << nr);
|
||||
}
|
||||
else
|
||||
{
|
||||
val |= (1 << nr);
|
||||
}
|
||||
|
||||
putreg16(val, reg);
|
||||
}
|
||||
|
||||
static void set_default_priorities(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(default_irq_prio); i++)
|
||||
{
|
||||
uint16_t val;
|
||||
uint8_t prio = default_irq_prio[i];
|
||||
|
||||
if (prio > 31)
|
||||
{
|
||||
prio = 31;
|
||||
}
|
||||
|
||||
val = getreg16(IRQ_REG(ILR_IRQ(i)));
|
||||
val &= ~(0x1f << 2);
|
||||
val |= prio << 2;
|
||||
|
||||
/* Make edge mode default. Hopefully causes less trouble */
|
||||
|
||||
val |= 0x02;
|
||||
|
||||
putreg16(val, IRQ_REG(ILR_IRQ(i)));
|
||||
}
|
||||
}
|
||||
|
||||
/* Install the exception handlers to where the ROM loader jumps */
|
||||
|
||||
static void calypso_exceptions_install(void)
|
||||
{
|
||||
uint32_t *exceptions_dst = (uint32_t *) BASE_ADDR_IBOOT_EXC;
|
||||
uint32_t *exceptions_src = &_exceptions;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
*exceptions_dst++ = *exceptions_src++;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_irqinitialize
|
||||
*
|
||||
* Description:
|
||||
* Setup the IRQ and FIQ controllers
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_irqinitialize(void)
|
||||
{
|
||||
/* Prepare hardware */
|
||||
|
||||
calypso_exceptions_install();
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
/* Switch to internal ROM */
|
||||
|
||||
calypso_bootrom(1);
|
||||
|
||||
/* Set default priorities */
|
||||
|
||||
set_default_priorities();
|
||||
|
||||
/* Mask all interrupts off */
|
||||
|
||||
putreg16(0xffff, IRQ_REG(MASK_IT_REG1));
|
||||
putreg16(0xffff, IRQ_REG(MASK_IT_REG2));
|
||||
|
||||
/* clear all pending interrupts */
|
||||
putreg16(0, IRQ_REG(IT_REG1));
|
||||
putreg16(0, IRQ_REG(IT_REG2));
|
||||
|
||||
/* Enable interrupts globally to the ARM core */
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
up_irq_restore(SVC_MODE | PSR_F_BIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_disable_irq
|
||||
*
|
||||
* Description:
|
||||
* Disable the IRQ specified by 'irq'
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_disable_irq(int irq)
|
||||
{
|
||||
if ((unsigned)irq < NR_IRQS)
|
||||
{
|
||||
_irq_enable(irq, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_enable_irq
|
||||
*
|
||||
* Description:
|
||||
* Enable the IRQ specified by 'irq'
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_enable_irq(int irq)
|
||||
{
|
||||
if ((unsigned)irq < NR_IRQS)
|
||||
{
|
||||
_irq_enable(irq, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_prioritize_irq
|
||||
*
|
||||
* Description:
|
||||
* Set the priority of an IRQ.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_ARCH_IRQPRIO
|
||||
int up_prioritize_irq(int nr, int prio)
|
||||
{
|
||||
uint16_t val;
|
||||
|
||||
if (prio == -1)
|
||||
{
|
||||
prio = default_irq_prio[nr];
|
||||
}
|
||||
|
||||
if (prio > 31)
|
||||
{
|
||||
prio = 31;
|
||||
}
|
||||
|
||||
val = prio << 2;
|
||||
putreg16(val, IRQ_REG(ILR_IRQ(nr)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Entry point for interrupts
|
||||
****************************************************************************/
|
||||
|
||||
void up_decodeirq(uint32_t *regs)
|
||||
{
|
||||
uint8_t num, tmp;
|
||||
uint32_t *saved_regs;
|
||||
|
||||
/* XXX: What is this???
|
||||
* Passed to but ignored in IRQ handlers
|
||||
* Only valid meaning is apparently non-NULL == IRQ context */
|
||||
|
||||
saved_regs = (uint32_t *)CURRENT_REGS;
|
||||
CURRENT_REGS = regs;
|
||||
|
||||
/* Detect & deliver the IRQ */
|
||||
|
||||
num = getreg8(IRQ_REG(IRQ_NUM)) & 0x1f;
|
||||
irq_dispatch(num, regs);
|
||||
|
||||
/* Start new IRQ agreement */
|
||||
|
||||
tmp = getreg8(IRQ_REG(IRQ_CTRL));
|
||||
tmp |= 0x01;
|
||||
putreg8(tmp, IRQ_REG(IRQ_CTRL));
|
||||
|
||||
CURRENT_REGS = saved_regs;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Entry point for FIQs
|
||||
****************************************************************************/
|
||||
|
||||
void calypso_fiq(void)
|
||||
{
|
||||
uint8_t num, tmp;
|
||||
uint32_t *regs;
|
||||
|
||||
/* XXX: What is this???
|
||||
* Passed to but ignored in IRQ handlers
|
||||
* Only valid meaning is apparently non-NULL == IRQ context */
|
||||
|
||||
regs = (uint32_t *)CURRENT_REGS;
|
||||
CURRENT_REGS = (uint32_t *)#
|
||||
|
||||
/* Detect & deliver like an IRQ but we are in FIQ context */
|
||||
|
||||
num = getreg8(IRQ_REG(FIQ_NUM)) & 0x1f;
|
||||
irq_dispatch(num, regs);
|
||||
|
||||
/* Start new FIQ agreement */
|
||||
|
||||
tmp = getreg8(IRQ_REG(IRQ_CTRL));
|
||||
tmp |= 0x02;
|
||||
putreg8(tmp, IRQ_REG(IRQ_CTRL));
|
||||
|
||||
CURRENT_REGS = regs;
|
||||
}
|
@ -1,385 +0,0 @@
|
||||
/****************************************************************************
|
||||
* Driver for Calypso keypad hardware
|
||||
*
|
||||
* 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/semaphore.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <arch/calypso/defines.h>
|
||||
#include <arch/calypso/memory.h>
|
||||
#include <arch/calypso/timer.h>
|
||||
#include <arch/calypso/armio.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)
|
||||
|
||||
/****************************************************************************
|
||||
* Decoder functions for matrix and power button
|
||||
****************************************************************************/
|
||||
|
||||
static int btn_dec(uint32_t * btn_state, uint8_t col, uint8_t reg,
|
||||
char *buf, size_t buflen, size_t * len)
|
||||
{
|
||||
uint8_t diff = (*btn_state ^ reg) & 0x1f;
|
||||
|
||||
while (diff)
|
||||
{
|
||||
uint8_t val = diff & ~(diff - 1);
|
||||
uint8_t sc = val >> 1;
|
||||
sc |= sc << 2;
|
||||
sc += col;
|
||||
sc += (sc & 0x20) ? 0x26 : 0x3f;
|
||||
|
||||
if (reg & val)
|
||||
{
|
||||
sc |= 0x20;
|
||||
}
|
||||
|
||||
/* Check for space in buffer and dispatch */
|
||||
|
||||
if (*len < buflen)
|
||||
{
|
||||
buf[(*len)++] = sc;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Only change diff if dispatched/buffer not full */
|
||||
|
||||
diff ^= val;
|
||||
}
|
||||
|
||||
/* Store new state of the buttons (but only if they where dispatch) */
|
||||
|
||||
*btn_state >>= 5;
|
||||
#ifdef INCLUDE_ALL_COLS
|
||||
*btn_state |= (reg ^ diff) << 20;
|
||||
#else
|
||||
*btn_state |= (reg ^ diff) << 15;
|
||||
#endif
|
||||
return diff;
|
||||
}
|
||||
|
||||
static int pwr_btn_dec(uint32_t * state, uint8_t reg, char *buf, size_t * len)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
/* Check for pressed power button. If pressed, ignore other
|
||||
* buttons since it collides with an entire row.
|
||||
*/
|
||||
|
||||
if (~*state & 0x80000000)
|
||||
{
|
||||
buf[0] = 'z';
|
||||
*len = 1;
|
||||
*state |= 0x80000000;
|
||||
}
|
||||
|
||||
return 1; /* break loop in caller */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check for released power button. */
|
||||
|
||||
if (*state & 0x80000000)
|
||||
{
|
||||
buf[0] = 'Z';
|
||||
*len = 1;
|
||||
|
||||
*state &= 0x7fffffff;
|
||||
|
||||
/* Don't scan others when released; might trigger
|
||||
* false keystrokes otherwise
|
||||
*/
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0; /* Continue with other columns */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Keypad: Fileops Prototypes and Structures
|
||||
****************************************************************************/
|
||||
|
||||
typedef FAR struct file file_t;
|
||||
|
||||
static int keypad_open(file_t * filep);
|
||||
static int keypad_close(file_t * filep);
|
||||
static ssize_t keypad_read(file_t * filep, FAR char *buffer, size_t buflen);
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
static int keypad_poll(file_t * filep, FAR struct pollfd *fds, bool setup);
|
||||
#endif
|
||||
|
||||
static const struct file_operations keypad_ops =
|
||||
{
|
||||
keypad_open, /* open */
|
||||
keypad_close, /* close */
|
||||
keypad_read, /* read */
|
||||
0, /* write */
|
||||
0, /* seek */
|
||||
0, /* ioctl */
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
keypad_poll /* poll */
|
||||
#endif
|
||||
};
|
||||
|
||||
static sem_t kbdsem;
|
||||
|
||||
/****************************************************************************
|
||||
* Keypad: Fileops
|
||||
****************************************************************************/
|
||||
|
||||
static int keypad_open(file_t * filep)
|
||||
{
|
||||
register uint16_t reg;
|
||||
|
||||
/* Unmask keypad interrupt */
|
||||
|
||||
reg = readw(ARMIO_REG(KBD_GPIO_MASKIT));
|
||||
writew(reg & ~KBD_INT, ARMIO_REG(KBD_GPIO_MASKIT));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int keypad_close(file_t * filep)
|
||||
{
|
||||
register uint16_t reg;
|
||||
|
||||
/* Mask keypad interrupt */
|
||||
|
||||
reg = readw(ARMIO_REG(KBD_GPIO_MASKIT));
|
||||
writew(reg | KBD_INT, ARMIO_REG(KBD_GPIO_MASKIT));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static ssize_t keypad_read(file_t * filep, FAR char *buf, size_t buflen)
|
||||
{
|
||||
static uint32_t btn_state = 0;
|
||||
register uint16_t reg;
|
||||
uint16_t col, col_mask;
|
||||
size_t len = 0;
|
||||
|
||||
if (buf == NULL || buflen < 1)
|
||||
{
|
||||
/* Well... nothing to do */
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
retry:
|
||||
col = 1;
|
||||
col_mask = 0x1e;
|
||||
|
||||
if (!btn_state)
|
||||
{
|
||||
/* Drive all cols low such that all buttons cause events */
|
||||
|
||||
writew(0, ARMIO_REG(KBC_REG));
|
||||
|
||||
/* No button currently pressed, use IRQ */
|
||||
|
||||
reg = readw(ARMIO_REG(KBD_GPIO_MASKIT));
|
||||
writew(reg & ~KBD_INT, ARMIO_REG(KBD_GPIO_MASKIT));
|
||||
sem_wait(&kbdsem);
|
||||
}
|
||||
else
|
||||
{
|
||||
writew(0x1f, ARMIO_REG(KBC_REG));
|
||||
usleep(80000);
|
||||
}
|
||||
|
||||
/* Scan columns */
|
||||
|
||||
#ifdef INCLUDE_ALL_COLS
|
||||
while (col <= 6)
|
||||
{
|
||||
#else
|
||||
while (col <= 5)
|
||||
{
|
||||
#endif
|
||||
/* Read keypad latch and immediately set new column since
|
||||
* synchronization takes about 5usec. For the 1st round, the
|
||||
* interrupt has prepared this and the context switch takes
|
||||
* long enough to serve as a delay.
|
||||
*/
|
||||
|
||||
reg = readw(ARMIO_REG(KBR_LATCH_REG));
|
||||
writew(col_mask, ARMIO_REG(KBC_REG));
|
||||
|
||||
/* Turn pressed buttons into 1s */
|
||||
|
||||
reg = 0x1f & ~reg;
|
||||
|
||||
if (col == 1)
|
||||
{
|
||||
/* Power/End switch */
|
||||
|
||||
if (pwr_btn_dec(&btn_state, reg, buf, &len))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Non-power switches */
|
||||
|
||||
if (btn_dec(&btn_state, col, reg, buf, buflen, &len))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Select next column and respective mask */
|
||||
|
||||
col_mask = 0x1f & ~(1 << col++);
|
||||
|
||||
/* We have to wait for synchronization of the inputs. The
|
||||
* processing is too fast if no/few buttons are processed.
|
||||
*/
|
||||
|
||||
usleep(5);
|
||||
|
||||
/* XXX: usleep seems to suffer hugh overhead. Better this!?
|
||||
* If nothing else can be done, it's overhead still wastes
|
||||
* time 'usefully'.
|
||||
*/
|
||||
/* sched_yield(); up_udelay(2); */
|
||||
}
|
||||
|
||||
/* If we don't have anything to return, retry to avoid EOF */
|
||||
|
||||
if (!len)
|
||||
{
|
||||
goto retry;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Keypad interrupt handler
|
||||
* mask interrupts
|
||||
* prepare column drivers for scan
|
||||
* posts keypad semaphore
|
||||
****************************************************************************/
|
||||
|
||||
int calypso_kbd_irq(int irq, uint32_t * regs)
|
||||
{
|
||||
register uint16_t reg;
|
||||
|
||||
/* Mask keypad interrupt */
|
||||
|
||||
reg = readw(ARMIO_REG(KBD_GPIO_MASKIT));
|
||||
writew(reg | KBD_INT, ARMIO_REG(KBD_GPIO_MASKIT));
|
||||
|
||||
/* Turn off column drivers */
|
||||
|
||||
writew(0x1f, ARMIO_REG(KBC_REG));
|
||||
|
||||
/* Let the userspace know */
|
||||
|
||||
sem_post(&kbdsem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Initialize device, add /dev/... nodes
|
||||
****************************************************************************/
|
||||
|
||||
void up_keypad(void)
|
||||
{
|
||||
/* kbssem semaphore helps leaving IRQ ctx as soon as possible. This
|
||||
* semaphore is used for signaling and, hence, should not have priority
|
||||
* inheritance enabled.
|
||||
*/
|
||||
|
||||
sem_init(&kbdsem, 0, 0);
|
||||
sem_setprotocol(&kbdsem, SEM_PRIO_NONE);
|
||||
|
||||
/* Drive cols low in idle state such that all buttons cause events */
|
||||
|
||||
writew(0, ARMIO_REG(KBC_REG));
|
||||
|
||||
(void)register_driver("/dev/keypad", &keypad_ops, 0444, NULL);
|
||||
}
|
||||
|
||||
int keypad_kbdinit(void)
|
||||
{
|
||||
calypso_armio();
|
||||
up_keypad();
|
||||
|
||||
return OK;
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
|
||||
#include "calypso_spi.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_power_off
|
||||
*
|
||||
* Description:
|
||||
* Power off the board.
|
||||
*
|
||||
* If this function returns, then it was not possible to power-off the
|
||||
* board due to some other constraints.
|
||||
*
|
||||
* Input Parameters:
|
||||
* status - Status information provided with the power off event.
|
||||
*
|
||||
* Returned Value:
|
||||
* If this function returns, then it was not possible to power-off the
|
||||
* board due to some constraints. The return value int this case is a
|
||||
* board-specific reason for the failure to shutdown.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BOARDCTL_POWEROFF
|
||||
int board_power_off(int status)
|
||||
{
|
||||
struct spi_dev_s *spi = calypso_spibus_initialize(0);
|
||||
uint16_t tx;
|
||||
|
||||
SPI_SETBITS(spi, 16);
|
||||
(void)SPI_HWFEATURES(spi, 0);
|
||||
|
||||
tx = (1 << 6) | (1 << 1);
|
||||
SPI_SNDBLOCK(spi, &tx, 1);
|
||||
|
||||
tx = (1 << 6) | (30 << 1);
|
||||
SPI_SNDBLOCK(spi, &tx, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -1,968 +0,0 @@
|
||||
/****************************************************************************
|
||||
* 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, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define BASE_BAUD 115200
|
||||
|
||||
#if defined(CONFIG_UART_IRDA_HWFLOWCONTROL) || defined(CONFIG_UART_MODEM_HWFLOWCONTROL)
|
||||
# define CONFIG_UART_HWFLOWCONTROL
|
||||
#endif
|
||||
|
||||
#if UART_FCR_OFFS == UART_EFR_OFFS
|
||||
# define UART_MULTIPLEX_REGS
|
||||
|
||||
/* HW flow control not supported yet */
|
||||
|
||||
# undef CONFIG_UART_HWFLOWCONTROL
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct uart_regs_s
|
||||
{
|
||||
uint32_t ier;
|
||||
uint32_t lcr;
|
||||
uint32_t fcr;
|
||||
#ifdef CONFIG_UART_HWFLOWCONTROL
|
||||
uint32_t efr;
|
||||
uint32_t tcr;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct up_dev_s
|
||||
{
|
||||
unsigned int uartbase; /* Base address of UART registers */
|
||||
unsigned int baud_base; /* Base baud for conversions */
|
||||
unsigned int baud; /* Configured baud */
|
||||
uint8_t xmit_fifo_size; /* Size of transmit FIFO */
|
||||
uint8_t irq; /* IRQ associated with this UART */
|
||||
uint8_t parity; /* 0=none, 1=odd, 2=even */
|
||||
uint8_t bits; /* Number of bits (7 or 8) */
|
||||
#ifdef CONFIG_UART_HWFLOWCONTROL
|
||||
bool flowcontrol; /* true: Hardware flow control
|
||||
* is enabled. */
|
||||
#endif
|
||||
bool stopbits2; /* true: Configure with 2
|
||||
* stop bits instead of 1 */
|
||||
struct uart_regs_s regs; /* Shadow copy of readonly regs */
|
||||
|
||||
#ifdef CONFIG_SERCOMM_CONSOLE
|
||||
bool sercomm; /* Call sercomm in interrupt if true */
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int up_setup(struct uart_dev_s *dev);
|
||||
static void up_shutdown(struct uart_dev_s *dev);
|
||||
static int up_attach(struct uart_dev_s *dev);
|
||||
static void up_detach(struct uart_dev_s *dev);
|
||||
static int up_interrupt(int irq, void *context);
|
||||
static int up_ioctl(struct file *filep, int cmd, unsigned long arg);
|
||||
static int up_receive(struct uart_dev_s *dev, unsigned int *status);
|
||||
static void up_rxint(struct uart_dev_s *dev, bool enable);
|
||||
static bool up_rxavailable(struct uart_dev_s *dev);
|
||||
static void up_send(struct uart_dev_s *dev, int ch);
|
||||
static void up_txint(struct uart_dev_s *dev, bool enable);
|
||||
static bool up_txready(struct uart_dev_s *dev);
|
||||
static bool up_txempty(struct uart_dev_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct uart_ops_s g_uart_ops =
|
||||
{
|
||||
.setup = up_setup,
|
||||
.shutdown = up_shutdown,
|
||||
.attach = up_attach,
|
||||
.detach = up_detach,
|
||||
.ioctl = up_ioctl,
|
||||
.receive = up_receive,
|
||||
.rxint = up_rxint,
|
||||
.rxavailable = up_rxavailable,
|
||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||
.rxflowcontrol = NULL,
|
||||
#endif
|
||||
.send = up_send,
|
||||
.txint = up_txint,
|
||||
.txready = up_txready,
|
||||
.txempty = up_txempty,
|
||||
};
|
||||
|
||||
/* I/O buffers */
|
||||
|
||||
static char g_irdarxbuffer[CONFIG_UART_IRDA_RXBUFSIZE];
|
||||
static char g_irdatxbuffer[CONFIG_UART_IRDA_TXBUFSIZE];
|
||||
static char g_modemrxbuffer[CONFIG_UART_MODEM_RXBUFSIZE];
|
||||
static char g_modemtxbuffer[CONFIG_UART_MODEM_TXBUFSIZE];
|
||||
|
||||
/* This describes the state of the C5471 serial IRDA port. */
|
||||
|
||||
static struct up_dev_s g_irdapriv =
|
||||
{
|
||||
.xmit_fifo_size = UART_IRDA_XMIT_FIFO_SIZE,
|
||||
.baud_base = BASE_BAUD,
|
||||
.uartbase = UART_IRDA_BASE,
|
||||
.baud = CONFIG_UART_IRDA_BAUD,
|
||||
.irq = UART_IRQ_IRDA,
|
||||
.parity = CONFIG_UART_IRDA_PARITY,
|
||||
.bits = CONFIG_UART_IRDA_BITS,
|
||||
#ifdef CONFIG_UART_IRDA_HWFLOWCONTROL
|
||||
.flowcontrol = true,
|
||||
#endif
|
||||
.stopbits2 = CONFIG_UART_IRDA_2STOP,
|
||||
|
||||
#ifdef CONFIG_SERCOMM_CONSOLE
|
||||
.sercomm = false,
|
||||
#endif
|
||||
};
|
||||
|
||||
static uart_dev_t g_irdaport =
|
||||
{
|
||||
.recv =
|
||||
{
|
||||
.size = CONFIG_UART_IRDA_RXBUFSIZE,
|
||||
.buffer = g_irdarxbuffer,
|
||||
},
|
||||
.xmit =
|
||||
{
|
||||
.size = CONFIG_UART_IRDA_TXBUFSIZE,
|
||||
.buffer = g_irdatxbuffer,
|
||||
},
|
||||
.ops = &g_uart_ops,
|
||||
.priv = &g_irdapriv,
|
||||
};
|
||||
|
||||
/* This describes the state of the C5471 serial Modem port. */
|
||||
|
||||
static struct up_dev_s g_modempriv =
|
||||
{
|
||||
.xmit_fifo_size = UART_XMIT_FIFO_SIZE,
|
||||
.baud_base = BASE_BAUD,
|
||||
.uartbase = UART_MODEM_BASE,
|
||||
.baud = CONFIG_UART_MODEM_BAUD,
|
||||
.irq = UART_IRQ_MODEM,
|
||||
.parity = CONFIG_UART_MODEM_PARITY,
|
||||
.bits = CONFIG_UART_MODEM_BITS,
|
||||
#ifdef CONFIG_UART_MODEM_HWFLOWCONTROL
|
||||
.flowcontrol = true,
|
||||
#endif
|
||||
.stopbits2 = CONFIG_UART_MODEM_2STOP,
|
||||
|
||||
#ifdef CONFIG_SERCOMM_CONSOLE
|
||||
.sercomm = false,
|
||||
#endif
|
||||
};
|
||||
|
||||
static uart_dev_t g_modemport =
|
||||
{
|
||||
.recv =
|
||||
{
|
||||
.size = CONFIG_UART_MODEM_RXBUFSIZE,
|
||||
.buffer = g_modemrxbuffer,
|
||||
},
|
||||
.xmit =
|
||||
{
|
||||
.size = CONFIG_UART_MODEM_TXBUFSIZE,
|
||||
.buffer = g_modemtxbuffer,
|
||||
},
|
||||
.ops = &g_uart_ops,
|
||||
.priv = &g_modempriv,
|
||||
};
|
||||
|
||||
/* Now, which one with be tty0/console and which tty1? */
|
||||
|
||||
#ifdef CONFIG_SERIAL_IRDA_CONSOLE
|
||||
# define CONSOLE_DEV g_irdaport
|
||||
# define TTYS0_DEV g_irdaport
|
||||
# define TTYS1_DEV g_modemport
|
||||
#else
|
||||
# define CONSOLE_DEV g_modemport
|
||||
# define TTYS0_DEV g_modemport
|
||||
# define TTYS1_DEV g_irdaport
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_inserial
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t up_inserial(struct up_dev_s *priv, uint32_t offset)
|
||||
{
|
||||
#if UART_REGISTER_BITS == 8
|
||||
return getreg8(priv->uartbase + offset);
|
||||
#elif UART_REGISTER_BITS == 32
|
||||
return getreg32(priv->uartbase + offset);
|
||||
#else
|
||||
#error Unsupported number of bits set in UART_REGISTER_BITS
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_serialout
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_serialout(struct up_dev_s *priv, uint32_t offset, uint32_t value)
|
||||
{
|
||||
#if UART_REGISTER_BITS == 8
|
||||
putreg8(value & 0xff, priv->uartbase + offset);
|
||||
#elif UART_REGISTER_BITS == 32
|
||||
putreg32(value, priv->uartbase + offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_disableuartint
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_disableuartint(struct up_dev_s *priv, uint16_t *ier)
|
||||
{
|
||||
if (ier)
|
||||
{
|
||||
*ier = priv->regs.ier & UART_IER_INTMASK;
|
||||
}
|
||||
priv->regs.ier &= ~UART_IER_INTMASK;
|
||||
up_serialout(priv, UART_IER_OFFS, priv->regs.ier);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_restoreuartint
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_restoreuartint(struct up_dev_s *priv, uint16_t ier)
|
||||
{
|
||||
priv->regs.ier |= ier & (UART_IER_RECVINT | UART_IER_XMITINT);
|
||||
up_serialout(priv, UART_IER_OFFS, priv->regs.ier);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_waittxready
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_waittxready(struct up_dev_s *priv)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
for (tmp = 1000 ; tmp > 0 ; tmp--)
|
||||
{
|
||||
if ((up_inserial(priv, UART_SSR_OFFS) & UART_SSR_TXFULL) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/****************************************************************************
|
||||
* Name: up_disablebreaks
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_disablebreaks(struct up_dev_s *priv)
|
||||
{
|
||||
priv->regs.lcr &= ~UART_LCR_BOC;
|
||||
up_serialout(priv, UART_LCR_OFFS, priv->regs.lcr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_enablebreaks
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_enablebreaks(struct up_dev_s *priv)
|
||||
{
|
||||
priv->regs.lcr |= UART_LCR_BOC;
|
||||
up_serialout(priv, UART_LCR_OFFS, priv->regs.lcr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_setrate
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_setrate(struct up_dev_s *priv, unsigned int rate)
|
||||
{
|
||||
uint32_t div_bit_rate;
|
||||
|
||||
switch (rate)
|
||||
{
|
||||
case 115200:
|
||||
div_bit_rate = BAUD_115200;
|
||||
break;
|
||||
case 57600:
|
||||
div_bit_rate = BAUD_57600;
|
||||
break;
|
||||
case 38400:
|
||||
div_bit_rate = BAUD_38400;
|
||||
break;
|
||||
case 19200:
|
||||
div_bit_rate = BAUD_19200;
|
||||
break;
|
||||
case 4800:
|
||||
div_bit_rate = BAUD_4800;
|
||||
break;
|
||||
case 2400:
|
||||
div_bit_rate = BAUD_2400;
|
||||
break;
|
||||
case 1200:
|
||||
div_bit_rate = BAUD_1200;
|
||||
break;
|
||||
case 9600:
|
||||
default:
|
||||
div_bit_rate = BAUD_9600;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef UART_DIV_BIT_RATE_OFFS
|
||||
up_serialout(priv, UART_DIV_BIT_RATE_OFFS, div_bit_rate);
|
||||
#else
|
||||
up_serialout(priv, UART_DIV_LOW_OFFS, div_bit_rate);
|
||||
up_serialout(priv, UART_DIV_HIGH_OFFS, div_bit_rate >> 8);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_setup
|
||||
*
|
||||
* Description:
|
||||
* Configure the UART baud, bits, parity, fifos, etc. This
|
||||
* method is called the first time that the serial port is
|
||||
* opened.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include <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();
|
||||
}
|
||||
priv = (struct up_dev_s *)dev->priv;
|
||||
|
||||
cause = up_inserial(priv, UART_ISR_OFFS) & 0x0000003f;
|
||||
|
||||
if ((cause & 0x0000000c) == 0x0000000c)
|
||||
{
|
||||
uint32_t ier_val = 0;
|
||||
|
||||
/* Is this an interrupt from the IrDA UART? */
|
||||
|
||||
if (irq == UART_IRQ_IRDA)
|
||||
{
|
||||
/* Save the currently enabled IrDA UART interrupts
|
||||
* so that we can restore the IrDA interrupt state
|
||||
* below.
|
||||
*/
|
||||
|
||||
ier_val = up_inserial(priv, UART_IER_OFFS);
|
||||
|
||||
/* Then disable all IrDA UART interrupts */
|
||||
|
||||
up_serialout(priv, UART_IER_OFFS, 0);
|
||||
}
|
||||
|
||||
/* Receive characters from the RX fifo */
|
||||
|
||||
#ifdef CONFIG_SERCOMM_CONSOLE
|
||||
if (priv->sercomm)
|
||||
{
|
||||
sercomm_recvchars(dev);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
uart_recvchars(dev);
|
||||
}
|
||||
|
||||
/* read UART_RHR to clear int condition
|
||||
* toss = up_inserialchar(priv,&status);
|
||||
*/
|
||||
|
||||
/* Is this an interrupt from the IrDA UART? */
|
||||
|
||||
if (irq == UART_IRQ_IRDA)
|
||||
{
|
||||
/* Restore the IrDA UART interrupt enables */
|
||||
|
||||
up_serialout(priv, UART_IER_OFFS, ier_val);
|
||||
}
|
||||
}
|
||||
else if ((cause & 0x0000000c) == 0x00000004)
|
||||
{
|
||||
#ifdef CONFIG_SERCOMM_CONSOLE
|
||||
if (priv->sercomm)
|
||||
{
|
||||
sercomm_recvchars(dev);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
uart_recvchars(dev);
|
||||
}
|
||||
}
|
||||
|
||||
if ((cause & 0x00000002) != 0)
|
||||
{
|
||||
#ifdef CONFIG_SERCOMM_CONSOLE
|
||||
if (priv->sercomm)
|
||||
{
|
||||
sercomm_xmitchars(dev);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
uart_xmitchars(dev);
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_ioctl
|
||||
*
|
||||
* Description:
|
||||
* All ioctl calls will be routed through this method
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
struct inode *inode = filep->f_inode;
|
||||
struct uart_dev_s *dev = inode->i_private;
|
||||
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
||||
int ret = OK;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT
|
||||
case TIOCSERGSTRUCT:
|
||||
{
|
||||
struct up_dev_s *user = (struct up_dev_s *)arg;
|
||||
if (!user)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(user, dev, sizeof(struct up_dev_s));
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
|
||||
{
|
||||
irqstate_t flags = enter_critical_section();
|
||||
up_enablebreaks(priv);
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
|
||||
{
|
||||
irqstate_t flags;
|
||||
flags = enter_critical_section();
|
||||
up_disablebreaks(priv);
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_receive
|
||||
*
|
||||
* Description:
|
||||
* Called (usually) from the interrupt level to receive one character from
|
||||
* the UART. Error bits associated with the receipt are provided in the
|
||||
* the return 'status'.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int up_receive(struct uart_dev_s *dev, unsigned int *status)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
||||
uint32_t rhr;
|
||||
uint32_t lsr;
|
||||
|
||||
/* Construct a 16bit status word that uses the high byte to
|
||||
* hold the status bits associated with framing,parity,break
|
||||
* and a low byte that holds error bits of LSR for
|
||||
* conditions such as overflow, etc.
|
||||
*/
|
||||
|
||||
rhr = up_inserial(priv, UART_RHR_OFFS);
|
||||
lsr = up_inserial(priv, UART_LSR_OFFS);
|
||||
|
||||
*status = (unsigned int)((rhr & 0x0000ff00) | (lsr & 0x000000ff));
|
||||
|
||||
return rhr & 0x000000ff;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_rxint
|
||||
*
|
||||
* Description:
|
||||
* Call to enable or disable RX interrupts
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void up_rxint(struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
||||
if (enable)
|
||||
{
|
||||
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
|
||||
priv->regs.ier |= UART_IER_RECVINT;
|
||||
up_serialout(priv, UART_IER_OFFS, priv->regs.ier);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->regs.ier &= ~UART_IER_RECVINT;
|
||||
up_serialout(priv, UART_IER_OFFS, priv->regs.ier);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_rxavailable
|
||||
*
|
||||
* Description:
|
||||
* Return true if the receive fifo is not empty
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool up_rxavailable(struct uart_dev_s *dev)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
||||
return up_inserial(priv, UART_LSR_OFFS) & UART_RX_FIFO_NOEMPTY;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_send
|
||||
*
|
||||
* Description:
|
||||
* This method will send one byte on the UART
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void up_send(struct uart_dev_s *dev, int ch)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
||||
up_serialout(priv, UART_THR_OFFS, (uint8_t)ch);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_txint
|
||||
*
|
||||
* Description:
|
||||
* Call to enable or disable TX interrupts
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void up_txint(struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
||||
if (enable)
|
||||
{
|
||||
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
|
||||
priv->regs.ier |= UART_IER_XMITINT;
|
||||
up_serialout(priv, UART_IER_OFFS, priv->regs.ier);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->regs.ier &= ~UART_IER_XMITINT;
|
||||
up_serialout(priv, UART_IER_OFFS, priv->regs.ier);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_txready
|
||||
*
|
||||
* Description:
|
||||
* Return true if the tranmsit fifo is not full
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool up_txready(struct uart_dev_s *dev)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
||||
return (up_inserial(priv, UART_SSR_OFFS) & UART_SSR_TXFULL) == 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_txempty
|
||||
*
|
||||
* Description:
|
||||
* Return true if the transmit fifo is empty
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool up_txempty(struct uart_dev_s *dev)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
||||
return (up_inserial(priv, UART_LSR_OFFS) & UART_LSR_TREF) != 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Funtions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_earlyserialinit
|
||||
*
|
||||
* Description:
|
||||
* Performs the low level UART initialization early in
|
||||
* debug so that the serial console will be available
|
||||
* during bootup. This must be called before up_serialinit.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_earlyserialinit(void)
|
||||
{
|
||||
up_disableuartint(TTYS0_DEV.priv, NULL);
|
||||
up_disableuartint(TTYS1_DEV.priv, NULL);
|
||||
|
||||
CONSOLE_DEV.isconsole = true;
|
||||
up_setup(&CONSOLE_DEV);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_serialinit
|
||||
*
|
||||
* Description:
|
||||
* Register serial console and serial ports. This assumes
|
||||
* that up_earlyserialinit was called previously.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_serialinit(void)
|
||||
{
|
||||
#ifdef CONFIG_SERCOMM_CONSOLE
|
||||
((struct up_dev_s *)TTYS0_DEV.priv)->sercomm = true;
|
||||
(void)sercomm_register("/dev/console", &TTYS0_DEV);
|
||||
(void)uart_register("/dev/ttyS0", &TTYS1_DEV);
|
||||
#else
|
||||
(void)uart_register("/dev/console", &CONSOLE_DEV);
|
||||
(void)uart_register("/dev/ttyS0", &TTYS0_DEV);
|
||||
(void)uart_register("/dev/ttyS1", &TTYS1_DEV);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_putc
|
||||
*
|
||||
* Description:
|
||||
* Provide priority, low-level access to support OS debug
|
||||
* writes
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_putc(int ch)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv;
|
||||
uint16_t ier;
|
||||
|
||||
up_disableuartint(priv, &ier);
|
||||
up_waittxready(priv);
|
||||
up_serialout(priv, UART_THR_OFFS, (uint8_t)ch);
|
||||
|
||||
/* Check for LF */
|
||||
|
||||
if (ch == '\n')
|
||||
{
|
||||
/* Add CR */
|
||||
|
||||
up_waittxready(priv);
|
||||
up_serialout(priv, UART_THR_OFFS, '\r');
|
||||
}
|
||||
|
||||
up_waittxready(priv);
|
||||
up_restoreuartint(priv, ier);
|
||||
return ch;
|
||||
}
|
||||
|
@ -1,314 +0,0 @@
|
||||
/****************************************************************************
|
||||
* 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/spi.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <semaphore.h>
|
||||
#include <debug.h>
|
||||
#include <assert.h>
|
||||
#include <errno.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 */
|
||||
sem_t exclsem; /* Supports mutually exclusive access */
|
||||
};
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
||||
{
|
||||
struct calypso_spidev_s *priv = (struct calypso_spidev_s *)dev;
|
||||
|
||||
if (lock)
|
||||
{
|
||||
/* Take the semaphore (perhaps waiting) */
|
||||
|
||||
while (sem_wait(&priv->exclsem) != 0)
|
||||
{
|
||||
/* The only case that an error should occur here is if the wait
|
||||
* was awakened by a signal.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(errno == EINTR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)sem_post(&priv->exclsem);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* STUBS! */
|
||||
|
||||
static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
|
||||
bool selected)
|
||||
{
|
||||
}
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
{
|
||||
return frequency;
|
||||
}
|
||||
|
||||
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
||||
{
|
||||
}
|
||||
|
||||
/* Osmocom wrapper */
|
||||
|
||||
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
{
|
||||
((FAR struct calypso_spidev_s *)dev)->nbits = nbits;
|
||||
}
|
||||
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords)
|
||||
{
|
||||
FAR struct calypso_spidev_s *priv = (FAR struct calypso_spidev_s *)dev;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < nwords; i++)
|
||||
{
|
||||
spi_xfer(0, priv->nbits, txbuffer + i, rxbuffer + i);
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
{
|
||||
uint16_t buf = wd;
|
||||
spi_exchange(dev, &buf, &buf, 1);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static const struct spi_ops_s g_spiops =
|
||||
{
|
||||
.lock = spi_lock,
|
||||
.select = spi_select,
|
||||
.setfrequency = spi_setfrequency,
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = 0,
|
||||
#endif
|
||||
.status = 0,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = 0,
|
||||
#endif
|
||||
.send = spi_send,
|
||||
#ifdef CONFIG_SPI_EXCHANGE
|
||||
.exchange = spi_exchange,
|
||||
#else
|
||||
.sndblock = spi_sndblock,
|
||||
.recvblock = spi_recvblock,
|
||||
#endif
|
||||
.registercallback = 0,
|
||||
};
|
||||
|
||||
static struct calypso_spidev_s g_spidev =
|
||||
{
|
||||
.spidev = { &g_spiops },
|
||||
.nbits = 0,
|
||||
.exclsem = SEM_INITIALIZER(1)
|
||||
};
|
||||
|
||||
void spi_init(void)
|
||||
{
|
||||
putreg16(SPI_SET1_EN_CLK | SPI_SET1_WR_IRQ_DIS | SPI_SET1_RDWR_IRQ_DIS,
|
||||
SPI_REG(REG_SET1));
|
||||
|
||||
putreg16(0x0001, SPI_REG(REG_SET2));
|
||||
}
|
||||
|
||||
int spi_xfer(uint8_t dev_idx, uint8_t bitlen, const void *dout, void *din)
|
||||
{
|
||||
uint8_t bytes_per_xfer;
|
||||
uint8_t reg_status, reg_ctrl = 0;
|
||||
uint32_t tmp;
|
||||
|
||||
if (bitlen == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bitlen > 32)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dev_idx > 4)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
bytes_per_xfer = bitlen / 8;
|
||||
if (bitlen % 8)
|
||||
{
|
||||
bytes_per_xfer ++;
|
||||
}
|
||||
|
||||
reg_ctrl |= (bitlen - 1) << SPI_CTRL_NB_SHIFT;
|
||||
reg_ctrl |= (dev_idx & 0x7) << SPI_CTRL_AD_SHIFT;
|
||||
|
||||
if (bitlen <= 8)
|
||||
{
|
||||
tmp = *(uint8_t *)dout;
|
||||
tmp <<= 24 + (8-bitlen); /* align to MSB */
|
||||
}
|
||||
else if (bitlen <= 16)
|
||||
{
|
||||
tmp = *(uint16_t *)dout;
|
||||
tmp <<= 16 + (16-bitlen); /* align to MSB */
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = *(uint32_t *)dout;
|
||||
tmp <<= (32-bitlen); /* align to MSB */
|
||||
}
|
||||
|
||||
spiinfo("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));
|
||||
spiinfo("reg_ctrl=0x%04x ", reg_ctrl);
|
||||
|
||||
/* wait until the transfer is complete */
|
||||
|
||||
while (1)
|
||||
{
|
||||
reg_status = getreg16(SPI_REG(REG_STATUS));
|
||||
spiinfo("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));
|
||||
spiinfo("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;
|
||||
}
|
||||
}
|
||||
|
||||
spiinfo("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: calypso_spibus_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the selected SPI port
|
||||
*
|
||||
* Input Parameter:
|
||||
* Port number (for hardware that has mutiple SPI interfaces)
|
||||
*
|
||||
* Returned Value:
|
||||
* Valid SPI device structure reference on succcess; a NULL on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct spi_dev_s *calypso_spibus_initialize(int port)
|
||||
{
|
||||
switch (port)
|
||||
{
|
||||
case 0: /* SPI master device */
|
||||
spi_init();
|
||||
return (FAR struct spi_dev_s *)&g_spidev;
|
||||
|
||||
case 1: /* uWire device */
|
||||
return NULL;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
#ifndef ___ARCH_ARM_SRC_CALYPSO_CALYPSO_SPI_H
|
||||
#define ___ARCH_ARM_SRC_CALYPSO_CALYPSO_SPI_H
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define BASE_ADDR_SPI 0xfffe3000
|
||||
#define SPI_REG(n) (BASE_ADDR_SPI+(n))
|
||||
|
||||
#define SPI_SET1_EN_CLK (1 << 0)
|
||||
#define SPI_SET1_WR_IRQ_DIS (1 << 4)
|
||||
#define SPI_SET1_RDWR_IRQ_DIS (1 << 5)
|
||||
|
||||
#define SPI_CTRL_RDWR (1 << 0)
|
||||
#define SPI_CTRL_WR (1 << 1)
|
||||
#define SPI_CTRL_NB_SHIFT 2
|
||||
#define SPI_CTRL_AD_SHIFT 7
|
||||
|
||||
#define SPI_STATUS_RE (1 << 0) /* Read End */
|
||||
#define SPI_STATUS_WE (1 << 1) /* Write End */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
enum spi_regs
|
||||
{
|
||||
REG_SET1 = 0x00,
|
||||
REG_SET2 = 0x02,
|
||||
REG_CTRL = 0x04,
|
||||
REG_STATUS = 0x06,
|
||||
REG_TX_LSB = 0x08,
|
||||
REG_TX_MSB = 0x0a,
|
||||
REG_RX_LSB = 0x0c,
|
||||
REG_RX_MSB = 0x0e,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: calypso_spibus_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the selected SPI port
|
||||
*
|
||||
* Input Parameter:
|
||||
* Port number (for hardware that has mutiple SPI interfaces)
|
||||
*
|
||||
* Returned Value:
|
||||
* Valid SPI device structure reference on succcess; a NULL on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct spi_dev_s *calypso_spibus_initialize(int port);
|
||||
|
||||
#endif /* ___ARCH_ARM_SRC_CALYPSO_CALYPSO_SPI_H */
|
@ -1,227 +0,0 @@
|
||||
/****************************************************************************
|
||||
* 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 %d\n", num);
|
||||
return;
|
||||
}
|
||||
|
||||
ctl = getreg8(TIMER_REG(num, CNTL_TIMER));
|
||||
if (on)
|
||||
{
|
||||
ctl |= CNTL_START | CNTL_CLOCK_ENABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctl &= ~CNTL_START;
|
||||
}
|
||||
|
||||
putreg8(ctl, TIMER_REG(num, CNTL_TIMER));
|
||||
}
|
||||
|
||||
void hwtimer_config(int num, uint8_t pre_scale, int auto_reload)
|
||||
{
|
||||
uint8_t ctl;
|
||||
|
||||
ctl = (pre_scale & 0x7) << 2;
|
||||
if (auto_reload)
|
||||
ctl |= CNTL_AUTO_RELOAD;
|
||||
|
||||
putreg8(ctl, TIMER_REG(num, CNTL_TIMER));
|
||||
}
|
||||
|
||||
void hwtimer_load(int num, uint16_t val)
|
||||
{
|
||||
putreg16(val, TIMER_REG(num, LOAD_TIMER));
|
||||
}
|
||||
|
||||
uint16_t hwtimer_read(int num)
|
||||
{
|
||||
uint8_t ctl = getreg8(TIMER_REG(num, CNTL_TIMER));
|
||||
|
||||
/* Somehow a read results in an abort */
|
||||
|
||||
if ((ctl & (CNTL_START | CNTL_CLOCK_ENABLE)) != (CNTL_START | CNTL_CLOCK_ENABLE))
|
||||
{
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
return getreg16(TIMER_REG(num, READ_TIMER));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Watchdog Timer
|
||||
****************************************************************************/
|
||||
|
||||
#define BASE_ADDR_WDOG 0xfffff800
|
||||
#define WDOG_REG(m) (BASE_ADDR_WDOG + m)
|
||||
|
||||
enum wdog_reg
|
||||
{
|
||||
WD_CNTL_TIMER = CNTL_TIMER,
|
||||
WD_LOAD_TIMER = LOAD_TIMER,
|
||||
WD_READ_TIMER = 0x02,
|
||||
WD_MODE = 0x04,
|
||||
};
|
||||
|
||||
enum wdog_ctl
|
||||
{
|
||||
WD_CTL_START = (1 << 7),
|
||||
WD_CTL_AUTO_RELOAD = (1 << 8)
|
||||
};
|
||||
|
||||
enum wdog_mode
|
||||
{
|
||||
WD_MODE_DIS_ARM = 0xF5,
|
||||
WD_MODE_DIS_CONFIRM = 0xA0,
|
||||
WD_MODE_ENABLE = (1 << 15)
|
||||
};
|
||||
|
||||
#define WD_CTL_PRESCALE(value) (((value)&0x07) << 9)
|
||||
|
||||
static void wdog_irq(__unused enum irq_nr nr)
|
||||
{
|
||||
puts("=> WATCHDOG\n");
|
||||
}
|
||||
|
||||
void wdog_enable(int on)
|
||||
{
|
||||
if (!on)
|
||||
{
|
||||
putreg16(WD_MODE_DIS_ARM, WDOG_REG(WD_MODE));
|
||||
putreg16(WD_MODE_DIS_CONFIRM, WDOG_REG(WD_MODE));
|
||||
}
|
||||
}
|
||||
|
||||
void wdog_reset(void)
|
||||
{
|
||||
/* Enable watchdog */
|
||||
|
||||
putreg16(WD_MODE_ENABLE, WDOG_REG(WD_MODE));
|
||||
|
||||
/* Force expiration */
|
||||
|
||||
putreg16(0x0000, WDOG_REG(WD_LOAD_TIMER));
|
||||
putreg16(0x0000, WDOG_REG(WD_LOAD_TIMER));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: up_timerisr
|
||||
*
|
||||
* Description:
|
||||
* The timer ISR will perform a variety of services for
|
||||
* various portions of the systems.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_timerisr(int irq, uint32_t *regs)
|
||||
{
|
||||
/* Process timer interrupt */
|
||||
|
||||
sched_process_timer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: up_timer_initialize
|
||||
*
|
||||
* Description:
|
||||
* Setup Calypso HW timer 2 to cause system ticks.
|
||||
*
|
||||
* This function is called during start-up to initialize
|
||||
* the timer interrupt.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_timer_initialize(void)
|
||||
{
|
||||
up_disable_irq(IRQ_SYSTIMER);
|
||||
|
||||
/* The timer runs at 13MHz / 32, i.e. 406.25kHz */
|
||||
/* 4062 ticks until expiry yields 100Hz interrupt */
|
||||
|
||||
hwtimer_load(2, 4062);
|
||||
hwtimer_config(2, 0, 1);
|
||||
hwtimer_enable(2, 1);
|
||||
|
||||
/* Attach and enable the timer interrupt */
|
||||
|
||||
irq_attach(IRQ_SYSTIMER, (xcpt_t)up_timerisr);
|
||||
up_enable_irq(IRQ_SYSTIMER);
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
/****************************************************************************
|
||||
* 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 */
|
||||
|
||||
_info("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));
|
||||
_info(", 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));
|
||||
_info(", 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);
|
||||
|
||||
_info(")\n");
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,211 +0,0 @@
|
||||
/****************************************************************************
|
||||
* 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 __ARCH_ARM_SRC_CALYPSO_CHIP_H
|
||||
#define __ARCH_ARM_SRC_CALYPSO_CHIP_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* UARTs ********************************************************************/
|
||||
|
||||
#define UART_IRDA_BASE 0xffff5000
|
||||
#define UART_MODEM_BASE 0xffff5800
|
||||
#define UART_UIR 0xffff6000
|
||||
#define UARTn_IO_RANGE 0x00000800
|
||||
|
||||
/* Common UART Registers. Expressed as offsets from the BASE address */
|
||||
|
||||
#define UART_RHR_OFFS 0x00000000 /* Rcv Holding Register */
|
||||
#define UART_THR_OFFS 0x00000000 /* Xmit Holding Register */
|
||||
#define UART_FCR_OFFS 0x00000002 /* FIFO Control Register */
|
||||
#define UART_RFCR_OFFS 0x00000002 /* Rcv FIFO Control Register */
|
||||
#define UART_TFCR_OFFS 0x00000002 /* Xmit FIFO Control Register */
|
||||
#define UART_SCR_OFFS 0x00000010 /* Status Control Register */
|
||||
#define UART_LCR_OFFS 0x00000003 /* Line Control Register */
|
||||
#define UART_LSR_OFFS 0x00000005 /* Line Status Register */
|
||||
#define UART_SSR_OFFS 0x00000011 /* Supplementary Status Register */
|
||||
#define UART_MCR_OFFS 0x00000004 /* Modem Control Register */
|
||||
#define UART_MSR_OFFS 0x00000006 /* Modem Status Register */
|
||||
#define UART_IER_OFFS 0x00000001 /* Interrupt Enable Register */
|
||||
#define UART_ISR_OFFS 0x00000002 /* Interrupt Status Register */
|
||||
#define UART_EFR_OFFS 0x00000002 /* Enhanced Feature Register */
|
||||
#define UART_XON1_OFFS 0x00000004 /* XON1 Character Register */
|
||||
#define UART_XON2_OFFS 0x00000005 /* XON2 Character Register */
|
||||
#define UART_XOFF1_OFFS 0x00000006 /* XOFF1 Character Register */
|
||||
#define UART_XOFF2_OFFS 0x00000007 /* XOFF2 Character Register */
|
||||
#define UART_SPR_OFFS 0x00000007 /* Scratch-pad Register */
|
||||
#define UART_DIV_LOW_OFFS 0x00000000 /* Divisor for baud generation */
|
||||
#define UART_DIV_HIGH_OFFS 0x00000001
|
||||
#define UART_TCR_OFFS 0x00000006 /* Transmission Control Register */
|
||||
#define UART_TLR_OFFS 0x00000007 /* Trigger Level Register */
|
||||
#define UART_MDR_OFFS 0x00000008 /* Mode Definition Register */
|
||||
|
||||
/* UART Settings ************************************************************/
|
||||
|
||||
/* Miscellaneous UART settings. */
|
||||
|
||||
#define UART_REGISTER_BITS 8
|
||||
#define UART_IRQ_MODEM IRQ_UART_MODEM
|
||||
#define UART_IRQ_IRDA IRQ_UART_IRDA
|
||||
|
||||
#define UART_RX_FIFO_NOEMPTY 0x00000001
|
||||
#define UART_SSR_TXFULL 0x00000001
|
||||
#define UART_LSR_TREF 0x00000020
|
||||
|
||||
#define UART_XMIT_FIFO_SIZE 64
|
||||
#define UART_IRDA_XMIT_FIFO_SIZE 64
|
||||
|
||||
/* UART_LCR Register */
|
||||
/* Bits 31-7: Reserved */
|
||||
#define UART_LCR_BOC 0x00000040 /* Bit 6: Break Control */
|
||||
/* Bit 5: Parity Type 2 */
|
||||
#define UART_LCR_PAREVEN 0x00000010 /* Bit 4: Parity Type 1 */
|
||||
#define UART_LCR_PARODD 0x00000000
|
||||
#define UART_LCR_PARMARK 0x00000010
|
||||
#define UART_LCR_PARSPACE 0x00000011
|
||||
#define UART_LCR_PAREN 0x00000008 /* Bit 3: Paity Enable */
|
||||
#define UART_LCR_PARDIS 0x00000000
|
||||
#define UART_LCR_2STOP 0x00000004 /* Bit 2: Number of stop bits */
|
||||
#define UART_LCR_1STOP 0x00000000
|
||||
#define UART_LCR_5BITS 0x00000000 /* Bits 0-1: Word-length */
|
||||
#define UART_LCR_6BITS 0x00000001
|
||||
#define UART_LCR_7BITS 0x00000002
|
||||
#define UART_LCR_8BITS 0x00000003
|
||||
|
||||
#define UART_FCR_FTL 0x000000f0
|
||||
#define UART_FCR_FIFO_EN 0x00000001
|
||||
#define UART_FCR_TX_CLR 0x00000002
|
||||
#define UART_FCR_RX_CLR 0x00000004
|
||||
|
||||
#define UART_IER_RECVINT 0x00000001
|
||||
#define UART_IER_XMITINT 0x00000002
|
||||
#define UART_IER_LINESTSINT 0x00000004
|
||||
#define UART_IER_MODEMSTSINT 0x00000008 /* IrDA UART only */
|
||||
#define UART_IER_XOFFINT 0x00000020
|
||||
#define UART_IER_RTSINT 0x00000040 /* IrDA UART only */
|
||||
#define UART_IER_CTSINT 0x00000080 /* IrDA UART only */
|
||||
#define UART_IER_INTMASK 0x000000ff
|
||||
|
||||
#define BAUD_115200 0x00000007
|
||||
#define BAUD_57600 0x00000014
|
||||
#define BAUD_38400 0x00000021
|
||||
#define BAUD_19200 0x00000006
|
||||
#define BAUD_9600 0x0000000C
|
||||
#define BAUD_4800 0x00000018
|
||||
#define BAUD_2400 0x00000030
|
||||
#define BAUD_1200 0x00000060
|
||||
|
||||
#define MDR_UART_MODE 0x00000000 /* Both IrDA and Modem UARTs */
|
||||
#define MDR_SIR_MODE 0x00000001 /* IrDA UART only */
|
||||
#define MDR_AUTOBAUDING_MODE 0x00000002 /* Modem UART only */
|
||||
#define MDR_RESET_MODE 0x00000007 /* Both IrDA and Modem UARTs */
|
||||
|
||||
/* SPI **********************************************************************/
|
||||
|
||||
#define MAX_SPI 3
|
||||
|
||||
#define SPI_REGISTER_BASE 0xffff2000
|
||||
|
||||
/* ARMIO ********************************************************************/
|
||||
/* Timers / Watchdog ********************************************************/
|
||||
|
||||
#define C5471_TIMER0_CTRL 0xffff2a00
|
||||
#define C5471_TIMER0_CNT 0xffff2a04
|
||||
#define C5471_TIMER1_CTRL 0xffff2b00
|
||||
#define C5471_TIMER1_CNT 0xffff2b04
|
||||
#define C5471_TIMER2_CTRL 0xffff2c00
|
||||
#define C5471_TIMER2_CNT 0xffff2c04
|
||||
|
||||
/* Interrupts ***************************************************************/
|
||||
|
||||
#define HAVE_SRC_IRQ_BIN_REG 0
|
||||
|
||||
#define INT_FIRST_IO 0xffff2d00
|
||||
#define INT_IO_RANGE 0x5C
|
||||
|
||||
#define IT_REG 0xffff2d00
|
||||
#define MASK_IT_REG 0xffff2d04
|
||||
#define SRC_IRQ_REG 0xffff2d08
|
||||
#define SRC_FIQ_REG 0xffff2d0c
|
||||
#define SRC_IRQ_BIN_REG 0xffff2d10
|
||||
#define INT_CTRL_REG 0xffff2d18
|
||||
|
||||
#define ILR_IRQ0_REG 0xffff2d1C /* 0-Timer 0 */
|
||||
#define ILR_IRQ1_REG 0xffff2d20 /* 1-Timer 1 */
|
||||
#define ILR_IRQ2_REG 0xffff2d24 /* 2-Timer 2 */
|
||||
#define ILR_IRQ3_REG 0xffff2d28 /* 3-GPIO0 */
|
||||
#define ILR_IRQ4_REG 0xffff2d2c /* 4-Ethernet */
|
||||
#define ILR_IRQ5_REG 0xffff2d30 /* 5-KBGPIO[7:0] */
|
||||
#define ILR_IRQ6_REG 0xffff2d34 /* 6-Uart serial */
|
||||
#define ILR_IRQ7_REG 0xffff2d38 /* 7-Uart IRDA */
|
||||
#define ILR_IRQ8_REG 0xffff2d3c /* 8-KBGPIO[15:8] */
|
||||
#define ILR_IRQ9_REG 0xffff2d40 /* 9-GPIO3 */
|
||||
#define ILR_IRQ10_REG 0xffff2d44 /* 10-GPIO2 */
|
||||
#define ILR_IRQ11_REG 0xffff2d48 /* 11-I2C */
|
||||
#define ILR_IRQ12_REG 0xffff2d4c /* 12-GPIO1 */
|
||||
#define ILR_IRQ13_REG 0xffff2d50 /* 13-SPI */
|
||||
#define ILR_IRQ14_REG 0xffff2d54 /* 14-GPIO[19:4] */
|
||||
#define ILR_IRQ15_REG 0xffff2d58 /* 15-API */
|
||||
|
||||
/* CLKM *********************************************************************/
|
||||
|
||||
#define CLKM 0xffff2f00
|
||||
#define CLKM_CTL_RST 0xffff2f10
|
||||
#define CLKM_RESET 0xffff2f18
|
||||
|
||||
#define CLKM_RESET_EIM 0x00000008
|
||||
#define CLKM_EIM_CLK_STOP 0x00000010
|
||||
#define CLKM_CTL_RST_LEAD_RESET 0x00000000
|
||||
#define CLKM_CTL_RST_EXT_RESET 0x00000002
|
||||
|
||||
/****************************************************************************
|
||||
* Inline Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_CALYPSO_CHIP_H */
|
@ -1,230 +0,0 @@
|
||||
/****************************************************************************
|
||||
* 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);
|
||||
}
|
@ -191,11 +191,6 @@
|
||||
# define _DATA_INIT &_eronly
|
||||
# define _START_DATA &_sdata
|
||||
# define _END_DATA &_edata
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
# define _START_NOCACHE &_snocache
|
||||
# define _END_NOCACHE &_enocache
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This is the value used to mark the stack for subsequent stack monitoring
|
||||
@ -284,11 +279,6 @@ EXTERN uint32_t _edata; /* End+1 of .data */
|
||||
EXTERN uint32_t _sbss; /* Start of .bss */
|
||||
EXTERN uint32_t _ebss; /* End+1 of .bss */
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
EXTERN uint32_t _snocache; /* Start of .nocache */
|
||||
EXTERN uint32_t _enocache; /* End+1 of .nocache */
|
||||
#endif
|
||||
|
||||
/* 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,
|
||||
|
@ -281,7 +281,8 @@ static void efm32_leuart_setbaud(uintptr_t base, uint32_t baud)
|
||||
|
||||
void efm32_lowsetup(void)
|
||||
{
|
||||
#if defined(HAVE_UART_DEVICE) || defined(HAVE_LEUART_DEVICE)
|
||||
#if defined(HAVE_UART_DEVICE) || defined(HAVE_LEUART_DEVICE) || \
|
||||
defined(HAVE_SPI_DEVICE)
|
||||
uint32_t regval;
|
||||
#endif
|
||||
|
||||
|
@ -126,9 +126,7 @@
|
||||
* address in the top-level memory map are candidates for other mapping uses:
|
||||
*
|
||||
* 00018000-000fffff Reserved -- Not used
|
||||
* 00400000-007fffff Reserved -- Used as the virtual address an inter-CPU,
|
||||
* un-cached memory region in SMP
|
||||
* configurations
|
||||
* 00400000-007fffff Reserved -- Not used
|
||||
* 00d00000-00ffffff Reserved -- Not used
|
||||
* 0220c000-023fffff Reserved -- Not used
|
||||
* 80000000-efffffff Reserved -- Level 2 page table (See below)
|
||||
@ -929,8 +927,6 @@
|
||||
* the address space.
|
||||
*/
|
||||
|
||||
#define INTERCPU_L2_PAGES 1 /* Pages allowed for inter-processor communications */
|
||||
|
||||
#ifndef CONFIG_ARCH_LOWVECTORS
|
||||
/* Memory map
|
||||
* VIRTUAL ADDRESS RANGE L1 PG TABLE L2 PG TABLE DESCRIPTION
|
||||
@ -938,10 +934,6 @@
|
||||
* ---------- ---------- ------------ ----------------------------
|
||||
* 0x80000000 0x803fffff 0x000002000 0x000000400 Vectors (1MiB)
|
||||
* 0x80100000 0x806fffff 0x000002400 0x000001800 Paging (6MiB)
|
||||
*
|
||||
* If SMP is enabled, then 1MiB of address spaces for the INTERCPU_L2_PAGES
|
||||
* pages are taken from the end of the Paging L2 page table to hold non-
|
||||
* cacheable, inter-processor communication data.
|
||||
*/
|
||||
|
||||
/* Vector L2 page table offset/size */
|
||||
@ -959,18 +951,10 @@
|
||||
# define VECTOR_L2_END_PADDR (VECTOR_L2_PBASE + VECTOR_L2_SIZE)
|
||||
# define VECTOR_L2_END_VADDR (VECTOR_L2_VBASE + VECTOR_L2_SIZE)
|
||||
|
||||
# if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Paging L2 page table offset/size */
|
||||
/* Paging L2 page table offset/size */
|
||||
|
||||
# define PGTABLE_L2_OFFSET 0x000002400
|
||||
# define PGTABLE_L2_SIZE 0x000001400
|
||||
|
||||
# else
|
||||
/* Paging L2 page table offset/size */
|
||||
|
||||
# define PGTABLE_L2_OFFSET 0x000002400
|
||||
# define PGTABLE_L2_SIZE 0x000001800
|
||||
# endif
|
||||
# define PGTABLE_L2_OFFSET 0x000002400
|
||||
# define PGTABLE_L2_SIZE 0x000001800
|
||||
|
||||
#else
|
||||
/* Memory map
|
||||
@ -978,24 +962,12 @@
|
||||
* START END OFFSET SIZE
|
||||
* ---------- ---------- ------------ ----------------------------
|
||||
* 0x80000000 0x806fffff 0x000002000 0x000001c00 Paging (7MiB)
|
||||
*
|
||||
* If SMP is enabled, then 1MiB of address spaces for the INTERCPU_L2_PAGES
|
||||
* pages are taken from the end of the Paging L2 page table to hold non-
|
||||
* cacheable, inter-processor communication data.
|
||||
*/
|
||||
|
||||
# if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Paging L2 page table offset/size */
|
||||
|
||||
# define PGTABLE_L2_OFFSET 0x000002000
|
||||
# define PGTABLE_L2_SIZE 0x000001800
|
||||
|
||||
# else
|
||||
/* Paging L2 page table offset/size */
|
||||
|
||||
# define PGTABLE_L2_OFFSET 0x000002000
|
||||
# define PGTABLE_L2_SIZE 0x000001c00
|
||||
# endif
|
||||
# define PGTABLE_L2_OFFSET 0x000002000
|
||||
# define PGTABLE_L2_SIZE 0x000001c00
|
||||
|
||||
#endif
|
||||
|
||||
@ -1013,23 +985,6 @@
|
||||
#define PGTABLE_L2_END_PADDR (PGTABLE_L2_PBASE + PGTABLE_L2_SIZE)
|
||||
#define PGTABLE_L2_END_VADDR (PGTABLE_L2_VBASE + PGTABLE_L2_SIZE)
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Non-cached inter-processor communication data */
|
||||
|
||||
# define INTERCPU_L2_OFFSET (PGTABLE_L2_OFFSET + PGTABLE_L2_SIZE)
|
||||
# define INTERCPU_L2_SIZE (0x00000400)
|
||||
|
||||
/* Non-cached inter-processor communication page table base addresses */
|
||||
|
||||
# define INTERCPU_L2_PBASE (PGTABLE_BASE_PADDR + INTERCPU_L2_OFFSET)
|
||||
# define INTERCPU_L2_VBASE (PGTABLE_BASE_VADDR + INTERCPU_L2_OFFSET)
|
||||
|
||||
/* Non-cached inter-processor communication end addresses */
|
||||
|
||||
# define INTERCPU_L2_END_PADDR (INTERCPU_L2_PBASE + INTERCPU_L2_SIZE)
|
||||
# define INTERCPU_L2_END_VADDR (INTERCPU_L2_VBASE + INTERCPU_L2_SIZE)
|
||||
#endif
|
||||
|
||||
/* Base address of the interrupt vector table.
|
||||
*
|
||||
* IMX_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM
|
||||
@ -1052,8 +1007,7 @@
|
||||
* START END CONTENT
|
||||
* ---------- ---------- ---------------------------
|
||||
* 0x00000000 0x00010000 Vectors (VECTOR_TABLE_SIZE)
|
||||
* 0x00010000 0x00011000 Inter-CPU communications
|
||||
* 0x00011000 0x0003c000 Unused
|
||||
* 0x00010000 0x0003c000 Unused
|
||||
* 0x0003c000 0x00004000 Page table (PGTABLE_SIZE)
|
||||
*/
|
||||
|
||||
@ -1061,27 +1015,13 @@
|
||||
# define IMX_VECTOR_VSRAM IMX_OCRAM_VBASE
|
||||
# define IMX_VECTOR_VADDR 0x00000000
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Inter-processor communications.
|
||||
*
|
||||
* NOTICE that we use the unused virtual address space at 0x00400000 for
|
||||
* the inter-CPU virtual communication area.
|
||||
*/
|
||||
|
||||
# define INTERCPU_PADDR (IMX_VECTOR_PADDR + VECTOR_TABLE_SIZE)
|
||||
# define INTERCPU_VADDR (0x00400000)
|
||||
# define INTERCPU_SIZE (INTERCPU_L2_PAGES << 12)
|
||||
# define INTERCPU_VSRAM (IMX_VECTOR_VSRAM + VECTOR_TABLE_SIZE)
|
||||
#endif
|
||||
|
||||
#else /* Vectors located at 0xffff:0000 -- this probably does not work */
|
||||
/* OCRAM Memory Map:
|
||||
* ---------- ---------- ---------------------------
|
||||
* START END CONTENT
|
||||
* ---------- ---------- ---------------------------
|
||||
* 0x00000000 0x00004000 Page table (PGTABLE_SIZE)
|
||||
* 0x00004000 0x0002f000 Unused
|
||||
* 0x0002f000 0x00030000 Inter-CPU communications
|
||||
* 0x00004000 0x00030000 Unused
|
||||
* 0x00030000 0x00010000 Vectors (VECTOR_TABLE_SIZE)
|
||||
*/
|
||||
|
||||
@ -1089,18 +1029,6 @@
|
||||
# define IMX_VECTOR_VSRAM (IMX_OCRAM_VBASE + IMX_OCRAM_SIZE - VECTOR_TABLE_SIZE)
|
||||
# define IMX_VECTOR_VADDR 0xffff0000
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Inter-processor communications
|
||||
*
|
||||
* NOTICE that we use the unused virtual address space at 0x00400000 for
|
||||
* the inter-CPU virtual communication area.
|
||||
*/
|
||||
|
||||
# define INTERCPU_PADDR (IMX_VECTOR_PADDR - INTERCPU_L2_SIZE)
|
||||
# define INTERCPU_VADDR (0x00400000)
|
||||
# define INTERCPU_SIZE (INTERCPU_L2_PAGES << 12)
|
||||
# define INTERCPU_VSRAM (IMX_VECTOR_VSRAM - INTERCPU_L2_SIZE)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
|
@ -235,48 +235,6 @@ static void imx_vectormapping(void)
|
||||
# define imx_vectormapping()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imx_intercpu_mapping
|
||||
*
|
||||
* Description:
|
||||
* Setup a special mapping for the non-cached, inter-cpu communications
|
||||
* area.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
static void imx_intercpu_mapping(void)
|
||||
{
|
||||
uint32_t intercpu_paddr = INTERCPU_PADDR & PTE_SMALL_PADDR_MASK;
|
||||
uint32_t intercpu_vaddr = INTERCPU_VADDR & PTE_SMALL_PADDR_MASK;
|
||||
uint32_t end_paddr = INTERCPU_PADDR + INTERCPU_SIZE;
|
||||
|
||||
DEBUGASSERT(intercpu_vaddr == (uint32_t)&_snocache);
|
||||
|
||||
/* We want to keep the inter-cpu region in on-chip RAM (OCRAM). The
|
||||
* i.MX6 has 256Kb of OCRAM positioned at physical address 0x0090:0000.
|
||||
*/
|
||||
|
||||
while (intercpu_paddr < end_paddr)
|
||||
{
|
||||
mmu_l2_setentry(INTERCPU_L2_VBASE, intercpu_paddr, intercpu_vaddr,
|
||||
MMU_L2_INTERCPUFLAGS);
|
||||
intercpu_paddr += 4096;
|
||||
intercpu_vaddr += 4096;
|
||||
}
|
||||
|
||||
/* Now set the level 1 descriptor to refer to the level 2 page table. */
|
||||
|
||||
mmu_l1_setentry(INTERCPU_L2_PBASE & PMD_PTE_PADDR_MASK,
|
||||
INTERCPU_VADDR & PMD_PTE_PADDR_MASK,
|
||||
MMU_L1_INTERCPUFLAGS);
|
||||
}
|
||||
#else
|
||||
/* No inter-cpu communications area */
|
||||
|
||||
# define imx_intercpu_mapping()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imx_copyvectorblock
|
||||
*
|
||||
@ -477,15 +435,6 @@ void arm_boot(void)
|
||||
imx_vectormapping();
|
||||
PROGRESS('D');
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Provide a special mapping for the OCRAM interrupt vector positioned in
|
||||
* high memory.
|
||||
*/
|
||||
|
||||
imx_intercpu_mapping();
|
||||
PROGRESS('E');
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_RAMFUNCS
|
||||
/* Copy any necessary code sections from FLASH to RAM. The correct
|
||||
* destination in OCRAM is given by _sramfuncs and _eramfuncs. The
|
||||
@ -498,14 +447,14 @@ void arm_boot(void)
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
PROGRESS('F');
|
||||
PROGRESS('E');
|
||||
|
||||
/* Flush the copied RAM functions into physical RAM so that will
|
||||
* be available when fetched into the I-Cache.
|
||||
*/
|
||||
|
||||
arch_clean_dcache((uintptr_t)&_sramfuncs, (uintptr_t)&_eramfuncs)
|
||||
PROGRESS('G');
|
||||
PROGRESS('F');
|
||||
#endif
|
||||
|
||||
/* Setup up vector block. _vector_start and _vector_end are exported from
|
||||
@ -513,23 +462,23 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
imx_copyvectorblock();
|
||||
PROGRESS('H');
|
||||
PROGRESS('G');
|
||||
|
||||
/* Disable the watchdog timer */
|
||||
|
||||
imx_wdtdisable();
|
||||
PROGRESS('I');
|
||||
PROGRESS('H');
|
||||
|
||||
/* Initialize clocking to settings provided by board-specific logic */
|
||||
|
||||
imx_clockconfig();
|
||||
PROGRESS('J');
|
||||
PROGRESS('I');
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Initialize the FPU */
|
||||
|
||||
arm_fpuconfig();
|
||||
PROGRESS('K');
|
||||
PROGRESS('J');
|
||||
#endif
|
||||
|
||||
/* Perform board-specific memroy initialization, This must include
|
||||
@ -541,7 +490,7 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
imx_memory_initialize();
|
||||
PROGRESS('L');
|
||||
PROGRESS('K');
|
||||
|
||||
#ifdef NEED_SDRAM_REMAPPING
|
||||
/* SDRAM was configured in a temporary state to support low-level
|
||||
@ -550,7 +499,7 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
imx_remap();
|
||||
PROGRESS('M');
|
||||
PROGRESS('L');
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOT_SDRAM_DATA
|
||||
@ -559,7 +508,7 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
arm_data_initialize();
|
||||
PROGRESS('N');
|
||||
PROGRESS('M');
|
||||
#endif
|
||||
|
||||
/* Perform board-specific device initialization. This would include
|
||||
@ -567,23 +516,12 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
imx_board_initialize();
|
||||
PROGRESS('O');
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Initialize the uncached, inter-CPU communications area */
|
||||
|
||||
for (dest = &_snocache; dest < &_enocache; )
|
||||
{
|
||||
*dest++ = 0;
|
||||
}
|
||||
|
||||
PROGRESS('P');
|
||||
#endif
|
||||
PROGRESS('N');
|
||||
|
||||
/* Perform common, low-level chip initialization (might do nothing) */
|
||||
|
||||
imx_lowsetup();
|
||||
PROGRESS('Q');
|
||||
PROGRESS('O');
|
||||
|
||||
#ifdef USE_EARLYSERIALINIT
|
||||
/* Perform early serial initialization if we are going to use the serial
|
||||
@ -591,7 +529,7 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
imx_earlyserialinit();
|
||||
PROGRESS('R');
|
||||
PROGRESS('P');
|
||||
#endif
|
||||
|
||||
/* Now we can enable all other CPUs. The enabled CPUs will start execution
|
||||
@ -600,6 +538,6 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
imx_cpu_enable();
|
||||
PROGRESS('S');
|
||||
PROGRESS('Q');
|
||||
PROGRESS('\n');
|
||||
}
|
||||
|
@ -115,10 +115,6 @@ static void up_output_compare(uint32_t sr, uint32_t of)
|
||||
|
||||
if ((sr & of) != 0)
|
||||
{
|
||||
/* Clear the pending output compare interrupt */
|
||||
|
||||
putreg32(of, IMX_GPT_SR);
|
||||
|
||||
/* Process timer interrupt event */
|
||||
|
||||
sched_process_timer();
|
||||
@ -140,9 +136,16 @@ static void up_output_compare(uint32_t sr, uint32_t of)
|
||||
|
||||
int up_timerisr(int irq, uint32_t *regs)
|
||||
{
|
||||
/* Sample the SR (once) and process all pending output compare interrupt */
|
||||
/* Sample the SR (once) */
|
||||
|
||||
uint32_t sr = getreg32(IMX_GPT_SR);
|
||||
|
||||
/* Clear GPT status register */
|
||||
|
||||
putreg32(sr, IMX_GPT_SR);
|
||||
|
||||
/* Process all pending output compare interrupt */
|
||||
|
||||
up_output_compare(sr, GPT_INT_OF1);
|
||||
up_output_compare(sr, GPT_INT_OF2);
|
||||
up_output_compare(sr, GPT_INT_OF3);
|
||||
|
@ -70,7 +70,7 @@ CMN_CSRCS += up_dumpnvic.c
|
||||
endif
|
||||
|
||||
CHIP_ASRCS =
|
||||
CHIP_CSRCS = kl_clockconfig.c kl_gpio.c kl_idle.c kl_irq.c kl_getc.c
|
||||
CHIP_CSRCS = kl_clockconfig.c kl_gpio.c kl_idle.c kl_irq.c
|
||||
CHIP_CSRCS += kl_lowputc.c kl_serial.c kl_start.c kl_cfmconfig.c
|
||||
|
||||
ifneq ($(CONFIG_SCHED_TICKLESS),y)
|
||||
|
@ -71,7 +71,7 @@ endif
|
||||
|
||||
CHIP_ASRCS =
|
||||
CHIP_CSRCS = lpc11_clockconfig.c lpc11_gpio.c lpc11_i2c.c lpc11_idle.c
|
||||
CHIP_CSRCS += lpc11_irq.c lpc11_lowputc.c lpc11_getc.c lpc11_serial.c
|
||||
CHIP_CSRCS += lpc11_irq.c lpc11_lowputc.c lpc11_serial.c
|
||||
CHIP_CSRCS += lpc11_spi.c lpc11_ssp.c lpc11_start.c
|
||||
|
||||
# Configuration-dependent LPC11xx files
|
||||
|
@ -1,47 +0,0 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/lpc11/lpc11_getc.h
|
||||
*
|
||||
* Copyright (C) 2015, 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_GETC_H
|
||||
#define __ARCH_ARM_SRC_LPC11XX_LPC11_GETC_H
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include "lpc11_serial.h"
|
||||
#include "chip/lpc11_uart.h"
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_GETC_H */
|
@ -2086,6 +2086,7 @@ static int lpc17_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlo
|
||||
rlong[2] = getreg32(LPC17_SDCARD_RESP2);
|
||||
rlong[3] = getreg32(LPC17_SDCARD_RESP3);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -603,23 +603,23 @@
|
||||
#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_CD_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_13)
|
||||
#define PINCONF_SD_CD_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_8)
|
||||
#define PINCONF_SD_CLK (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_0)
|
||||
#define PINCONF_SD_CMD_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_6)
|
||||
#define PINCONF_SD_CMD_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_10)
|
||||
#define PINCONF_SD_DAT0_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_9)
|
||||
#define PINCONF_SD_DAT0_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_4)
|
||||
#define PINCONF_SD_DAT1_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_10)
|
||||
#define PINCONF_SD_DAT1_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_5)
|
||||
#define PINCONF_SD_DAT2_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_11)
|
||||
#define PINCONF_SD_DAT2_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_6)
|
||||
#define PINCONF_SD_DAT3_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_12)
|
||||
#define PINCONF_SD_DAT3_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_7)
|
||||
#define PINCONF_SD_DAT4 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_11)
|
||||
#define PINCONF_SD_DAT5 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_12)
|
||||
#define PINCONF_SD_DAT6 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_13)
|
||||
#define PINCONF_SD_DAT7 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|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)
|
||||
|
@ -603,23 +603,23 @@
|
||||
#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_CD_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_13)
|
||||
#define PINCONF_SD_CD_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_8)
|
||||
#define PINCONF_SD_CLK (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_0)
|
||||
#define PINCONF_SD_CMD_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_6)
|
||||
#define PINCONF_SD_CMD_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_10)
|
||||
#define PINCONF_SD_DAT0_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_9)
|
||||
#define PINCONF_SD_DAT0_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_4)
|
||||
#define PINCONF_SD_DAT1_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_10)
|
||||
#define PINCONF_SD_DAT1_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_5)
|
||||
#define PINCONF_SD_DAT2_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_11)
|
||||
#define PINCONF_SD_DAT2_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_6)
|
||||
#define PINCONF_SD_DAT3_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_12)
|
||||
#define PINCONF_SD_DAT3_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_7)
|
||||
#define PINCONF_SD_DAT4 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_11)
|
||||
#define PINCONF_SD_DAT5 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_12)
|
||||
#define PINCONF_SD_DAT6 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_13)
|
||||
#define PINCONF_SD_DAT7 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|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)
|
||||
|
@ -603,23 +603,23 @@
|
||||
#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_CD_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_13)
|
||||
#define PINCONF_SD_CD_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_8)
|
||||
#define PINCONF_SD_CLK (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_0)
|
||||
#define PINCONF_SD_CMD_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_6)
|
||||
#define PINCONF_SD_CMD_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_10)
|
||||
#define PINCONF_SD_DAT0_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_9)
|
||||
#define PINCONF_SD_DAT0_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_4)
|
||||
#define PINCONF_SD_DAT1_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_10)
|
||||
#define PINCONF_SD_DAT1_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_5)
|
||||
#define PINCONF_SD_DAT2_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_11)
|
||||
#define PINCONF_SD_DAT2_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_6)
|
||||
#define PINCONF_SD_DAT3_1 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_12)
|
||||
#define PINCONF_SD_DAT3_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_7)
|
||||
#define PINCONF_SD_DAT4 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_11)
|
||||
#define PINCONF_SD_DAT5 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_12)
|
||||
#define PINCONF_SD_DAT6 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_13)
|
||||
#define PINCONF_SD_DAT7 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|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)
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <debug.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
|
@ -1907,16 +1907,35 @@ static int mcan_del_extfilter(FAR struct sam_mcan_s *priv, int ndx)
|
||||
|
||||
DEBUGASSERT(priv != NULL && priv->config != NULL);
|
||||
config = priv->config;
|
||||
DEBUGASSERT(ndx < config->nextfilters);
|
||||
|
||||
/* Check user Parameters */
|
||||
|
||||
DEBUGASSERT(ndx >= 0 || ndx < config->nextfilters);
|
||||
|
||||
if (ndx < 0 || ndx >= config->nextfilters)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get exclusive excess to the MCAN hardware */
|
||||
|
||||
mcan_dev_lock(priv);
|
||||
|
||||
/* Release the filter */
|
||||
|
||||
word = ndx >> 5;
|
||||
bit = ndx & 0x1f;
|
||||
|
||||
/* Check if this filter is really assigned */
|
||||
|
||||
if ((priv->extfilters[word] & (1 << bit)) == 0)
|
||||
{
|
||||
/* No, error out */
|
||||
|
||||
mcan_dev_unlock(priv);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Release the filter */
|
||||
|
||||
priv->extfilters[word] &= ~(1 << bit);
|
||||
|
||||
DEBUGASSERT(priv->nextalloc > 0);
|
||||
@ -2137,16 +2156,35 @@ static int mcan_del_stdfilter(FAR struct sam_mcan_s *priv, int ndx)
|
||||
|
||||
DEBUGASSERT(priv != NULL && priv->config != NULL);
|
||||
config = priv->config;
|
||||
DEBUGASSERT(ndx < config->nstdfilters);
|
||||
|
||||
/* Check Userspace Parameters */
|
||||
|
||||
DEBUGASSERT(ndx >= 0 || ndx < config->nstdfilters);
|
||||
|
||||
if (ndx < 0 || ndx >= config->nstdfilters)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get exclusive excess to the MCAN hardware */
|
||||
|
||||
mcan_dev_lock(priv);
|
||||
|
||||
/* Release the filter */
|
||||
|
||||
word = ndx >> 5;
|
||||
bit = ndx & 0x1f;
|
||||
|
||||
/* Check if this filter is really assigned */
|
||||
|
||||
if ((priv->stdfilters[word] & (1 << bit)) == 0)
|
||||
{
|
||||
/* No, error out */
|
||||
|
||||
mcan_dev_unlock(priv);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Release the filter */
|
||||
|
||||
priv->stdfilters[word] &= ~(1 << bit);
|
||||
|
||||
DEBUGASSERT(priv->nstdalloc > 0);
|
||||
@ -3388,6 +3426,19 @@ static void mcan_interrupt(FAR struct can_dev_s *dev)
|
||||
{
|
||||
canerr("ERROR: TX %08x\n", pending & MCAN_TXERR_INTS);
|
||||
|
||||
/* An Acknowledge-Error will occur if for example the device
|
||||
* is not connected to the bus.
|
||||
*
|
||||
* The CAN-Standard states that the Chip has to retry the
|
||||
* message forever, which will produce an ACKE every time.
|
||||
* To prevent this Interrupt-Flooding and the high CPU-Load
|
||||
* we disable the ACKE here as long we didn't transfer at
|
||||
* least one message successfully (see MCAN_INT_TC below).
|
||||
*/
|
||||
|
||||
ie &= ~MCAN_INT_ACKE;
|
||||
mcan_putreg(priv, SAM_MCAN_IE_OFFSET, ie);
|
||||
|
||||
/* Clear the error indications */
|
||||
|
||||
mcan_putreg(priv, SAM_MCAN_IR_OFFSET, MCAN_TXERR_INTS);
|
||||
@ -3441,6 +3492,17 @@ static void mcan_interrupt(FAR struct can_dev_s *dev)
|
||||
|
||||
if ((pending & MCAN_INT_TC) != 0)
|
||||
{
|
||||
/* Check if we have disabled the ACKE in the error-handling above
|
||||
* (see MCAN_TXERR_INTS) to prevent Interrupt-Flooding and
|
||||
* re-enable the error interrupt here again.
|
||||
*/
|
||||
|
||||
if ((ie & MCAN_INT_ACKE) == 0)
|
||||
{
|
||||
ie |= MCAN_INT_ACKE;
|
||||
mcan_putreg(priv, SAM_MCAN_IE_OFFSET, ie);
|
||||
}
|
||||
|
||||
/* Clear the pending TX completion interrupt (and all
|
||||
* other TX-related interrupts)
|
||||
*/
|
||||
|
@ -110,7 +110,7 @@ CHIP_ASRCS =
|
||||
|
||||
CHIP_CSRCS = stm32_allocateheap.c stm32_start.c stm32_rcc.c stm32_lse.c
|
||||
CHIP_CSRCS += stm32_lsi.c stm32_gpio.c stm32_exti_gpio.c stm32_flash.c
|
||||
CHIP_CSRCS += stm32_irq.c stm32_dma.c stm32_lowputc.c stm32_getc.c
|
||||
CHIP_CSRCS += stm32_irq.c stm32_dma.c stm32_lowputc.c
|
||||
CHIP_CSRCS += stm32_serial.c stm32_spi.c stm32_sdio.c stm32_tim.c
|
||||
CHIP_CSRCS += stm32_waste.c stm32_ccm.c stm32_uid.c stm32_capture.c
|
||||
|
||||
|
@ -78,7 +78,6 @@
|
||||
#include "stm32_usbdev.h"
|
||||
#include "stm32_wdg.h"
|
||||
#include "stm32_lowputc.h"
|
||||
#include "stm32_getc.h"
|
||||
#include "stm32_eth.h"
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_STM32_STM32_H */
|
||||
|
@ -295,6 +295,10 @@
|
||||
# define SRAM1_END 0x20018000
|
||||
# elif defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429)
|
||||
# define SRAM1_END 0x20030000
|
||||
# elif defined(CONFIG_STM32_STM32F446)
|
||||
# define SRAM1_END 0x20020000
|
||||
# elif defined(CONFIG_STM32_STM32F469)
|
||||
# define SRAM1_END 0x20050000
|
||||
# else
|
||||
# define SRAM1_END 0x20020000
|
||||
# endif
|
||||
|
@ -313,7 +313,7 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
|
||||
addr -= STM32_FLASH_BASE;
|
||||
}
|
||||
|
||||
if ((addr+count) >= STM32_FLASH_SIZE)
|
||||
if ((addr+count) > STM32_FLASH_SIZE)
|
||||
{
|
||||
return -EFAULT;
|
||||
}
|
||||
|
@ -1,121 +0,0 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/stm32/stm32_getc.c
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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.h"
|
||||
#include "stm32_rcc.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_uart.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Select U[S]ART console base address */
|
||||
|
||||
#ifdef HAVE_CONSOLE
|
||||
# if defined(CONFIG_USART1_SERIAL_CONSOLE)
|
||||
# define STM32_CONSOLE_BASE STM32_USART1_BASE
|
||||
# elif defined(CONFIG_USART2_SERIAL_CONSOLE)
|
||||
# define STM32_CONSOLE_BASE STM32_USART2_BASE
|
||||
# elif defined(CONFIG_USART3_SERIAL_CONSOLE)
|
||||
# define STM32_CONSOLE_BASE STM32_USART3_BASE
|
||||
# elif defined(CONFIG_UART4_SERIAL_CONSOLE)
|
||||
# define STM32_CONSOLE_BASE STM32_UART4_BASE
|
||||
# elif defined(CONFIG_UART5_SERIAL_CONSOLE)
|
||||
# define STM32_CONSOLE_BASE STM32_UART5_BASE
|
||||
# elif defined(CONFIG_USART6_SERIAL_CONSOLE)
|
||||
# define STM32_CONSOLE_BASE STM32_USART6_BASE
|
||||
# elif defined(CONFIG_UART7_SERIAL_CONSOLE)
|
||||
# define STM32_CONSOLE_BASE STM32_UART7_BASE
|
||||
# elif defined(CONFIG_UART8_SERIAL_CONSOLE)
|
||||
# define STM32_CONSOLE_BASE STM32_UART8_BASE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_getc
|
||||
*
|
||||
* Description:
|
||||
* Read one byte from the serial console
|
||||
*
|
||||
* REVIST: If used with the serial driver enabled, then this could
|
||||
* interfere with the serial driver operations. Serial interrupts should
|
||||
* be disabled when this function executes in that case.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_getc(void)
|
||||
{
|
||||
uint32_t ch = 0;
|
||||
|
||||
#ifdef HAVE_CONSOLE
|
||||
/* While there is any error, read and discard bytes to clear the errors */
|
||||
|
||||
while ((getreg32(STM32_CONSOLE_BASE + STM32_USART_SR_OFFSET) &
|
||||
(USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE)) != 0)
|
||||
{
|
||||
(void)getreg32(STM32_CONSOLE_BASE + STM32_USART_RDR_OFFSET);
|
||||
}
|
||||
|
||||
/* Wait until the RX data register has a character to be read */
|
||||
|
||||
while ((getreg32(STM32_CONSOLE_BASE + STM32_USART_SR_OFFSET) & USART_SR_RXNE) == 0);
|
||||
|
||||
/* Then read the character */
|
||||
|
||||
ch = getreg32(STM32_CONSOLE_BASE + STM32_USART_RDR_OFFSET);
|
||||
#endif /* HAVE_CONSOLE */
|
||||
|
||||
return (int)ch;
|
||||
}
|
@ -2209,6 +2209,7 @@ static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlo
|
||||
rlong[2] = getreg32(STM32_SDIO_RESP3);
|
||||
rlong[3] = getreg32(STM32_SDIO_RESP4);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2577,12 +2578,14 @@ static int stm32_dmapreflight(FAR struct sdio_dev_s *dev,
|
||||
|
||||
DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
|
||||
|
||||
#if !defined(CONFIG_STM32_STM32F40XX)
|
||||
/* Wide bus operation is required for DMA */
|
||||
|
||||
if (!priv->widebus)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* DMA must be possible to the buffer */
|
||||
|
||||
|
@ -1945,11 +1945,11 @@ static int up_interrupt_common(struct up_dev_s *priv)
|
||||
static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) \
|
||||
|| defined(CONFIG_STM32F7_SERIALBRK_BSDCOMPAT)
|
||||
|| defined(CONFIG_STM32_SERIALBRK_BSDCOMPAT)
|
||||
struct inode *inode = filep->f_inode;
|
||||
struct uart_dev_s *dev = inode->i_private;
|
||||
#endif
|
||||
#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_STM32F7_SERIALBRK_BSDCOMPAT)
|
||||
#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_STM32_SERIALBRK_BSDCOMPAT)
|
||||
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
||||
#endif
|
||||
int ret = OK;
|
||||
|
@ -743,7 +743,8 @@ static void stm32_stdclockconfig(void)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(PWR_CSR_ODRDY)
|
||||
#if defined(CONFIG_STM32_STM32F429) || defined(CONFIG_STM32_STM32F446) || \
|
||||
defined(CONFIG_STM32_STM32F469)
|
||||
|
||||
/* Enable the Over-drive to extend the clock frequency to 180 Mhz */
|
||||
|
||||
|
@ -997,7 +997,7 @@
|
||||
#define GPIO_SPI2_SCK_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN13)
|
||||
#define GPIO_SPI2_SCK_4 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN3)
|
||||
#define GPIO_SPI2_SCK_5 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTI|GPIO_PIN1)
|
||||
#define GPIO_SPI2_SCK_6 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTIA|GPIO_PIN12)
|
||||
#define GPIO_SPI2_SCK_6 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12)
|
||||
|
||||
#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4)
|
||||
#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN11)
|
||||
|
@ -107,6 +107,23 @@
|
||||
#define CC_PWMDIV_64 (0x5) /* (Value) Divided by 64 */
|
||||
|
||||
#define TIVA_PWMn_CTL_ENABLE (0) /* (Bit) PWM Block Enable */
|
||||
#define CTL_DISABLE (0) /* (Value) Disable */
|
||||
#define CTL_ENABLE (1) /* (Value) Enable */
|
||||
|
||||
#define INTEN_GEN3 (3) /* (Bit) Enable PWM GEN3 Interrupt */
|
||||
#define INTEN_GEN2 (2) /* (Bit) Enable PWM GEN2 Interrupt */
|
||||
#define INTEN_GEN1 (1) /* (Bit) Enable PWM GEN1 Interrupt */
|
||||
#define INTEN_GEN0 (0) /* (Bit) Enable PWM GEN0 Interrupt */
|
||||
#define INT_DISABLE (0) /* (Value) Disable */
|
||||
#define INT_ENABLE (1) /* (Value) Enable */
|
||||
|
||||
#define INTCMPBD (5) /* (Bit) Interrupt for Counter=PWMnCMPB Down */
|
||||
#define INTCMPBU (4) /* (Bit) Interrupt for Counter=PWMnCMPB Up */
|
||||
#define INTCMPAD (3) /* (Bit) Interrupt for Counter=PWMnCMPA Down */
|
||||
#define INTCMPAU (2) /* (Bit) Interrupt for Counter=PWMnCMPA Up */
|
||||
#define INTCNTLOAD (1) /* (Bit) Interrupt for Counter=PWMnLOAD */
|
||||
#define INTCNTZERO (0) /* (Bit) Interrupt for Counter=0 */
|
||||
#define INT_CLR (0) /* (Value) Bit Clear */
|
||||
#define INT_SET (1) /* (Value) Bit Set */
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TIVA_PWM_H */
|
||||
|
@ -85,21 +85,57 @@ struct tiva_pwm_chan_s
|
||||
uint8_t generator_id;
|
||||
uintptr_t generator_base;
|
||||
uint8_t channel_id;
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
bool inited;
|
||||
uint8_t irq;
|
||||
uint32_t count;
|
||||
uint32_t cur_count;
|
||||
FAR void *handle;
|
||||
#endif
|
||||
};
|
||||
|
||||
/************************************************************************************
|
||||
* Private Function Prototypes
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_TIVA_PWM0_CHAN0)
|
||||
static int tiva_pwm_gen0_interrupt(int irq, FAR void *context);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_TIVA_PWM0_CHAN2)
|
||||
static int tiva_pwm_gen1_interrupt(int irq, FAR void *context);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_TIVA_PWM0_CHAN4)
|
||||
static int tiva_pwm_gen2_interrupt(int irq, FAR void *context);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_TIVA_PWM0_CHAN6)
|
||||
static int tiva_pwm_gen3_interrupt(int irq, FAR void *context);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PWM_PULSECOUNT) && \
|
||||
(defined(CONFIG_TIVA_PWM0_CHAN0) || defined(CONFIG_TIVA_PWM0_CHAN2) || \
|
||||
defined(CONFIG_TIVA_PWM0_CHAN4) || defined(CONFIG_TIVA_PWM0_CHAN6))
|
||||
static int tiva_pwm_interrupt(struct tiva_pwm_chan_s *chan);
|
||||
#endif
|
||||
|
||||
static inline void tiva_pwm_putreg(struct tiva_pwm_chan_s *chan,
|
||||
unsigned int offset, uint32_t regval);
|
||||
static inline uint32_t tiva_pwm_getreg(struct tiva_pwm_chan_s *chan,
|
||||
unsigned int offset);
|
||||
static inline int tiva_pwm_timer(FAR struct tiva_pwm_chan_s *chan,
|
||||
FAR const struct pwm_info_s *info);
|
||||
|
||||
static int tiva_pwm_setup(FAR struct pwm_lowerhalf_s *dev);
|
||||
static int tiva_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev);
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
static int tiva_pwm_start(FAR struct pwm_lowerhalf_s *dev,
|
||||
FAR const struct pwm_info_s *info, FAR void *handle);
|
||||
#else
|
||||
static int tiva_pwm_start(FAR struct pwm_lowerhalf_s *dev,
|
||||
FAR const struct pwm_info_s *info);
|
||||
#endif
|
||||
static int tiva_pwm_stop(FAR struct pwm_lowerhalf_s *dev);
|
||||
static int tiva_pwm_ioctl(FAR struct pwm_lowerhalf_s *dev,
|
||||
int cmd, unsigned long arg);
|
||||
@ -108,7 +144,7 @@ static int tiva_pwm_ioctl(FAR struct pwm_lowerhalf_s *dev,
|
||||
* Private Data
|
||||
************************************************************************************/
|
||||
|
||||
static uint32_t g_pwm_freq = 15000000;
|
||||
static uint32_t g_pwm_freq = 1875000;
|
||||
static uint32_t g_pwm_counter = (1 << 16);
|
||||
|
||||
static const struct pwm_ops_s g_pwm_ops =
|
||||
@ -129,6 +165,13 @@ static struct tiva_pwm_chan_s g_pwm_chan0 =
|
||||
.generator_id = 0,
|
||||
.generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 0,
|
||||
.channel_id = 0,
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
.inited = false,
|
||||
.irq = TIVA_IRQ_PWM0_GEN0,
|
||||
.count = 0,
|
||||
.cur_count = 0,
|
||||
.handle = NULL,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -141,6 +184,13 @@ static struct tiva_pwm_chan_s g_pwm_chan1 =
|
||||
.generator_id = 0,
|
||||
.generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 0,
|
||||
.channel_id = 1,
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
.inited = false,
|
||||
.irq = TIVA_IRQ_PWM0_GEN0,
|
||||
.count = 0,
|
||||
.cur_count = 0,
|
||||
.handle = NULL,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -153,6 +203,13 @@ static struct tiva_pwm_chan_s g_pwm_chan2 =
|
||||
.generator_id = 1,
|
||||
.generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 1,
|
||||
.channel_id = 2,
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
.inited = false,
|
||||
.irq = TIVA_IRQ_PWM0_GEN1,
|
||||
.count = 0,
|
||||
.cur_count = 0,
|
||||
.handle = NULL,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -165,6 +222,13 @@ static struct tiva_pwm_chan_s g_pwm_chan3 =
|
||||
.generator_id = 1,
|
||||
.generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 1,
|
||||
.channel_id = 3,
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
.inited = false,
|
||||
.irq = TIVA_IRQ_PWM0_GEN1,
|
||||
.count = 0,
|
||||
.cur_count = 0,
|
||||
.handle = NULL,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -177,6 +241,13 @@ static struct tiva_pwm_chan_s g_pwm_chan4 =
|
||||
.generator_id = 2,
|
||||
.generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 2,
|
||||
.channel_id = 4,
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
.inited = false,
|
||||
.irq = TIVA_IRQ_PWM0_GEN2,
|
||||
.count = 0,
|
||||
.cur_count = 0,
|
||||
.handle = NULL,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -189,6 +260,13 @@ static struct tiva_pwm_chan_s g_pwm_chan5 =
|
||||
.generator_id = 2,
|
||||
.generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 2,
|
||||
.channel_id = 5,
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
.inited = false,
|
||||
.irq = TIVA_IRQ_PWM0_GEN2,
|
||||
.count = 0,
|
||||
.cur_count = 0,
|
||||
.handle = NULL,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -198,9 +276,16 @@ static struct tiva_pwm_chan_s g_pwm_chan6 =
|
||||
.ops = &g_pwm_ops,
|
||||
.controller_id = 0,
|
||||
.controller_base = TIVA_PWM0_BASE,
|
||||
.generator_id = 3,
|
||||
.generator_id = 3,
|
||||
.generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 3,
|
||||
.channel_id = 6,
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
.inited = false,
|
||||
.irq = TIVA_IRQ_PWM0_GEN3,
|
||||
.count = 0,
|
||||
.cur_count = 0,
|
||||
.handle = NULL,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -213,6 +298,13 @@ static struct tiva_pwm_chan_s g_pwm_chan7 =
|
||||
.generator_id = 3,
|
||||
.generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 3,
|
||||
.channel_id = 7,
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
.inited = false,
|
||||
.irq = TIVA_IRQ_PWM0_GEN3,
|
||||
.count = 0,
|
||||
.cur_count = 0,
|
||||
.handle = NULL,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -220,6 +312,76 @@ static struct tiva_pwm_chan_s g_pwm_chan7 =
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: tiva_pwm_gen[n]_interrupt
|
||||
*
|
||||
* Description:
|
||||
* Pulse count interrupt handlers for PWM[n]
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_TIVA_PWM0_CHAN0)
|
||||
static int tiva_pwm_gen0_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
return tiva_pwm_interrupt(&g_pwm_chan0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_TIVA_PWM0_CHAN2)
|
||||
static int tiva_pwm_gen1_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
return tiva_pwm_interrupt(&g_pwm_chan2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_TIVA_PWM0_CHAN4)
|
||||
static int tiva_pwm_gen2_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
return tiva_pwm_interrupt(&g_pwm_chan4);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_TIVA_PWM0_CHAN6)
|
||||
static int tiva_pwm_gen3_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
return tiva_pwm_interrupt(&g_pwm_chan6);
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: tiva_pwm_interrupt
|
||||
*
|
||||
* Description:
|
||||
* Common pulse count interrupt handler.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_PWM_PULSECOUNT) && \
|
||||
(defined(CONFIG_TIVA_PWM0_CHAN0) || defined(CONFIG_TIVA_PWM0_CHAN2) || \
|
||||
defined(CONFIG_TIVA_PWM0_CHAN4) || defined(CONFIG_TIVA_PWM0_CHAN6))
|
||||
static int tiva_pwm_interrupt(struct tiva_pwm_chan_s *chan)
|
||||
{
|
||||
/* Clear interrupt */
|
||||
|
||||
tiva_pwm_putreg(chan, TIVA_PWMn_ISC_OFFSET, INT_SET << INTCMPAD);
|
||||
|
||||
/* Count down current pulse count */
|
||||
|
||||
chan->cur_count--;
|
||||
|
||||
/* Disable PWM generator and reload current pulse count */
|
||||
|
||||
if (chan->cur_count == 0)
|
||||
{
|
||||
tiva_pwm_putreg(chan, TIVA_PWMn_CTL_OFFSET, CTL_DISABLE << TIVA_PWMn_CTL_ENABLE);
|
||||
chan->cur_count = chan->count;
|
||||
pwm_expired(chan->handle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: tiva_pwm_getreg
|
||||
*
|
||||
@ -251,7 +413,7 @@ static inline void tiva_pwm_putreg(struct tiva_pwm_chan_s *chan,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_setup
|
||||
* Name: tiva_pwm_setup
|
||||
*
|
||||
* Description:
|
||||
* This method is called when the driver is opened. The lower half driver
|
||||
@ -288,7 +450,7 @@ static int tiva_pwm_setup(FAR struct pwm_lowerhalf_s *dev)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_shutdown
|
||||
* Name: tiva_pwm_shutdown
|
||||
*
|
||||
* Description:
|
||||
* This method is called when the driver is closed. The lower half driver
|
||||
@ -320,7 +482,7 @@ static int tiva_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_start
|
||||
* Name: tiva_pwm_start
|
||||
*
|
||||
* Description:
|
||||
* (Re-)initialize the timer resources and start the pulsed output
|
||||
@ -328,33 +490,117 @@ static int tiva_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev)
|
||||
* Input parameters:
|
||||
* dev - A reference to the lower half PWM driver state structure
|
||||
* info - A reference to the characteristics of the pulsed output
|
||||
* handle - This is the handle that was provided to the lower-half
|
||||
* start() method.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
static int tiva_pwm_start(FAR struct pwm_lowerhalf_s *dev,
|
||||
FAR const struct pwm_info_s *info, FAR void *handle)
|
||||
{
|
||||
FAR struct tiva_pwm_chan_s *chan = (FAR struct tiva_pwm_chan_s *)dev;
|
||||
pwminfo("start PWM for channel %d\n", chan->channel_id);
|
||||
|
||||
/* Save the handle */
|
||||
|
||||
chan->handle = handle;
|
||||
|
||||
/* Load pulse count and current pulse count
|
||||
*
|
||||
* Workaround:
|
||||
* Count should be add 1 for the first time
|
||||
*/
|
||||
|
||||
chan->count = info->count;
|
||||
chan->cur_count = info->count;
|
||||
|
||||
if (!chan->inited)
|
||||
{
|
||||
chan->count++;
|
||||
chan->cur_count++;
|
||||
chan->inited = true;
|
||||
}
|
||||
|
||||
/* Count 0 means to generate indefinite number of pulses */
|
||||
|
||||
if (info->count == 0)
|
||||
{
|
||||
pwm_expired(chan->handle);
|
||||
|
||||
/* Disable interrupt */
|
||||
|
||||
uint32_t enable = getreg32(chan->controller_base + TIVA_PWM_INTEN_OFFSET);
|
||||
enable &= ~(INT_ENABLE << chan->generator_id);
|
||||
putreg32(enable, chan->controller_base + TIVA_PWM_INTEN_OFFSET);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Enable interrupt */
|
||||
|
||||
uint32_t enable = getreg32(chan->controller_base + TIVA_PWM_INTEN_OFFSET);
|
||||
enable |= (INT_ENABLE << chan->generator_id);
|
||||
putreg32(enable, chan->controller_base + TIVA_PWM_INTEN_OFFSET);
|
||||
}
|
||||
|
||||
/* Start the timer */
|
||||
|
||||
return tiva_pwm_timer(chan, info);
|
||||
}
|
||||
#else
|
||||
static int tiva_pwm_start(FAR struct pwm_lowerhalf_s *dev,
|
||||
FAR const struct pwm_info_s *info)
|
||||
{
|
||||
FAR struct tiva_pwm_chan_s *chan = (FAR struct tiva_pwm_chan_s *)dev;
|
||||
pwminfo("start PWM for channel %d\n", chan->channel_id);
|
||||
|
||||
/* Start the timer */
|
||||
|
||||
return tiva_pwm_timer(chan, info);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tiva_pwm_timer
|
||||
*
|
||||
* Description:
|
||||
* Configure PWM registers and start the PWM timer
|
||||
*
|
||||
* Input parameters:
|
||||
* dev - A reference to the lower half PWM driver state structure
|
||||
* info - A reference to the characteristics of the pulsed output
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int tiva_pwm_start(FAR struct pwm_lowerhalf_s *dev,
|
||||
FAR const struct pwm_info_s *info)
|
||||
static inline int tiva_pwm_timer(FAR struct tiva_pwm_chan_s *chan,
|
||||
FAR const struct pwm_info_s *info)
|
||||
{
|
||||
FAR struct tiva_pwm_chan_s *chan = (FAR struct tiva_pwm_chan_s *)dev;
|
||||
pwminfo("start PWM for channel %d\n", chan->channel_id);
|
||||
|
||||
uint16_t duty = info->duty;
|
||||
uint32_t frequency = info->frequency;
|
||||
|
||||
pwminfo("> frequency = %d\n", frequency);
|
||||
pwminfo("> duty = %d\n", duty);
|
||||
|
||||
/* Configure PWM countdown mode (refer to TM4C1294NC 23.4.6) */
|
||||
|
||||
tiva_pwm_putreg(chan, TIVA_PWMn_CTL_OFFSET, 0);
|
||||
if (chan->channel_id % 2 == 0)
|
||||
{
|
||||
tiva_pwm_putreg(chan, TIVA_PWMn_GENA_OFFSET,
|
||||
GENx_LOW << TIVA_PWMn_GENx_ACTCMPAD | GENx_HIGH << TIVA_PWMn_GENx_ACTLOAD);
|
||||
GENx_LOW << TIVA_PWMn_GENx_ACTCMPAD |
|
||||
GENx_HIGH << TIVA_PWMn_GENx_ACTLOAD);
|
||||
}
|
||||
else
|
||||
{
|
||||
tiva_pwm_putreg(chan, TIVA_PWMn_GENB_OFFSET,
|
||||
GENx_LOW << TIVA_PWMn_GENx_ACTCMPBD | GENx_HIGH << TIVA_PWMn_GENx_ACTLOAD);
|
||||
GENx_LOW << TIVA_PWMn_GENx_ACTCMPBD |
|
||||
GENx_HIGH << TIVA_PWMn_GENx_ACTLOAD);
|
||||
}
|
||||
|
||||
/* Set the PWM period (refer to TM4C1294NC 23.4.7) */
|
||||
@ -363,7 +609,7 @@ static int tiva_pwm_start(FAR struct pwm_lowerhalf_s *dev,
|
||||
uint32_t pwm_max_freq = g_pwm_freq;
|
||||
uint32_t load = (uint32_t)(g_pwm_freq / frequency);
|
||||
|
||||
pwminfo("channel %d: load = %u (%08x)\n", chan->channel_id, load, load);
|
||||
pwminfo("> load = %u (%08x)\n", load, load);
|
||||
|
||||
if (load >= g_pwm_counter || load < 1)
|
||||
{
|
||||
@ -383,7 +629,7 @@ static int tiva_pwm_start(FAR struct pwm_lowerhalf_s *dev,
|
||||
|
||||
uint32_t comp = (uint32_t)((1 - (float)duty / g_pwm_counter) * load);
|
||||
comp = (duty == 0) ? (comp - 1) : (comp);
|
||||
pwminfo("channel %d: comp = %u (%08x)\n", chan->channel_id, comp, comp);
|
||||
pwminfo("> comp = %u (%08x)\n", comp, comp);
|
||||
|
||||
if (chan->channel_id % 2 == 0)
|
||||
{
|
||||
@ -408,7 +654,7 @@ static int tiva_pwm_start(FAR struct pwm_lowerhalf_s *dev,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_stop
|
||||
* Name: tiva_pwm_stop
|
||||
*
|
||||
* Description:
|
||||
* Stop the pulsed output and reset the timer resources
|
||||
@ -441,7 +687,7 @@ static int tiva_pwm_stop(FAR struct pwm_lowerhalf_s *dev)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_ioctl
|
||||
* Name: tiva_pwm_ioctl
|
||||
*
|
||||
* Description:
|
||||
* Lower-half logic may support platform-specific ioctl commands
|
||||
@ -550,11 +796,12 @@ FAR struct pwm_lowerhalf_s *tiva_pwm_initialize(int channel)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pwminfo("channel %d: channel_id=%d, ", channel, chan->channel_id);
|
||||
pwminfo("controller_id=%d, controller_base=%08x, ",
|
||||
chan->controller_id, chan->controller_base);
|
||||
pwminfo("generator_id=%d, generator_base=%08x\n",
|
||||
chan->generator_id, chan->generator_base);
|
||||
pwminfo("channel %d:\n", channel);
|
||||
pwminfo("> channel_id = %d\n", chan->channel_id);
|
||||
pwminfo("> controller_id = %d\n", chan->controller_id);
|
||||
pwminfo("> controller_base = %08x\n", chan->controller_base);
|
||||
pwminfo("> generator_id = %d\n", chan->generator_id);
|
||||
pwminfo("> generator_base = %08x\n", chan->generator_base);
|
||||
|
||||
/* Enable PWM controller (refer to TM4C1294NC 23.4.1) */
|
||||
|
||||
@ -564,14 +811,55 @@ FAR struct pwm_lowerhalf_s *tiva_pwm_initialize(int channel)
|
||||
|
||||
/* Configure PWM Clock Configuration (refer to TM4C1294NC 23.4.5)
|
||||
*
|
||||
* On TM4C1294NC, configure the PWM clock source as 15MHz (the system
|
||||
* clock 120MHz divided by 8)
|
||||
* On TM4C1294NC, configure the PWM clock source as 1.875MHz (the system
|
||||
* clock 120MHz divided by 64)
|
||||
*
|
||||
* TODO: need an algorithm to choose the best divider and load value combo.
|
||||
*/
|
||||
|
||||
putreg32(CC_USEPWM << TIVA_PWM_CC_USEPWM | CC_PWMDIV_8 << TIVA_PWM_CC_PWMDIV,
|
||||
putreg32(CC_USEPWM << TIVA_PWM_CC_USEPWM | CC_PWMDIV_64 << TIVA_PWM_CC_PWMDIV,
|
||||
chan->controller_base + TIVA_PWM_CC);
|
||||
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
|
||||
/* Enable interrupt INTCMPAD mode */
|
||||
|
||||
tiva_pwm_putreg(chan, TIVA_PWMn_INTEN_OFFSET, INT_SET << INTCMPAD);
|
||||
|
||||
/* Attach IRQ handler and enable interrupt*/
|
||||
|
||||
switch (chan->channel_id)
|
||||
{
|
||||
#ifdef CONFIG_TIVA_PWM0_CHAN0
|
||||
case 0:
|
||||
irq_attach(chan->irq, tiva_pwm_gen0_interrupt);
|
||||
up_enable_irq(chan->irq);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TIVA_PWM0_CHAN2
|
||||
case 2:
|
||||
irq_attach(chan->irq, tiva_pwm_gen1_interrupt);
|
||||
up_enable_irq(chan->irq);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TIVA_PWM0_CHAN4
|
||||
case 4:
|
||||
irq_attach(chan->irq, tiva_pwm_gen2_interrupt);
|
||||
up_enable_irq(chan->irq);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TIVA_PWM0_CHAN6
|
||||
case 6:
|
||||
irq_attach(chan->irq, tiva_pwm_gen3_interrupt);
|
||||
up_enable_irq(chan->irq);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return (FAR struct pwm_lowerhalf_s *)chan;
|
||||
}
|
||||
|
@ -46,6 +46,7 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Must match definitions in up_testset.c */
|
||||
|
||||
#define SP_UNLOCKED false /* The Un-locked state */
|
||||
|
@ -62,7 +62,10 @@ pthread_mutex_init NXpthread_mutex_init
|
||||
pthread_mutex_lock NXpthread_mutex_lock
|
||||
pthread_mutex_unlock NXpthread_mutex_unlock
|
||||
pthread_setspecific NXpthread_setspecific
|
||||
pthread_setcancelstate NXpthread_setcancelstate
|
||||
pthread_setcanceltype NXpthread_setcanceltype
|
||||
pthread_sigmask NXpthread_sigmask
|
||||
pthread_testcancel NXpthread_testcancel
|
||||
pthread_yield NXpthread_yield
|
||||
ptsname NXptsname
|
||||
ptsname_r NXptsname_r
|
||||
|
@ -52,7 +52,7 @@
|
||||
# include <arch/irq.h>
|
||||
# ifdef CONFIG_SMP
|
||||
# include <nuttx/sched.h>
|
||||
# include <arch/spinlock.h>
|
||||
# include <nuttx/spinlock.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -22,6 +22,10 @@ config ARCH_CHIP_ESP32
|
||||
of two CPUs is symmetric, meaning they use the same addresses to
|
||||
access the same memory.
|
||||
|
||||
The two CPUs are named "PRO_CPU" and "APP_CPU" (for "protocol" and
|
||||
"application"), however for most purposes the two CPUs are
|
||||
interchangeable.
|
||||
|
||||
endchoice # XTENSA chip selection
|
||||
|
||||
config ARCH_FAMILY_LX6
|
||||
|
@ -378,7 +378,7 @@
|
||||
#define ESP32_CPUINT_NEDGEPERIPHS 4
|
||||
#define EPS32_CPUINT_EDGESET 0x50400400
|
||||
|
||||
#define ESP32_CPUINT_NNMIPERIPHS 4
|
||||
#define ESP32_CPUINT_NNMIPERIPHS 1
|
||||
#define EPS32_CPUINT_NMISET 0x00004000
|
||||
|
||||
#define ESP32_CPUINT_TIMER0 6
|
||||
@ -388,11 +388,12 @@
|
||||
#define ESP32_CPUINT_TIMER2 16
|
||||
#define ESP32_CPUINT_SOFTWARE1 29
|
||||
|
||||
#define ESP32_CPUINT_NINTERNAL 5
|
||||
#define ESP32_CPUINT_NINTERNAL 6
|
||||
|
||||
#define ESP32_CPUINT_MAX 31
|
||||
#define EPS32_CPUINT_PERIPHSET 0xdffe6f3f
|
||||
#define EPS32_CPUINT_INTERNALSET 0x200180c0
|
||||
#define ESP32_NCPUINTS 32
|
||||
#define ESP32_CPUINT_MAX (ESP32_NCPUINTS - 1)
|
||||
#define EPS32_CPUINT_PERIPHSET 0xdffe773f
|
||||
#define EPS32_CPUINT_INTERNALSET 0x200188c0
|
||||
|
||||
/* Priority 1: 0-10, 12-13, 17-18 (15)
|
||||
* Priority 2: 19-21 (3)
|
||||
|
@ -108,20 +108,21 @@
|
||||
# define REG_LBEG (_REG_LOOPS_START + 0)
|
||||
# define REG_LEND (_REG_LOOPS_START + 1)
|
||||
# define REG_LCOUNT (_REG_LOOPS_START + 2)
|
||||
# define _REG_CALL0_START (_REG_LOOPS_START + 3)
|
||||
# define _REG_WINDOW_TMPS (_REG_LOOPS_START + 3)
|
||||
#else
|
||||
# define _REG_CALL0_START _REG_LOOPS_START
|
||||
# define _REG_WINDOW_TMPS _REG_LOOPS_START
|
||||
#endif
|
||||
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
/* Temporary space for saving stuff during window spill */
|
||||
/* Temporary space for saving stuff during window spill.
|
||||
* REVISIT: I don't think that we need so many temporaries.
|
||||
*/
|
||||
|
||||
# define REG_TMP0 (_REG_CALL0_START + 0)
|
||||
# define REG_TMP1 (_REG_CALL0_START + 1)
|
||||
# define REG_TMP2 (_REG_CALL0_START + 2)
|
||||
# define _REG_OVLY_START (_REG_CALL0_START + 3)
|
||||
# define REG_TMP0 (_REG_WINDOW_TMPS + 0)
|
||||
# define REG_TMP1 (_REG_WINDOW_TMPS + 1)
|
||||
# define _REG_OVLY_START (_REG_WINDOW_TMPS + 2)
|
||||
#else
|
||||
# define _REG_OVLY_START _REG_CALL0_START
|
||||
# define _REG_OVLY_START _REG_WINDOW_TMPS
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XTENSA_USE_OVLY
|
||||
|
@ -153,7 +153,8 @@ static inline uint32_t xtensa_get_cpenable(void)
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"rsr %0, CPENABLE" : "=r"(cpenable)
|
||||
"\trsr %0, CPENABLE\n"
|
||||
: "=r"(cpenable)
|
||||
);
|
||||
|
||||
return cpenable;
|
||||
@ -165,7 +166,9 @@ static inline void xtensa_set_cpenable(uint32_t cpenable)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"wsr %0, PS" : : "r"(cpenable)
|
||||
"\twsr %0, CPENABLE\n"
|
||||
"\trsync\n"
|
||||
: : "r"(cpenable)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -104,10 +104,30 @@
|
||||
|
||||
/* Check if an interrupt stack size is configured */
|
||||
|
||||
#ifndef CONFIG_ARCH_INTERRUPTSTACK
|
||||
# define CONFIG_ARCH_INTERRUPTSTACK 0
|
||||
#define HAVE_INTERRUPTSTACK 1
|
||||
|
||||
#if !defined(CONFIG_ARCH_INTERRUPTSTACK)
|
||||
# define CONFIG_ARCH_INTERRUPTSTACK 0
|
||||
# undef HAVE_INTERRUPTSTACK
|
||||
#elif CONFIG_ARCH_INTERRUPTSTACK < 16
|
||||
# warning CONFIG_ARCH_INTERRUPTSTACK is to small
|
||||
# undef HAVE_INTERRUPTSTACK
|
||||
#endif
|
||||
|
||||
#define INTERRUPTSTACK_SIZE ((CONFIG_ARCH_INTERRUPTSTACK + 15) & ~15)
|
||||
#define INTERRUPT_STACKWORDS (INTERRUPTSTACK_SIZE >> 2)
|
||||
|
||||
/* An IDLE thread stack size for CPU0 must be defined */
|
||||
|
||||
#if !defined(CONFIG_IDLETHREAD_STACKSIZE)
|
||||
# error CONFIG_IDLETHREAD_STACKSIZE is not defined
|
||||
#elif CONFIG_IDLETHREAD_STACKSIZE < 16
|
||||
# error CONFIG_IDLETHREAD_STACKSIZE is to small
|
||||
#endif
|
||||
|
||||
#define IDLETHREAD_STACKSIZE ((CONFIG_IDLETHREAD_STACKSIZE + 15) & ~15)
|
||||
#define IDLETHREAD_STACKWORDS (IDLETHREAD_STACKSIZE >> 2)
|
||||
|
||||
/* Used for stack usage measurements */
|
||||
|
||||
#define STACK_COLOR 0xdeadbeef
|
||||
@ -180,12 +200,16 @@ extern volatile uint32_t *g_current_regs[1];
|
||||
|
||||
#endif
|
||||
|
||||
/* Address of the saved user stack pointer */
|
||||
#ifdef HAVE_INTERRUPTSTACK
|
||||
/* The (optional) interrupt stack */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
extern void g_intstackbase;
|
||||
extern uint32_t g_intstack[INTERRUPT_STACKWORDS];
|
||||
#endif
|
||||
|
||||
/* Address of the CPU0 IDLE thread */
|
||||
|
||||
extern uint32_t g_idlestack[IDLETHREAD_STACKWORDS];
|
||||
|
||||
/* 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:
|
||||
@ -266,7 +290,7 @@ void xtensa_coproc_disable(struct xtensa_cpstate_s *cpstate, int cpset);
|
||||
|
||||
/* IRQs */
|
||||
|
||||
uint32_t *xtensa_int_decode(uint32_t *regs);
|
||||
uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs);
|
||||
uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs);
|
||||
uint32_t xtensa_enable_cpuint(uint32_t *shadow, uint32_t intmask);
|
||||
uint32_t xtensa_disable_cpuint(uint32_t *shadow, uint32_t intmask);
|
||||
@ -293,7 +317,8 @@ void xtensa_coproc_restorestate(struct xtensa_cpstate_s *cpstate);
|
||||
|
||||
/* Signals */
|
||||
|
||||
void xtensa_sigdeliver(void);
|
||||
void _xtensa_sig_trampoline(void);
|
||||
void xtensa_sig_deliver(void);
|
||||
|
||||
/* Chip-specific functions **************************************************/
|
||||
/* Chip specific functions defined in arch/xtensa/src/<chip> */
|
||||
|
@ -58,6 +58,27 @@
|
||||
* CALL8, or CALL12 instructions to save 4, 8, or 12 live registers. Calls
|
||||
* to routines that use a2..a7 for parameters may use only CALL8 or CALL12.
|
||||
*
|
||||
* Arguments are passed in both registers and memory. The first six incoming
|
||||
* arguments are stored in registers a2 through a7, and additional arguments
|
||||
* are stored on the stack starting at the current stack pointer a1. Because
|
||||
* Xtensa uses register windows that rotate during a function call, outgoing
|
||||
* arguments that will become the incoming arguments must be stored to
|
||||
* different register numbers. Depending on the call instruction and, thus,
|
||||
* the rotation of the register window, the arguments are passed starting
|
||||
* starting with register a(2+N), where N is the size of the window rotation.
|
||||
* Therefore, the first argument in case of a call4 instruction is placed into
|
||||
* a6, and for a call8 instruction into a10. Large arguments (8-bytes) are
|
||||
* always passed in an even/odd register pair even if that means to omit a
|
||||
* register for alignment. The return values are stored in a2 through a7.
|
||||
*
|
||||
* return addr stack ptr arg0, arg1, arg2, arg3, arg4, arg5
|
||||
* ----------- --------- ----------------------------------
|
||||
* a0 a1 a2, a3, a4, a5, a6, a7
|
||||
*
|
||||
* call4 a4 a5 a6, a7, a8, a9, a10, a11
|
||||
* call8 a8 a9 a10, a11, a12, a13, a14, a15
|
||||
* call12 a12 a13 a14, a15 --- --- --- ---
|
||||
*
|
||||
* The stack pointer SP should only be modified by ENTRY and MOVSP
|
||||
* instructions (except for initialization and restoration). If some other
|
||||
* instruction modifies SP, any values in the register-spill area will not
|
||||
|
214
arch/xtensa/src/common/xtensa_checkstack.c
Normal file
214
arch/xtensa/src/common/xtensa_checkstack.c
Normal file
@ -0,0 +1,214 @@
|
||||
/****************************************************************************
|
||||
* arch/xtensa/src/common/xtensa_checkstack.c
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/tls.h>
|
||||
#include <nuttx/board.h>
|
||||
|
||||
#include "xtensa.h"
|
||||
#include "sched/sched.h"
|
||||
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static size_t do_stackcheck(uintptr_t alloc, size_t size);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: do_stackcheck
|
||||
*
|
||||
* Description:
|
||||
* Determine (approximately) how much stack has been used be searching the
|
||||
* stack memory for a high water mark. That is, the deepest level of the
|
||||
* stack that clobbered some recognizable marker in the stack memory.
|
||||
*
|
||||
* Input Parameters:
|
||||
* alloc - Allocation base address of the stack
|
||||
* size - The size of the stack in bytes
|
||||
*
|
||||
* Returned value:
|
||||
* The estimated amount of stack space used.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static size_t do_stackcheck(uintptr_t alloc, size_t size)
|
||||
{
|
||||
FAR uintptr_t start;
|
||||
FAR uintptr_t end;
|
||||
FAR uint32_t *ptr;
|
||||
size_t mark;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get aligned addresses of the top and bottom of the stack */
|
||||
|
||||
#ifdef CONFIG_TLS
|
||||
/* Skip over the TLS data structure at the bottom of the stack */
|
||||
|
||||
DEBUGASSERT((alloc & TLS_STACK_MASK) == 0);
|
||||
start = alloc + sizeof(struct tls_info_s);
|
||||
#else
|
||||
start = alloc & ~3;
|
||||
#endif
|
||||
end = (alloc + size + 3) & ~3;
|
||||
|
||||
/* Get the adjusted size based on the top and bottom of the stack */
|
||||
|
||||
size = end - start;
|
||||
|
||||
/* The Xtensa CPUs use a push-down stack: the stack grows toward lower
|
||||
* addresses in memory. We need to start at the lowest address in the
|
||||
* stack memory allocation and search to higher addresses. The first word
|
||||
* we encounter that does not have the magic value is the high water mark.
|
||||
*/
|
||||
|
||||
for (ptr = (FAR uint32_t *)start, mark = (size >> 2);
|
||||
*ptr == STACK_COLOR && mark > 0;
|
||||
ptr++, mark--);
|
||||
|
||||
/* If the stack is completely used, then this might mean that the stack
|
||||
* overflowed from above (meaning that the stack is too small), or may
|
||||
* have been overwritten from below meaning that some other stack or data
|
||||
* structure overflowed.
|
||||
*
|
||||
* If you see returned values saying that the entire stack is being used
|
||||
* then enable the following logic to see it there are unused areas in the
|
||||
* middle of the stack.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
if (mark + 16 > nwords)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
ptr = (FAR uint32_t *)start;
|
||||
for (i = 0; i < size; i += 4*64)
|
||||
{
|
||||
for (j = 0; j < 64; j++)
|
||||
{
|
||||
int ch;
|
||||
if (*ptr++ == STACK_COLOR)
|
||||
{
|
||||
ch = '.';
|
||||
}
|
||||
else
|
||||
{
|
||||
ch = 'X';
|
||||
}
|
||||
|
||||
up_putc(ch);
|
||||
}
|
||||
|
||||
up_putc('\n');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return our guess about how much stack space was used */
|
||||
|
||||
return mark << 2;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_check_stack and friends
|
||||
*
|
||||
* Description:
|
||||
* Determine (approximately) how much stack has been used be searching the
|
||||
* stack memory for a high water mark. That is, the deepest level of the
|
||||
* stack that clobbered some recognizable marker in the stack memory.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned value:
|
||||
* The estimated amount of stack space used.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t up_check_tcbstack(FAR struct tcb_s *tcb)
|
||||
{
|
||||
return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size);
|
||||
}
|
||||
|
||||
ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb)
|
||||
{
|
||||
return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb);
|
||||
}
|
||||
|
||||
size_t up_check_stack(void)
|
||||
{
|
||||
return up_check_tcbstack(this_task());
|
||||
}
|
||||
|
||||
ssize_t up_check_stack_remain(void)
|
||||
{
|
||||
return up_check_tcbstack_remain(this_task());
|
||||
}
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
size_t up_check_intstack(void)
|
||||
{
|
||||
return do_stackcheck((uintptr_t)&g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3));
|
||||
}
|
||||
|
||||
size_t up_check_intstack_remain(void)
|
||||
{
|
||||
return (CONFIG_ARCH_INTERRUPTSTACK & ~3) - up_check_intstack();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_STACK_COLORATION */
|
@ -116,7 +116,6 @@
|
||||
|
||||
_xtensa_context_save:
|
||||
|
||||
s32i a2, a2, (4 * REG_A2)
|
||||
s32i a3, a2, (4 * REG_A3)
|
||||
s32i a4, a2, (4 * REG_A4)
|
||||
s32i a5, a2, (4 * REG_A5)
|
||||
@ -146,22 +145,13 @@ _xtensa_context_save:
|
||||
s32i a3, a2, (4 * REG_LCOUNT)
|
||||
#endif
|
||||
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
mov a9, a0 /* Preserve ret addr */
|
||||
#endif
|
||||
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
/* To spill the reg windows, temp. need pre-interrupt stack ptr and
|
||||
* a4-15. Need to save a9,12,13 temporarily (in frame temps) and
|
||||
* recover originals. Interrupts need to be disabled below
|
||||
* XCHAL_EXCM_LEVEL and window overflow and underflow exceptions
|
||||
* disabled (assured by PS.EXCM == 1).
|
||||
* a4-15. Interrupts need to be disabled below XCHAL_EXCM_LEVEL and
|
||||
* window overflow and underflow exceptions disabled (assured by
|
||||
* PS.EXCM == 1).
|
||||
*/
|
||||
|
||||
s32i a12, a2, (4 * REG_TMP0) /* Temp. save stuff in stack frame */
|
||||
s32i a13, a2, (4 * REG_TMP1)
|
||||
s32i a9, a2, (4 * REG_TMP2)
|
||||
|
||||
#ifdef CONFIG_XTENSA_USE_OVLY
|
||||
/* Save the overlay state if we are supporting overlays. Since we just
|
||||
* saved three registers, we can conveniently use them here. Note that
|
||||
@ -171,17 +161,16 @@ _xtensa_context_save:
|
||||
#error Overly support is not implemented
|
||||
#endif
|
||||
|
||||
l32i a12, a2, (4 * REG_A12) /* Recover original a9,12,13 */
|
||||
l32i a13, a2, (4 * REG_A13)
|
||||
l32i a9, a2, (4 * REG_A9)
|
||||
s32i a0, a2, (4 * REG_TMP0) /* Save return address */
|
||||
s32i sp, a2, (4 * REG_TMP1) /* Save current stack pointer */
|
||||
wsr a2, EXCSAVE_1 /* Preserve register save area */
|
||||
|
||||
#warning REVISIT: The following is probably not correct due to changes in registers
|
||||
addi sp, sp, (4 * XCPTCONTEXT_SIZE) /* Restore the interruptee's SP */
|
||||
call0 _xtensa_window_spill /* Preserves only a4,5,8,9,12,13 */
|
||||
addi sp, sp, -(4 * XCPTCONTEXT_SIZE)
|
||||
l32i a12, sp, (4 * REG_TMP0) /* Recover stuff from stack frame */
|
||||
l32i a13, sp, (4 * REG_TMP1)
|
||||
l32i a9, sp, (4 * REG_TMP2)
|
||||
l32i sp, a2, (4 * REG_A1) /* Restore the interruptee's SP */
|
||||
call0 _xtensa_window_spill /* Preserves only a4-a5, a8-a9, a12-a13 */
|
||||
|
||||
rsr a2, EXCSAVE_1 /* Save interruptee's a0 */
|
||||
l32i a0, a2, (4 * REG_TMP0) /* Save return address */
|
||||
l32i sp, a2, (4 * REG_TMP1) /* Save current stack pointer */
|
||||
#endif
|
||||
|
||||
ret
|
||||
@ -193,13 +182,11 @@ _xtensa_context_save:
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* NOTE: MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION!
|
||||
*
|
||||
* This functions implements the moral equivalent of setjmp(). It is
|
||||
* called from user code (with interrupts disabled) to save the current
|
||||
* state of the running thread. This function always returns zero.
|
||||
* However, it sets the saved value of the return address (A2) to 1.
|
||||
* If the thread is restarted via _xtensa_contest_restore or
|
||||
* If the thread is s via _xtensa_context_restore or
|
||||
* xtensa_context_restore, it will appear as a second return from
|
||||
* xtensa_context_save but with the returned value of 1 to distinguish
|
||||
* the two cases.
|
||||
@ -217,6 +204,24 @@ _xtensa_context_save:
|
||||
* Assumptions:
|
||||
* - Interrupts are disabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_context_save:
|
||||
*
|
||||
* Description:
|
||||
* This implementation of xtensa_context_save for the case of the CALL0 ABI
|
||||
*
|
||||
* Input State:
|
||||
* a0 = The return value to the caller.
|
||||
* a2 = The address of the register state state structure
|
||||
*
|
||||
* Return state:
|
||||
* a0 = The return value to the caller.
|
||||
* a2, a12-a15 preserved as at entry
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.global xtensa_context_save
|
||||
@ -227,30 +232,185 @@ _xtensa_context_save:
|
||||
.align 4
|
||||
|
||||
xtensa_context_save:
|
||||
ENTRY(16)
|
||||
|
||||
/* Set up for call to _xtensa_context_save() */
|
||||
/* Set up for (potential) call to _xtensa_context_save() */
|
||||
|
||||
rsr a12, PS /* Save callee's PS */
|
||||
s32i a12, a2, (4 * REG_PS)
|
||||
s32i a3, a2, (4 * REG_A3) /* Get scratch register */
|
||||
rsr a3, PS /* Save callee's PS */
|
||||
s32i a3, a2, (4 * REG_PS)
|
||||
s32i a0, a2, (4 * REG_PC) /* Save Return address as PC */
|
||||
|
||||
s32i a0, a2, (4 * REG_A0) /* Save callee's a0 */
|
||||
s32i sp, a2, (4 * REG_A1) /* Save callee's SP */
|
||||
movi a12, 1 /* Set saved A2 to 1 */
|
||||
s32i a12, a2, (4 * REG_A2)
|
||||
movi a3, 1 /* Set saved A2 to 1 */
|
||||
s32i a3, a2, (4 * REG_A2)
|
||||
|
||||
/* Save the rest of the processor state */
|
||||
/* Save the rest of the processor state. For the CALL0 ABI, we can user
|
||||
* _xtensa_context_save(), Otherwise we duplicate the context save here
|
||||
* to avoid the window spill.
|
||||
*/
|
||||
|
||||
l32i r3, a2, (4 * REG_A3) /* Recover original a3 */
|
||||
call0 _xtensa_context_save /* Save full register state */
|
||||
|
||||
/* Recover the return address and return zero */
|
||||
|
||||
l32i a0, a2, (4 * REG_A0) /* Recover return addess */
|
||||
movi a2, 0 /* Return zero */
|
||||
|
||||
ret
|
||||
RET(16)
|
||||
|
||||
.size xtensa_context_save, . - xtensa_context_save
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* This implementation of xtensa_context_save for the case of the window ABI.
|
||||
* This case is more complex. For the Window ABI, there is a "hook" that
|
||||
* performs the low level state state. xtensa_context_save() is a simply
|
||||
* trampoline function that performs the window oeprations in that
|
||||
* configuration.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
|
||||
/****************************************************************************
|
||||
* Name: _xtensa_save_hook:
|
||||
*
|
||||
* Input State:
|
||||
* True return value has already been saved
|
||||
* a0 = The return value into xtensa_context_save()
|
||||
* a2 = The address of the register state state structure
|
||||
*
|
||||
* Return state:
|
||||
* a0, a3 modified.
|
||||
* Other values as on entry
|
||||
* Returned value is in a3 (non-stanadard)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.type _xtensa_save_hook, @function
|
||||
|
||||
.align 4
|
||||
.literal_position
|
||||
.align 4
|
||||
|
||||
_xtensa_save_hook:
|
||||
|
||||
/* Save the return value of 1 that will be used when returning from a
|
||||
* context switch. NOTE that the returned value from this function is
|
||||
* expected in a3 (not the usual a2). This also frees up a3 for a use
|
||||
* as a scratch register.
|
||||
*/
|
||||
|
||||
movi a3, 1 /* Set saved a3 to 1 */
|
||||
s32i a3, a2, (4 * REG_A3)
|
||||
|
||||
/* Save the rest of the processor state.
|
||||
*
|
||||
* REVISIT: We could save a lot here. It should not be necessary to
|
||||
* preserve all of these registers. The ABI permits volatile, callee-
|
||||
* saved, registers to be clobbered on function calls. We save the
|
||||
* whole tamale here mostly for debug purposes.
|
||||
*
|
||||
* NOTE that a3 was saved above. The true a0 return value was saved
|
||||
* in xtensa_context_save. The a0 value saved below is the return into
|
||||
* xtensa_context_save.
|
||||
*/
|
||||
|
||||
rsr a3, PS /* Save callee's PS */
|
||||
s32i a3, a2, (4 * REG_PS)
|
||||
s32i a0, a2, (4 * REG_PC) /* Save Return address as PC */
|
||||
|
||||
s32i sp, a2, (4 * REG_A1) /* Save callee's SP */
|
||||
s32i a2, a2, (4 * REG_A2)
|
||||
s32i a4, a2, (4 * REG_A4) /* Save remaining registers */
|
||||
s32i a5, a2, (4 * REG_A5)
|
||||
s32i a6, a2, (4 * REG_A6)
|
||||
s32i a7, a2, (4 * REG_A7)
|
||||
s32i a8, a2, (4 * REG_A8)
|
||||
s32i a9, a2, (4 * REG_A9)
|
||||
s32i a10, a2, (4 * REG_A10)
|
||||
s32i a11, a2, (4 * REG_A11)
|
||||
|
||||
/* Call0 ABI callee-saved regs a12-15 */
|
||||
|
||||
s32i a12, a2, (4 * REG_A12)
|
||||
s32i a13, a2, (4 * REG_A13)
|
||||
s32i a14, a2, (4 * REG_A14)
|
||||
s32i a15, a2, (4 * REG_A15)
|
||||
|
||||
rsr a3, SAR
|
||||
s32i a3, a2, (4 * REG_SAR)
|
||||
|
||||
#ifdef XCHAL_HAVE_LOOPS
|
||||
rsr a3, LBEG
|
||||
s32i a3, a2, (4 * REG_LBEG)
|
||||
rsr a3, LEND
|
||||
s32i a3, a2, (4 * REG_LEND)
|
||||
rsr a3, LCOUNT
|
||||
s32i a3, a2, (4 * REG_LCOUNT)
|
||||
#endif
|
||||
|
||||
/* NOTE that the returned value is through a3 */
|
||||
|
||||
movi a3, 0 /* Return zero, no context switch */
|
||||
ret
|
||||
|
||||
.size _xtensa_save_hook, . - _xtensa_save_hook
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_context_save:
|
||||
*
|
||||
* Description:
|
||||
* This is the implementation of xtensa_context_save for the case of the
|
||||
* window ABI. In the window ABI configuration, xtensa_context_save is a
|
||||
* thin "trampoline" layer. It performs the ENTRY window operations on
|
||||
* entry and the exit. A call0 is used to force the retun from the context
|
||||
* switch to the window return within this trampoline.
|
||||
*
|
||||
* Input State:
|
||||
* a0 = The true return value to the caller.
|
||||
* a2 = The address of the register state state structure
|
||||
*
|
||||
* Return state:
|
||||
* a0, a2, and a3 modified.
|
||||
* Returned value is in a2
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.global xtensa_context_save
|
||||
.type xtensa_context_save, @function
|
||||
|
||||
.align 4
|
||||
.literal_position
|
||||
.align 4
|
||||
|
||||
xtensa_context_save:
|
||||
ENTRY(16)
|
||||
|
||||
/* Save the true return address in the register save structure (a0). */
|
||||
|
||||
s32i a0, a2, (4 * REG_A0) /* Save true return address (a0) */
|
||||
|
||||
/* Then perform the actual state save in _xtensa_save_hook. The saved
|
||||
* EPC will be set to the return from this function then we will do the
|
||||
* RET(16) window fix-up.
|
||||
*/
|
||||
|
||||
call0 _xtensa_save_hook /* Save full register state */
|
||||
|
||||
/* a0 and a2 will be automatically restored in the context switch case
|
||||
* with a3=1. In the non-context switch return with a2=0, a2 will still
|
||||
* be valid, but we have to restore a0 ourself. The following should
|
||||
* work in either case.
|
||||
*/
|
||||
|
||||
l32i a0, a2, (4 * REG_A0) /* Recover the true return address (a0) */
|
||||
mov a2, a3 /* Move a3 to the correct register for return */
|
||||
RET(16)
|
||||
|
||||
.size xtensa_context_save, . - xtensa_context_save
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: _xtensa_context_restore
|
||||
@ -273,12 +433,13 @@ xtensa_context_save:
|
||||
*
|
||||
* Exit conditions:
|
||||
* - A0 = Return address in caller.
|
||||
* - Other registers are restored as detailed above (including A1 and A2).
|
||||
* - Other registers are restored as detailed above
|
||||
* - A2 is preserved
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.global _xtensa_context_restore
|
||||
.type _xtensa_context_restore,@function
|
||||
.type xtensa_context_restore,@function
|
||||
|
||||
.align 4
|
||||
.literal_position
|
||||
@ -287,12 +448,12 @@ xtensa_context_save:
|
||||
_xtensa_context_restore:
|
||||
|
||||
#ifdef XCHAL_HAVE_LOOPS
|
||||
l32i a2, a2, (4 * REG_LBEG)
|
||||
l32i a3, a2, (4 * REG_LEND)
|
||||
wsr a2, LBEG
|
||||
l32i a2, a2, (4 * REG_LCOUNT)
|
||||
wsr a3, LEND
|
||||
wsr a2, LCOUNT
|
||||
l32i a3, a2, (4 * REG_LBEG)
|
||||
l32i a4, a2, (4 * REG_LEND)
|
||||
wsr a3, LBEG
|
||||
l32i a3, a2, (4 * REG_LCOUNT)
|
||||
wsr a4, LEND
|
||||
wsr a3, LCOUNT
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XTENSA_USE_OVLY
|
||||
@ -326,10 +487,6 @@ _xtensa_context_restore:
|
||||
l32i a14, a2, (4 * REG_A14)
|
||||
l32i a15, a2, (4 * REG_A15)
|
||||
|
||||
/* Finally, restore A2 with the correct value */
|
||||
|
||||
l32i a2, a2, (4 * REG_A2)
|
||||
|
||||
ret
|
||||
|
||||
.size _xtensa_context_restore, . - _xtensa_context_restore
|
||||
@ -339,8 +496,6 @@ _xtensa_context_restore:
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* NOTE: MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION!
|
||||
*
|
||||
* This functions implements the moral equivalent of longjmp(). It is
|
||||
* called from user code (with interrupts disabled) to restor the current
|
||||
* state of the running thread. This function always appears to be a
|
||||
@ -372,8 +527,40 @@ _xtensa_context_restore:
|
||||
.align 4
|
||||
|
||||
xtensa_context_restore:
|
||||
ENTRY(16)
|
||||
|
||||
/* Restore the processor state */
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
/* Force a spill of the live registers of the thread that has been
|
||||
* suspended.
|
||||
*
|
||||
* _xtensa_window_spill return state:
|
||||
* a2, a3: clobbered
|
||||
* a4,a5,a8,a9,a12,a13: preserved
|
||||
* a6,a7,a10,a11,a14,a15 clobbered if they were part of window(s)
|
||||
* to be spilled, otherwise they are the same as on entry
|
||||
* loop registers: Perserved
|
||||
* SAR: clobbered
|
||||
*
|
||||
* We need to preserve only a2 for _xtensa_context_restore
|
||||
*/
|
||||
|
||||
mov a4, a2 /* Save a2 in a preserved register */
|
||||
rsr a5, PS /* Save PS in preserved register */
|
||||
|
||||
movi a3, ~(PS_WOE_MASK | PS_INTLEVEL_MASK)
|
||||
and a2, a5, a3 /* Clear WOE, INTLEVEL */
|
||||
addi a2, a2, XCHAL_EXCM_LEVEL /* Set INTLEVEL = XCHAL_EXCM_LEVEL */
|
||||
wsr a2, PS /* Apply to PS */
|
||||
rsync
|
||||
|
||||
call0 _xtensa_window_spill
|
||||
wsr a5, PS /* Restore PS */
|
||||
rsync
|
||||
|
||||
mov a2, a4 /* Recover a2 */
|
||||
#endif
|
||||
|
||||
/* Restore the processor state for the newly started thread */
|
||||
|
||||
call0 _xtensa_context_restore /* Restore full register state */
|
||||
|
||||
@ -382,10 +569,15 @@ xtensa_context_restore:
|
||||
l32i a0, a2, (4 * REG_PS) /* Restore PS */
|
||||
wsr a0, PS
|
||||
l32i a0, a2, (4 * REG_PC) /* Set up for RFE */
|
||||
rsr a0, EPC
|
||||
wsr a0, EPC_1
|
||||
l32i a0, a2, (4 * REG_A0) /* Restore a0 */
|
||||
l32i a2, a2, (4 * REG_A2) /* Restore A2 */
|
||||
|
||||
/* Return from exception. RFE returns from either the UserExceptionVector
|
||||
* or the KernelExceptionVector. RFE sets PS.EXCM back to 0, and then
|
||||
* jumps to the address in EPC[1]. PS.UM and PS.WOE are left unchanged.
|
||||
*/
|
||||
|
||||
rfe /* And return from "exception" */
|
||||
|
||||
.size xtensa_context_restore, . - xtensa_context_restore
|
||||
|
@ -225,26 +225,12 @@ xtensa_coproc_savestate:
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
|
||||
/* Need to preserve a8-11. _xtensa_coproc_savestate modifies a2-a7,
|
||||
* a13-a15. So no registers need be saved.
|
||||
* a13-a15. a12-a15 are callee saved registers so a13-a14 must be
|
||||
* preserved.
|
||||
*/
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
/* Call _xtensa_coproc_savestate() with A2=address of co-processor
|
||||
* save area.
|
||||
*/
|
||||
|
||||
call0 _xtensa_coproc_savestate
|
||||
RET(16)
|
||||
|
||||
#else
|
||||
|
||||
/* Need to preserve a8-15. _xtensa_coproc_savestate modifies a2-a7,
|
||||
* a13-a15. So only a13-a15 need be preserved.
|
||||
*/
|
||||
|
||||
ENTRY(16)
|
||||
s32i a13, sp, LOCAL_OFFSET(1)
|
||||
s32i a13, sp, LOCAL_OFFSET(1) /* Save clobbered registers */
|
||||
s32i a14, sp, LOCAL_OFFSET(2)
|
||||
s32i a15, sp, LOCAL_OFFSET(3)
|
||||
|
||||
@ -256,12 +242,30 @@ xtensa_coproc_savestate:
|
||||
|
||||
/* Restore a13-15 and return */
|
||||
|
||||
l32i a13, sp, LOCAL_OFFSET(1)
|
||||
l32i a13, sp, LOCAL_OFFSET(1) /* Restore clobbered registers */
|
||||
l32i a14, sp, LOCAL_OFFSET(2)
|
||||
l32i a15, sp, LOCAL_OFFSET(3)
|
||||
|
||||
RET(16)
|
||||
|
||||
#else
|
||||
/* Need to preserve a8-15. _xtensa_coproc_savestate modifies a2-a7,
|
||||
* a13-a15. So a13-a15 may need to be preserved.
|
||||
*/
|
||||
|
||||
ENTRY(32 /*16*/) /* REVISIT: Why 32? */
|
||||
s32i a0, sp, LOCAL_OFFSET(1) /* Save return address */
|
||||
|
||||
/* Call _xtensa_coproc_savestate() with A2=address of co-processor
|
||||
* save area.
|
||||
*/
|
||||
|
||||
call0 _xtensa_coproc_savestate
|
||||
|
||||
/* Restore a0 and return */
|
||||
|
||||
l32i a0, sp, LOCAL_OFFSET(1) /* Recover return address */
|
||||
RET(32 /*16*/) /* REVISIT: Why 32? */
|
||||
|
||||
#endif
|
||||
|
||||
.size xtensa_coproc_savestate, . - xtensa_coproc_savestate
|
||||
@ -420,43 +424,47 @@ xtensa_coproc_restorestate:
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
|
||||
/* Need to preserve a8-11. _xtensa_coproc_restorestate modifies a2-a7,
|
||||
* a13-a15. So no registers need be saved.
|
||||
* a13-a15. a12-a15 are callee saved registers so a13-a14 must be
|
||||
* preserved.
|
||||
*/
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
/* Call _xtensa_coproc_restorestate() with A2=address of co-processor
|
||||
* save area.
|
||||
*/
|
||||
|
||||
call0 _xtensa_coproc_restorestate
|
||||
RET(16)
|
||||
|
||||
#else
|
||||
|
||||
/* Need to preserve a8-15. _xtensa_coproc_savestate modifies a2-a7,
|
||||
* a13-a15. So only a13-a15 need be preserved.
|
||||
*/
|
||||
|
||||
ENTRY(16)
|
||||
s32i a13, sp, LOCAL_OFFSET(1)
|
||||
s32i a13, sp, LOCAL_OFFSET(1) /* Save clobbered values */
|
||||
s32i a14, sp, LOCAL_OFFSET(2)
|
||||
s32i a15, sp, LOCAL_OFFSET(3)
|
||||
|
||||
/* Call _xtensa_coproc_restorestate() with A2=address of co-processor
|
||||
* save area.
|
||||
* save area. Registers a0, a2-a7, a13-a15 have been trashed.
|
||||
*/
|
||||
|
||||
call0 _xtensa_coproc_restorestate
|
||||
|
||||
/* Restore a13-15 and return */
|
||||
/* Restore a13-a15 and return */
|
||||
|
||||
l32i a13, sp, LOCAL_OFFSET(1)
|
||||
l32i a13, sp, LOCAL_OFFSET(1) /* Restore clobbered registers */
|
||||
l32i a14, sp, LOCAL_OFFSET(2)
|
||||
l32i a15, sp, LOCAL_OFFSET(3)
|
||||
|
||||
RET(16)
|
||||
|
||||
#else
|
||||
/* Need to preserve a8-15. _xtensa_coproc_savestate modifies a2-a7,
|
||||
* a13-a15. So a13-a15 may need to be preserved.
|
||||
*/
|
||||
|
||||
ENTRY(32 /*16*/) /* REVISIT: Why 32? */
|
||||
s32i a0, sp, LOCAL_OFFSET(1) /* Save return address */
|
||||
|
||||
/* Call _xtensa_coproc_restorestate() with A2=address of co-processor
|
||||
* save area. Registers a0, a2-a7, a13-a15 have been trashed.
|
||||
*/
|
||||
|
||||
call0 _xtensa_coproc_restorestate
|
||||
|
||||
/* Restore a0 and return */
|
||||
|
||||
l32i a0, sp, LOCAL_OFFSET(1) /* Recover return address */
|
||||
RET(32 /*16*/) /* REVISIT: Why 32? */
|
||||
|
||||
#endif
|
||||
|
||||
.size xtensa_coproc_restorestate, . - xtensa_coproc_restorestate
|
||||
|
@ -40,6 +40,8 @@
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/chip/core-isa.h>
|
||||
|
||||
#include "xtensa_abi.h"
|
||||
|
||||
#if XCHAL_HAVE_INTERRUPTS
|
||||
|
||||
/****************************************************************************
|
||||
@ -69,6 +71,7 @@
|
||||
.align 4
|
||||
|
||||
xtensa_enable_cpuint:
|
||||
ENTRY(16)
|
||||
|
||||
movi a4, 0
|
||||
xsr a4, INTENABLE /* Disables all interrupts */
|
||||
@ -80,7 +83,7 @@ xtensa_enable_cpuint:
|
||||
|
||||
wsr a5, INTENABLE /* Set CPU INTENABLE to shadow */
|
||||
mov a3, a4 /* Return previous shadow content */
|
||||
ret
|
||||
RET(16)
|
||||
|
||||
.size xtensa_enable_cpuint, . - xtensa_enable_cpuint
|
||||
|
||||
@ -107,6 +110,7 @@ xtensa_enable_cpuint:
|
||||
.align 4
|
||||
|
||||
xtensa_disable_cpuint:
|
||||
ENTRY(16)
|
||||
|
||||
movi a4, 0
|
||||
xsr a4, INTENABLE /* Disables all interrupts */
|
||||
@ -119,7 +123,7 @@ xtensa_disable_cpuint:
|
||||
|
||||
wsr a5, INTENABLE /* Set CPU INTENABLE to shadow */
|
||||
mov a3, a4 /* Return previous shadow content */
|
||||
ret
|
||||
RET(16)
|
||||
|
||||
.size xtensa_disable_cpuint, . - xtensa_disable_cpuint
|
||||
|
||||
|
@ -164,6 +164,7 @@ int up_cpu_paused(int cpu)
|
||||
}
|
||||
|
||||
spin_unlock(&g_cpu_wait[cpu]);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -78,6 +78,42 @@ static inline uint32_t xtensa_getsp(void)
|
||||
return sp;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_taskdump
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
static void up_taskdump(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
{
|
||||
/* Dump interesting properties of this task */
|
||||
|
||||
#if CONFIG_TASK_NAME_SIZE > 0
|
||||
_alert("%s: PID=%d Stack Used=%lu of %lu\n",
|
||||
tcb->name, tcb->pid, (unsigned long)up_check_tcbstack(tcb),
|
||||
(unsigned long)tcb->adj_stack_size);
|
||||
#else
|
||||
_alert("PID: %d Stack Used=%lu of %lu\n",
|
||||
tcb->pid, (unsigned long)up_check_tcbstack(tcb),
|
||||
(unsigned long)tcb->adj_stack_size);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_showtasks
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
static inline void up_showtasks(void)
|
||||
{
|
||||
/* Dump interesting properties of each task in the crash environment */
|
||||
|
||||
sched_foreach(up_taskdump, NULL);
|
||||
}
|
||||
#else
|
||||
# define up_showtasks()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_stackdump
|
||||
****************************************************************************/
|
||||
@ -130,9 +166,8 @@ static inline void xtensa_registerdump(void)
|
||||
(unsigned long)regs[REG_LCOUNT]);
|
||||
#endif
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
_alert(" TMP0: %08lx TMP1: %08lx TMP2: %08lx\n",
|
||||
(unsigned long)regs[REG_TMP0], (unsigned long)regs[REG_TMP1],
|
||||
(unsigned long)regs[REG_TMP2]);
|
||||
_alert(" TMP0: %08lx TMP1: %08lx\n",
|
||||
(unsigned long)regs[REG_TMP0], (unsigned long)regs[REG_TMP1]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -151,7 +186,7 @@ void xtensa_dumpstate(void)
|
||||
uint32_t sp = xtensa_getsp();
|
||||
uint32_t ustackbase;
|
||||
uint32_t ustacksize;
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
#ifdef HAVE_INTERRUPTSTACK
|
||||
uint32_t istackbase;
|
||||
uint32_t istacksize;
|
||||
#endif
|
||||
@ -166,14 +201,8 @@ void xtensa_dumpstate(void)
|
||||
|
||||
if (rtcb->pid == 0)
|
||||
{
|
||||
#warning REVISIT: Need top of IDLE stack
|
||||
#if 0
|
||||
ustackbase = g_idle_topstack - 4;
|
||||
ustacksize = CONFIG_IDLETHREAD_STACKSIZE;
|
||||
#else
|
||||
ustackbase = sp + 128;
|
||||
ustacksize = 128;
|
||||
#endif
|
||||
ustackbase = (uint32_t)&g_idlestack[IDLETHREAD_STACKWORDS-1];
|
||||
ustacksize = IDLETHREAD_STACKSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -184,9 +213,9 @@ void xtensa_dumpstate(void)
|
||||
/* Get the limits on the interrupt stack memory */
|
||||
|
||||
#warning REVISIT interrupt stack
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
istackbase = (uint32_t)&g_intstackbase;
|
||||
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4;
|
||||
#ifdef HAVE_INTERRUPTSTACK
|
||||
istackbase = (uint32_t)&g_intstack[INTERRUPT_STACKWORDS-1];
|
||||
istacksize = INTERRUPTSTACK_SIZE;
|
||||
|
||||
/* Show interrupt stack info */
|
||||
|
||||
@ -194,6 +223,9 @@ void xtensa_dumpstate(void)
|
||||
_alert("IRQ stack:\n");
|
||||
_alert(" base: %08x\n", istackbase);
|
||||
_alert(" size: %08x\n", istacksize);
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
_alert(" used: %08x\n", up_check_intstack());
|
||||
#endif
|
||||
|
||||
/* Does the current stack pointer lie within the interrupt
|
||||
* stack?
|
||||
@ -209,7 +241,7 @@ void xtensa_dumpstate(void)
|
||||
* at the base of the interrupt stack.
|
||||
*/
|
||||
|
||||
sp = g_intstackbase;
|
||||
sp = &g_instack[INTERRUPTSTACK_SIZE - sizeof(uint32_t)];
|
||||
_alert("sp: %08x\n", sp);
|
||||
}
|
||||
|
||||
@ -218,10 +250,16 @@ void xtensa_dumpstate(void)
|
||||
_alert("User stack:\n");
|
||||
_alert(" base: %08x\n", ustackbase);
|
||||
_alert(" size: %08x\n", ustacksize);
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
_alert(" used: %08x\n", up_check_tcbstack(rtcb));
|
||||
#endif
|
||||
#else
|
||||
_alert("sp: %08x\n", sp);
|
||||
_alert("stack base: %08x\n", ustackbase);
|
||||
_alert("stack size: %08x\n", ustacksize);
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
_alert("stack used: %08x\n", up_check_tcbstack(rtcb));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Dump the user stack if the stack pointer lies within the allocated user
|
||||
@ -230,7 +268,7 @@ void xtensa_dumpstate(void)
|
||||
|
||||
if (sp > ustackbase || sp <= ustackbase - ustacksize)
|
||||
{
|
||||
#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4
|
||||
#ifdef HAVE_INTERRUPTSTACK
|
||||
_alert("ERROR: Stack pointer is not within allocated stack\n");
|
||||
#endif
|
||||
}
|
||||
@ -242,6 +280,10 @@ void xtensa_dumpstate(void)
|
||||
/* Then dump the registers (if available) */
|
||||
|
||||
xtensa_registerdump();
|
||||
|
||||
/* Dump the state of all tasks (if available) */
|
||||
|
||||
up_showtasks();
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ARCH_STACKDUMP */
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include <arch/chip/core-isa.h>
|
||||
#include <arch/xtensa/xtensa_specregs.h>
|
||||
|
||||
#include "xtensa.h"
|
||||
#include "xtensa_abi.h"
|
||||
#include "chip_macros.h"
|
||||
#include "xtensa_timer.h"
|
||||
@ -125,37 +126,25 @@
|
||||
* a consequence of context switching.
|
||||
*/
|
||||
|
||||
mov a12, sp /* a12 = address of save area */
|
||||
|
||||
._xtensa_dispatch_level&level&:
|
||||
mov a12, sp /* Address of save area */
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
/* Get mask of pending, enabled interrupts at this level into a2. */
|
||||
|
||||
rsr a2, INTENABLE
|
||||
rsr a3, INTERRUPT
|
||||
movi a4, \mask
|
||||
and a2, a2, a3
|
||||
and a2, a2, a4
|
||||
beqz a2, 5f /* Nothing to do */
|
||||
|
||||
/* If multiple bits are set then MSB has highest priority. */
|
||||
|
||||
extract_msb a4, a2 /* a4 = MSB of a2, a2 trashed */
|
||||
|
||||
movi a3, XT_TIMER_INTEN /* a3 = timer interrupt bit */
|
||||
wsr a4, INTCLEAR /* Clear sw or edge-triggered interrupt */
|
||||
beq a3, a4, 4f /* If timer interrupt then skip table */
|
||||
and a2, a2, a4 /* a2 = Set of pending, enabled interrupts for this level */
|
||||
beqz a2, 1f /* Nothing to do */
|
||||
|
||||
/* Call xtensa_int_decode with, passing that address of the register save
|
||||
* area as a parameter (A2).
|
||||
*/
|
||||
|
||||
mov a2, a12 /* Argument: Top of stack = register save area */
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
/* Argument 1: Set of CPU interrupt to dispatch */
|
||||
mov a3, sp /* Argument 2: Top of stack = register save area */
|
||||
call0 xtensa_int_decode /* Call xtensa_int_decode */
|
||||
#else
|
||||
call4 xtensa_int_decode /* Call xtensa_int_decode */
|
||||
#endif
|
||||
|
||||
/* On return from xtensa_int_decode, a2 will contain the address of the new
|
||||
* register save area. Usually this would be the same as the current SP.
|
||||
@ -163,55 +152,38 @@
|
||||
* register save area. This may or may not reside on a stack.
|
||||
*/
|
||||
|
||||
beq a2, a12, 3f /* If timer interrupt then skip table */
|
||||
|
||||
/* Switch stacks */
|
||||
|
||||
mov a12, a2 /* Switch to the save area of the new thread */
|
||||
l32i a2, a12, (4 * REG_A1) /* Retrieve stack ptr and replace */
|
||||
addi sp, a2, -(4 * XCPTCONTEXT_SIZE)
|
||||
|
||||
3:
|
||||
j ._xtensa_dispatch_level&level& /* Check for more interrupts */
|
||||
#else
|
||||
/* Get mask of pending, enabled interrupts at this level into a2. */
|
||||
|
||||
4:
|
||||
rsr a6, INTENABLE
|
||||
rsr a2, INTERRUPT
|
||||
movi a3, \mask
|
||||
and a6, a6, a2
|
||||
and a6, a6, a3 /* a6 = Set of pending, enabled interrupts for this level */
|
||||
beqz a6, 1f /* Nothing to do */
|
||||
|
||||
.ifeq XT_TIMER_INTPRI - \level
|
||||
|
||||
/* Interrupt handler for the NuttX system timer if at this level.
|
||||
* We'll be reading the interrupt state again after this call
|
||||
* so no need to preserve any registers except a7 (pointer to
|
||||
* state save area).
|
||||
/* Call xtensa_int_decode with, passing that address of the register save
|
||||
* area as a parameter (A2).
|
||||
*/
|
||||
|
||||
movi a2, XTENSA_IRQ_TIMER&level& /* Argument 1: IRQ number */
|
||||
mov a3, a12 /* Argument 2: Top of stack = register save area */
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
call0 xtensa_irq_dispatch /* Call xtensa_int_decode */
|
||||
#else
|
||||
call4 xtensa_irq_dispatch /* Call xtensa_int_decode */
|
||||
/* Argument 1: Set of CPU interrupt to dispatch */
|
||||
mov a7, sp /* Argument 2: Top of stack = register save area */
|
||||
call4 xtensa_int_decode /* Call xtensa_int_decode */
|
||||
|
||||
/* On return from xtensa_int_decode, a6 will contain the address of the new
|
||||
* register save area. Usually this would be the same as the current SP.
|
||||
* But in the event of a context switch, a2 will instead refer to the TCB
|
||||
* register save area. This may or may not reside on a stack.
|
||||
*/
|
||||
|
||||
mov a12, a6 /* Switch to the save area of the new thread */
|
||||
#endif
|
||||
|
||||
/* On return from xtensa_irq_dispatch, A2 will contain the address of the new
|
||||
* register save area. Usually this would be the same as the current SP.
|
||||
* But in the event of a context switch, A2 will instead refer to the TCB
|
||||
* register save area.
|
||||
*/
|
||||
|
||||
beq a2, a12, 5f /* If timer interrupt then skip table */
|
||||
|
||||
/* Switch stacks */
|
||||
|
||||
mov a12, a2 /* Switch to the save area of the new thread */
|
||||
l32i a2, a12, (4 * REG_A1) /* Retrieve stack ptr and replace */
|
||||
addi sp, a2, -(4 * XCPTCONTEXT_SIZE)
|
||||
.endif
|
||||
|
||||
j ._xtensa_dispatch_level&level& /* Check for more interrupts */
|
||||
|
||||
5:
|
||||
/* done */
|
||||
|
||||
/* Done */
|
||||
1:
|
||||
.endm
|
||||
|
||||
/****************************************************************************
|
||||
@ -270,6 +242,7 @@
|
||||
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_level1_handler, @function
|
||||
.global _xtensa_level1_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_level1_handler:
|
||||
@ -306,24 +279,25 @@ _xtensa_level1_handler:
|
||||
/* Restore registers in preparation to return from interrupt */
|
||||
|
||||
mov a2, a12 /* a2 = address of new state save area */
|
||||
call0 _xtensa_context_restore
|
||||
call0 _xtensa_context_restore /* (preserves a2) */
|
||||
|
||||
/* Restore only level-specific regs (the rest were already restored) */
|
||||
|
||||
l32i a0, sp, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
l32i a0, a2, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
wsr a0, PS
|
||||
l32i a0, sp, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
l32i a0, a2, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
wsr a0, EPC_1
|
||||
l32i a0, sp, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i a2, sp, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
l32i sp, sp, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
rsync /* Ensure EPS and EPC written */
|
||||
l32i a0, a2, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i sp, a2, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
l32i a2, a2, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
rsync /* Ensure PS and EPC written */
|
||||
|
||||
/* Return from interrupt. RFI restores the PS from EPS_1 and jumps to
|
||||
* the address in EPC_1.
|
||||
/* Return from exception. RFE returns from either the UserExceptionVector
|
||||
* or the KernelExceptionVector. RFE sets PS.EXCM back to 0, and then
|
||||
* jumps to the address in EPC[1]. PS.UM and PS.WOE are left unchanged.
|
||||
*/
|
||||
|
||||
rfi 1
|
||||
rfe /* And return from "exception" */
|
||||
|
||||
/****************************************************************************
|
||||
* MEDIUM PRIORITY (LEVEL 2+) INTERRUPT LOW LEVEL HANDLERS.
|
||||
@ -354,6 +328,7 @@ _xtensa_level1_handler:
|
||||
#if XCHAL_EXCM_LEVEL >= 2
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_level2_handler, @function
|
||||
.global _xtensa_level2_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_level2_handler:
|
||||
@ -390,17 +365,17 @@ _xtensa_level2_handler:
|
||||
/* Restore registers in preparation to return from interrupt */
|
||||
|
||||
mov a2, a12 /* a2 = address of new state save area */
|
||||
call0 _xtensa_context_restore
|
||||
call0 _xtensa_context_restore /* (preserves a2) */
|
||||
|
||||
/* Restore only level-specific regs (the rest were already restored) */
|
||||
|
||||
l32i a0, sp, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
l32i a0, a2, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
wsr a0, EPS_2
|
||||
l32i a0, sp, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
l32i a0, a2, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
wsr a0, EPC_2
|
||||
l32i a0, sp, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i a2, sp, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
l32i sp, sp, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
l32i a0, a2, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i sp, a2, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
l32i a2, a2, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
rsync /* Ensure EPS and EPC written */
|
||||
|
||||
/* Return from interrupt. RFI restores the PS from EPS_2 and jumps to
|
||||
@ -414,6 +389,7 @@ _xtensa_level2_handler:
|
||||
#if XCHAL_EXCM_LEVEL >= 3
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_level3_handler, @function
|
||||
.global _xtensa_level3_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_level3_handler:
|
||||
@ -450,17 +426,17 @@ _xtensa_level3_handler:
|
||||
/* Restore registers in preparation to return from interrupt */
|
||||
|
||||
mov a2, a12 /* a2 = address of new state save area */
|
||||
call0 _xtensa_context_restore
|
||||
call0 _xtensa_context_restore /* (preserves a2) */
|
||||
|
||||
/* Restore only level-specific regs (the rest were already restored) */
|
||||
|
||||
l32i a0, sp, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
l32i a0, a2, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
wsr a0, EPS_3
|
||||
l32i a0, sp, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
l32i a0, a2, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
wsr a0, EPC_3
|
||||
l32i a0, sp, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i a2, sp, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
l32i sp, sp, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
l32i a0, a2, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i sp, a2, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
l32i a2, a2, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
rsync /* Ensure EPS and EPC written */
|
||||
|
||||
/* Return from interrupt. RFI restores the PS from EPS_3 and jumps to
|
||||
@ -474,6 +450,7 @@ _xtensa_level3_handler:
|
||||
#if XCHAL_EXCM_LEVEL >= 4
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_level4_handler, @function
|
||||
.global _xtensa_level4_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_level4_handler:
|
||||
@ -510,17 +487,17 @@ _xtensa_level4_handler:
|
||||
/* Restore registers in preparation to return from interrupt */
|
||||
|
||||
mov a2, a12 /* a2 = address of new state save area */
|
||||
call0 _xtensa_context_restore
|
||||
call0 _xtensa_context_restore /* (presevers a2) */
|
||||
|
||||
/* Restore only level-specific regs (the rest were already restored) */
|
||||
|
||||
l32i a0, sp, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
l32i a0, a2, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
wsr a0, EPS_4
|
||||
l32i a0, sp, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
l32i a0, a2, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
wsr a0, EPC_4
|
||||
l32i a0, sp, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i a2, sp, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
l32i sp, sp, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
l32i a0, a2, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i sp, a2, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
l32i a2, a2, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
rsync /* Ensure EPS and EPC written */
|
||||
|
||||
/* Return from interrupt. RFI restores the PS from EPS_4 and jumps to
|
||||
@ -534,6 +511,7 @@ _xtensa_level4_handler:
|
||||
#if XCHAL_EXCM_LEVEL >= 5
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_level5_handler, @function
|
||||
.global _xtensa_level5_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_level5_handler:
|
||||
@ -570,17 +548,17 @@ _xtensa_level5_handler:
|
||||
/* Restore registers in preparation to return from interrupt */
|
||||
|
||||
mov a2, a12 /* a2 = address of new state save area */
|
||||
call0 _xtensa_context_restore
|
||||
call0 _xtensa_context_restore /* (preserves a2) */
|
||||
|
||||
/* Restore only level-specific regs (the rest were already restored) */
|
||||
|
||||
l32i a0, sp, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
l32i a0, a2, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
wsr a0, EPS_5
|
||||
l32i a0, sp, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
l32i a0, a2, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
wsr a0, EPC_5
|
||||
l32i a0, sp, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i a2, sp, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
l32i sp, sp, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
l32i a0, a2, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i sp, a2, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
l32i a2, a2, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
rsync /* Ensure EPS and EPC written */
|
||||
|
||||
/* Return from interrupt. RFI restores the PS from EPS_5 and jumps to
|
||||
@ -594,6 +572,7 @@ _xtensa_level5_handler:
|
||||
#if XCHAL_EXCM_LEVEL >= 6
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_level6_handler, @function
|
||||
.global _xtensa_level6_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_level6_handler:
|
||||
@ -630,17 +609,17 @@ _xtensa_level6_handler:
|
||||
/* Restore registers in preparation to return from interrupt */
|
||||
|
||||
mov a2, a12 /* a2 = address of new state save area */
|
||||
call0 _xtensa_context_restore
|
||||
call0 _xtensa_context_restore /* (preserves a2) */
|
||||
|
||||
/* Restore only level-specific regs (the rest were already restored) */
|
||||
|
||||
l32i a0, sp, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
l32i a0, a2, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
wsr a0, EPS_6
|
||||
l32i a0, sp, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
l32i a0, a2, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
wsr a0, EPC_6
|
||||
l32i a0, sp, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i a2, sp, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
l32i sp, sp, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
l32i a0, a2, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i sp, a2, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
l32i a2, a2, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
rsync /* Ensure EPS and EPC written */
|
||||
|
||||
/* Return from interrupt. RFI restores the PS from EPS_6 and jumps to
|
||||
@ -690,6 +669,7 @@ _xtensa_level6_handler:
|
||||
#if XCHAL_INT_NLEVELS >=2 && XCHAL_EXCM_LEVEL < 2 && XCHAL_DEBUGLEVEL !=2
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_level2_handler, @function
|
||||
.global _xtensa_level2_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_level2_handler:
|
||||
@ -723,6 +703,7 @@ _xtensa_level2_handler:
|
||||
#if XCHAL_INT_NLEVELS >=3 && XCHAL_EXCM_LEVEL < 3 && XCHAL_DEBUGLEVEL !=3
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_level3_handler, @function
|
||||
.global _xtensa_level3_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_level3_handler:
|
||||
@ -758,6 +739,7 @@ _xtensa_level3_handler:
|
||||
#if XCHAL_INT_NLEVELS >=4 && XCHAL_EXCM_LEVEL < 4 && XCHAL_DEBUGLEVEL !=4
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_level4_handler, @function
|
||||
.global _xtensa_level4_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_level4_handler:
|
||||
@ -793,6 +775,7 @@ _xtensa_level4_handler:
|
||||
#if XCHAL_INT_NLEVELS >=5 && XCHAL_EXCM_LEVEL < 5 && XCHAL_DEBUGLEVEL !=5
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_level5_handler, @function
|
||||
.global _xtensa_level5_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_level5_handler:
|
||||
@ -828,6 +811,7 @@ _xtensa_level5_handler:
|
||||
#if XCHAL_INT_NLEVELS >=6 && XCHAL_EXCM_LEVEL < 6 && XCHAL_DEBUGLEVEL !=6
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_level6_handler, @function
|
||||
.global _xtensa_level6_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_level6_handler:
|
||||
|
@ -99,14 +99,14 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* If an interrupt level context switch has occurred, then save the
|
||||
* co-processor state in in the suspended thread's co-processor save
|
||||
* area.
|
||||
*
|
||||
* NOTE 1. The state of the co-processor has not been altered and
|
||||
* still represents the to-be-suspended thread.
|
||||
* NOTE 2. We saved a reference TCB of the original thread on entry.
|
||||
*/
|
||||
/* If an interrupt level context switch has occurred, then save the
|
||||
* co-processor state in in the suspended thread's co-processor save
|
||||
* area.
|
||||
*
|
||||
* NOTE 1. The state of the co-processor has not been altered and
|
||||
* still represents the to-be-suspended thread.
|
||||
* NOTE 2. We saved a reference TCB of the original thread on entry.
|
||||
*/
|
||||
|
||||
xtensa_coproc_savestate(&tcb->xcp.cpstate);
|
||||
|
||||
|
@ -59,10 +59,13 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
#include <arch/xtensa/core.h>
|
||||
#include <arch/xtensa/xtensa_specregs.h>
|
||||
|
||||
#include "chip_macros.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -95,6 +98,10 @@
|
||||
.align 4
|
||||
|
||||
_xtensa_panic:
|
||||
/* Save the exception code */
|
||||
|
||||
wsr a2, EXCSAVE_1
|
||||
|
||||
/* Save rest of interrupt context (A2=address of state save area on
|
||||
* stack.
|
||||
*/
|
||||
@ -111,17 +118,25 @@ _xtensa_panic:
|
||||
|
||||
/* Set up PS for C, reenable hi-pri interrupts, and clear EXCM. */
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM
|
||||
#else
|
||||
movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE
|
||||
#endif
|
||||
|
||||
wsr a0, PS
|
||||
|
||||
/* Call C panic handler: Arg1 (A2) = Exception code; Arg 2 (A3) = start
|
||||
* of the register save area.
|
||||
*/
|
||||
|
||||
mov a3, sp
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
rsr a2, EXCSAVE_1
|
||||
mov a3, sp
|
||||
call0 xtensa_panic /* Call xtensa_panic. Should not return */
|
||||
#else
|
||||
rsr a6, EXCSAVE_1
|
||||
mov a7, sp
|
||||
call4 xtensa_panic /* Call xtensa_panic. Should not return */
|
||||
#endif
|
||||
|
||||
|
@ -150,7 +150,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
* disabled
|
||||
*/
|
||||
|
||||
CURRENT_REGS[REG_PC] = (uint32_t)xtensa_sigdeliver;
|
||||
CURRENT_REGS[REG_PC] = (uint32_t)_xtensa_sig_trampoline;
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
CURRENT_REGS[REG_PS] = (uint32_t)(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM);
|
||||
#else
|
||||
@ -185,7 +185,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
* disabled
|
||||
*/
|
||||
|
||||
tcb->xcp.regs[REG_PC] = (uint32_t)xtensa_sigdeliver;
|
||||
tcb->xcp.regs[REG_PC] = (uint32_t)_xtensa_sig_trampoline;
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
tcb->xcp.regs[REG_PS] = (uint32_t)(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM);
|
||||
#else
|
||||
|
@ -58,7 +58,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_sigdeliver
|
||||
* Name: xtensa_sig_deliver
|
||||
*
|
||||
* Description:
|
||||
* This is the a signal handling trampoline. When a signal action was
|
||||
@ -67,7 +67,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void xtensa_sigdeliver(void)
|
||||
void xtensa_sig_deliver(void)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
uint32_t regs[XCPTCONTEXT_REGS];
|
||||
|
@ -1,8 +1,10 @@
|
||||
/****************************************************************************
|
||||
* configs/compal_e88/boot.c
|
||||
* arch/xtensa/src/common/xtensa_sigtramp.S
|
||||
*
|
||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
* Adapted from use in NuttX by:
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -33,43 +35,49 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.file "xtensa_sigtramp.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/board.h>
|
||||
|
||||
#include "xtensa_abi.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_app_initialize
|
||||
* Name: _xtensa_sig_trampoline
|
||||
*
|
||||
* Description:
|
||||
* Perform architecture specific initialization
|
||||
* Just sets up a proper window call to xtensa_sig_deliver(). We get
|
||||
* here via a context switch setup in up_schedule_signaction. Which
|
||||
* re-vectors the context switch to this location.
|
||||
*
|
||||
* Input Parameters:
|
||||
* arg - The boardctl() argument is passed to the board_app_initialize()
|
||||
* implementation without modification. The argument has no
|
||||
* meaning to NuttX; the meaning of the argument is a contract
|
||||
* between the board-specific initalization logic and the the
|
||||
* matching application logic. The value cold be such things as a
|
||||
* mode enumeration value, a set of DIP switch switch settings, a
|
||||
* pointer to configuration data read from a file or serial FLASH,
|
||||
* or whatever you would like to do with it. Every implementation
|
||||
* should accept zero/NULL as a default configuration.
|
||||
* Here we just call xtensa_sig_deliver() using the proper ABI. NOTE
|
||||
* that this function cannot return and depends on the fact that
|
||||
* xtensa_sig_deliver() does not return.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIB_BOARDCTL
|
||||
int board_app_initialize(uintptr_t arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_LIB_BOARDCTL */
|
||||
.text
|
||||
.global _xtensa_sig_trampoline
|
||||
.type _xtensa_sig_trampoline, @function
|
||||
.align 4
|
||||
|
||||
_xtensa_sig_trampoline:
|
||||
ENTRY(16) /* REVISIT: This should not be here */
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
cali0 xtensa_sig_deliver /* Call xtensa_sig_deliver */
|
||||
#else
|
||||
call4 xtensa_sig_deliver /* Call xtensa_sig_deliver */
|
||||
#endif
|
||||
|
||||
1: j 1b /* xtensa_sig_deliver does not return */
|
||||
|
||||
.size _xtensa_sig_trampoline, . - _xtensa_sig_trampoline
|
@ -59,10 +59,13 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
#include <arch/xtensa/core.h>
|
||||
#include <arch/xtensa/xtensa_specregs.h>
|
||||
|
||||
#include "chip_macros.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Assembly Language Macros
|
||||
****************************************************************************/
|
||||
@ -158,6 +161,7 @@ _xtensa_to_coproc_handler:
|
||||
****************************************************************************/
|
||||
|
||||
.type _xtensa_user_handler, @function
|
||||
.global _xtensa_user_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_user_handler:
|
||||
@ -225,12 +229,13 @@ _xtensa_user_handler:
|
||||
* beginning of the register save area.
|
||||
*/
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
rsr a2, EXCCAUSE /* Argument 1 (a2) = EXCCAUSE */
|
||||
mov a3, sp /* Argument 2 (a2) = pointer to register save area */
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
calx0 xtensa_user /* Call xtensa_user */
|
||||
#else
|
||||
rsr a6, EXCCAUSE /* Argument 1 (a2) = EXCCAUSE */
|
||||
mov a7, sp /* Argument 2 (a2) = pointer to register save area */
|
||||
call4 xtensa_user /* Call xtensa_user */
|
||||
#endif
|
||||
|
||||
@ -254,6 +259,7 @@ _xtensa_user_handler:
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_syscall_handler, @function
|
||||
.align 4
|
||||
|
||||
_xtensa_syscall_handler:
|
||||
|
||||
/* Allocate stack frame and save A0, A1, and PS */
|
||||
@ -323,54 +329,52 @@ _xtensa_syscall_handler:
|
||||
ps_setup 1 a0
|
||||
|
||||
/* Dispatch the sycall as with other interrupts. */
|
||||
/* At this point, sp holds the pointer to the register save area. That,
|
||||
* however, may change as a consequence of context switching.
|
||||
*/
|
||||
|
||||
mov a12, sp /* a12 = address of register save area */
|
||||
movi a2, XTENSA_IRQ_SYSCALL /* Argument 1: IRQ number */
|
||||
mov a3, a12 /* Argument 2: Top of stack = register save area */
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
call0 xtensa_irq_dispatch /* Call xtensa_int_decode */
|
||||
#else
|
||||
call4 xtensa_irq_dispatch /* Call xtensa_int_decode */
|
||||
#endif
|
||||
|
||||
/* On return from xtensa_irq_dispatch, A2 will contain the address of the new
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
movi a2, XTENSA_IRQ_SYSCALL /* Argument 1: IRQ number */
|
||||
mov a3, sp /* Argument 2: Top of stack = register save area */
|
||||
call0 xtensa_irq_dispatch /* Call xtensa_int_decode */
|
||||
|
||||
/* On return from xtensa_irq_dispatch, a2 will contain the address of the new
|
||||
* register save area. Usually this would be the same as the current SP.
|
||||
* But in the event of a context switch, A2 will instead refer to the TCB
|
||||
* register save area.
|
||||
*/
|
||||
|
||||
beq a2, a12, 2f /* If timer interrupt then skip table */
|
||||
#else
|
||||
movi a6, XTENSA_IRQ_SYSCALL /* Argument 1: IRQ number */
|
||||
mov a7, sp /* Argument 2: Top of stack = register save area */
|
||||
call4 xtensa_irq_dispatch /* Call xtensa_int_decode */
|
||||
|
||||
/* Switch stacks */
|
||||
/* On return from xtensa_irq_dispatch, a5 will contain the address of the new
|
||||
* register save area. Usually this would be the same as the current SP.
|
||||
* But in the event of a context switch, A2 will instead refer to the TCB
|
||||
* register save area.
|
||||
*/
|
||||
|
||||
mov a12, a2 /* Switch to the save area of the new thread */
|
||||
l32i a2, a12, (4 * REG_A1) /* Retrieve stack ptr and replace */
|
||||
addi sp, a2, -(4 * XCPTCONTEXT_SIZE)
|
||||
|
||||
2:
|
||||
mov a2, a6 /* Switch to the new register save area */
|
||||
#endif
|
||||
|
||||
/* Restore registers in preparation to return from interrupt */
|
||||
|
||||
mov a2, a12 /* a2 = address of new state save area */
|
||||
call0 _xtensa_context_restore
|
||||
call0 _xtensa_context_restore /* (Preserves a2) */
|
||||
|
||||
/* Restore only level-specific regs (the rest were already restored) */
|
||||
|
||||
l32i a0, sp, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
l32i a0, a2, (4 * REG_PS) /* Retrieve interruptee's PS */
|
||||
wsr a0, PS
|
||||
l32i a0, sp, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
l32i a0, a2, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
wsr a0, EPC_1
|
||||
l32i a0, sp, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i a2, sp, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
l32i sp, sp, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
l32i a0, a2, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i sp, a2, (4 * REG_A1) /* Remove interrupt stack frame */
|
||||
l32i a2, a2, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
rsync /* Ensure EPS and EPC written */
|
||||
|
||||
/* Return from exception. RFE returns from either the UserExceptionVector
|
||||
* or the KernelExceptionVector. RFE sets PS.EXCM back to 0 and then jumps
|
||||
* to the address in EPC[1].
|
||||
/* Return from exception. RFE returns from either the UserExceptionVector
|
||||
* or the KernelExceptionVector. RFE sets PS.EXCM back to 0, and then
|
||||
* jumps to the address in EPC[1]. PS.UM and PS.WOE are left unchanged.
|
||||
*/
|
||||
|
||||
rfe
|
||||
@ -463,12 +467,13 @@ _xtensa_coproc_handler:
|
||||
* beginning of the register save area.
|
||||
*/
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
rsr a2, EXCCAUSE /* Argument 1 (a2) = EXCCAUSE */
|
||||
mov a3, sp /* Argument 2 (a2) = pointer to register save area */
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
calx0 xtensa_user /* Call xtensa_user */
|
||||
#else
|
||||
rsr a6, EXCCAUSE /* Argument 1 (a2) = EXCCAUSE */
|
||||
mov a7, sp /* Argument 2 (a2) = pointer to register save area */
|
||||
call4 xtensa_user /* Call xtensa_user */
|
||||
#endif
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <arch/chip/core-isa.h>
|
||||
#include <arch/xtensa/xtensa_specregs.h>
|
||||
|
||||
#include "xtensa.h"
|
||||
#include "xtensa_abi.h"
|
||||
|
||||
/****************************************************************************
|
||||
@ -74,7 +75,7 @@ _xtensa_level2_vector:
|
||||
|
||||
/* Never returns here - call0 is used as a jump */
|
||||
|
||||
.end literal_prefix
|
||||
.end literal_prefix
|
||||
|
||||
.size _xtensa_level2_vector, . - _xtensa_level2_vector
|
||||
#endif
|
||||
@ -93,7 +94,7 @@ _xtensa_level3_vector:
|
||||
|
||||
/* Never returns here - call0 is used as a jump */
|
||||
|
||||
.end literal_prefix
|
||||
.end literal_prefix
|
||||
|
||||
.size _xtensa_level3_vector, . - _xtensa_level3_vector
|
||||
#endif
|
||||
@ -112,7 +113,7 @@ _xtensa_level4_vector:
|
||||
|
||||
/* Never returns here - call0 is used as a jump */
|
||||
|
||||
.end literal_prefix
|
||||
.end literal_prefix
|
||||
|
||||
.size _xtensa_level5_vector, . - _xtensa_level5_vector
|
||||
#endif
|
||||
@ -131,8 +132,8 @@ _xtensa_level5_vector:
|
||||
|
||||
/* Never returns here - call0 is used as a jump */
|
||||
|
||||
.size _xtensa_level5_vector, . - _xtensa_level5_vector
|
||||
.end literal_prefix
|
||||
.size _xtensa_level5_vector, . - _xtensa_level5_vector
|
||||
.end literal_prefix
|
||||
#endif
|
||||
|
||||
#if XCHAL_EXCM_LEVEL >= 6
|
||||
@ -202,7 +203,7 @@ _xtensa_nmi_vector:
|
||||
s32i a0, sp, (4 * REG_A0)
|
||||
|
||||
s32i a2, sp, (4 * REG_A2)
|
||||
movi a2, XTENSA_NMI_EXCEPTION /* Address of state save on stack */
|
||||
movi a2, XTENSA_NMI_EXCEPTION /* Argument 1: Error code */
|
||||
call0 _xtensa_panic /* Does not return */
|
||||
|
||||
#else
|
||||
@ -226,10 +227,10 @@ _xtensa_nmi_vector:
|
||||
****************************************************************************/
|
||||
|
||||
#if XCHAL_HAVE_DEBUG
|
||||
.begin literal_prefix .debug_exception_vector
|
||||
.section .debug_exception_vector.text, "ax"
|
||||
.global _debug_exception_vector
|
||||
.align 4
|
||||
.begin literal_prefix .debug_exception_vector
|
||||
.section .debug_exception_vector.text, "ax"
|
||||
.global _debug_exception_vector
|
||||
.align 4
|
||||
|
||||
_debug_exception_vector:
|
||||
|
||||
@ -244,7 +245,7 @@ _debug_exception_vector:
|
||||
s32i a0, sp, (4 * REG_A0)
|
||||
|
||||
s32i a2, sp, (4 * REG_A2)
|
||||
movi a2, XTENSA_DEBUG_EXCEPTION /* Address of state save on stack */
|
||||
movi a2, XTENSA_DEBUG_EXCEPTION /* Argument 1: Error code */
|
||||
call0 _xtensa_panic /* Does not return */
|
||||
|
||||
.end literal_prefix
|
||||
@ -261,10 +262,10 @@ _debug_exception_vector:
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef XCHAL_DOUBLEEXC_VECTOR_VADDR
|
||||
.begin literal_prefix .double_exception_vector
|
||||
.section .double_exception_vector.text, "ax"
|
||||
.global _double_exception_vector
|
||||
.align 4
|
||||
.begin literal_prefix .double_exception_vector
|
||||
.section .double_exception_vector.text, "ax"
|
||||
.global _double_exception_vector
|
||||
.align 4
|
||||
|
||||
_double_exception_vector:
|
||||
|
||||
@ -279,14 +280,19 @@ _double_exception_vector:
|
||||
s32i a0, sp, (4 * REG_PS)
|
||||
rsr a0, DEPC /* Save interruptee's PC */
|
||||
s32i a0, sp, (4 * REG_PC)
|
||||
rsr a0, EXCSAVE_1 /* Save interruptee's a0 -- REVISIT */
|
||||
rsr a0, EXCSAVE /* Save interruptee's a0 -- REVISIT */
|
||||
s32i a0, sp, (4 * REG_A0)
|
||||
|
||||
rsr a0, EXCCAUSE /* Save the EXCCAUSE register */
|
||||
s32i a0, sp, (4 * REG_EXCCAUSE)
|
||||
rsr a0, EXCVADDR /* Save the EXCVADDR register */
|
||||
s32i a0, sp, (4 * REG_EXCVADDR)
|
||||
|
||||
s32i a2, sp, (4 * REG_A2)
|
||||
movi a2, XTENSA_DOUBLE_EXCEPTION /* Address of state save on stack */
|
||||
movi a2, XTENSA_DOUBLE_EXCEPTION /* Argument 1: Error code */
|
||||
call0 _xtensa_panic /* Does not return */
|
||||
|
||||
.end literal_prefix
|
||||
.end literal_prefix
|
||||
|
||||
#endif /* XCHAL_DOUBLEEXC_VECTOR_VADDR */
|
||||
|
||||
@ -298,10 +304,10 @@ _double_exception_vector:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.begin literal_prefix .kernel_exception_vector
|
||||
.section .kernel_exception_vector.text, "ax"
|
||||
.global _kernel_exception_vector
|
||||
.align 4
|
||||
.begin literal_prefix .kernel_exception_vector
|
||||
.section .kernel_exception_vector.text, "ax"
|
||||
.global _kernel_exception_vector
|
||||
.align 4
|
||||
|
||||
_kernel_exception_vector:
|
||||
|
||||
@ -320,7 +326,7 @@ _kernel_exception_vector:
|
||||
s32i a0, sp, (4 * REG_A0)
|
||||
|
||||
s32i a2, sp, (4 * REG_A2)
|
||||
movi a2, XTENSA_KERNEL_EXCEPTION /* Address of state save on stack */
|
||||
movi a2, XTENSA_KERNEL_EXCEPTION /* Argument 1: Error code */
|
||||
call0 _xtensa_panic /* Does not return */
|
||||
|
||||
.end literal_prefix
|
||||
@ -333,15 +339,15 @@ _kernel_exception_vector:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.begin literal_prefix .user_exception_vector
|
||||
.section .user_exception_vector.text, "ax"
|
||||
.global _user_exception_vector
|
||||
.type _user_exception_vector, @function
|
||||
.align 4
|
||||
.begin literal_prefix .user_exception_vector
|
||||
.section .user_exception_vector.text, "ax"
|
||||
.global _user_exception_vector
|
||||
.type _user_exception_vector, @function
|
||||
.align 4
|
||||
|
||||
_user_exception_vector:
|
||||
|
||||
wsr a0, EXCSAVE_1 /* Preserve a0 */
|
||||
call0 xtensa_user_handler /* And jump to user exception handler */
|
||||
call0 _xtensa_user_handler /* And jump to user exception handler */
|
||||
|
||||
.end literal_prefix
|
||||
|
@ -35,14 +35,14 @@
|
||||
|
||||
# The start-up, "head", file. May be either a .S or a .c file.
|
||||
|
||||
HEAD_ASRC =
|
||||
HEAD_CSRC = esp32_start.c
|
||||
HEAD_ASRC = xtensa_vectors.S xtensa_window_vector.S xtensa_windowspill.S
|
||||
HEAD_ASRC += xtensa_int_handlers.S xtensa_user_handler.S
|
||||
HEAD_CSRC = esp32_start.c
|
||||
|
||||
# Common XTENSA files (arch/xtensa/src/common)
|
||||
|
||||
CMN_ASRCS = xtensa_context.S xtensa_coproc.S xtensa_cpuint.S
|
||||
CMN_ASRCS += xtensa_int_handlers.S xtensa_panic.S xtensa_user_handler.S
|
||||
CMN_ASRCS += xtensa_vectors.S xtensa_windowspill.S
|
||||
CMN_ASRCS = xtensa_context.S xtensa_coproc.S xtensa_cpuint.S xtensa_panic.S
|
||||
CMN_ASRCS += xtensa_sigtramp.S
|
||||
|
||||
CMN_CSRCS = xtensa_assert.c xtensa_blocktask.c xtensa_copystate.c
|
||||
CMN_CSRCS += xtensa_cpenable.c xtensa_createstack.c xtensa_exit.c xtensa_idle.c
|
||||
@ -68,6 +68,11 @@ ifeq ($(CONFIG_SMP),y)
|
||||
CMN_CSRCS += xtensa_cpupause.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_STACK_COLORATION),y)
|
||||
CMN_CSRCS += xtensa_checkstack.c
|
||||
endif
|
||||
|
||||
|
||||
# Use of common/xtensa_etherstub.c is deprecated. The preferred mechanism
|
||||
# is to use CONFIG_NETDEV_LATEINIT=y to suppress the call to
|
||||
# up_netinitialize() in xtensa_initialize.c. Then this stub would not be
|
||||
@ -89,7 +94,7 @@ CHIP_CSRCS += esp32_timerisr.c
|
||||
# Configuration-dependent ESP32 files
|
||||
|
||||
ifeq ($(CONFIG_SMP),y)
|
||||
CHIP_ASRCS = esp32_cpuhead.S esp32_cpuindex.S
|
||||
CHIP_ASRCS = esp32_cpuindex.S
|
||||
CMN_CSRCS += esp32_cpuidlestack.c esp32_cpustart.c esp32_intercpu_interrupt.c
|
||||
endif
|
||||
|
||||
|
@ -1,148 +0,0 @@
|
||||
/****************************************************************************
|
||||
* arch/xtensa/src/esp32/esp32_cpuhead.S
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.file "esp32_cpuhead.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/xtensa/xtensa_corebits.h>
|
||||
#include <arch/esp32/core-isa.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
.section .noinit, "aw"
|
||||
.global g_cpu1_idlestack
|
||||
.type g_cpu1_idlestack, @object
|
||||
.align 16
|
||||
|
||||
g_cpu1_idlestack:
|
||||
.space (CONFIG_SMP_IDLETHREAD_STACKSIZE & ~15)
|
||||
.Lcpu1_stacktop:
|
||||
.size g_cpu1_idlestack, . - g_cpu1_idlestack
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
|
||||
/****************************************************************************
|
||||
* Name: __cpu[n]_start
|
||||
*
|
||||
* Description:
|
||||
* Boot functions for each CPU (other than CPU0). These functions set up
|
||||
* the ARM operating mode, the initial stack, and configure co-processor
|
||||
* registers. At the end of the boot, esp32_cpu_boot() is called.
|
||||
*
|
||||
* These functions are provided by the common ARMv7-A logic.
|
||||
*
|
||||
* Input parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Do not return.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.global __cpu1_start
|
||||
.type __cpu1_start, @function
|
||||
|
||||
.align 4
|
||||
|
||||
.Lcpu1_bottomofstack:
|
||||
.long .Lcpu1_stacktop
|
||||
.size .Lcpu1_bottomofstack, . - .Lcpu1_bottomofstack
|
||||
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
.Lcpu1_bottomofstack:
|
||||
.long .Lcpu1_stacktop
|
||||
.size .Lcpu1_bottomofstack, . - .Lcpu1_bottomofstack
|
||||
|
||||
.Lcpu1_stackcolor:
|
||||
.long STACK_COLOR
|
||||
.size .Lcpu1_stackcolor, . - .Lcpu1_stackcolor
|
||||
#endif
|
||||
|
||||
.align 4
|
||||
|
||||
__cpu1_start:
|
||||
|
||||
/* Set up the stack pointer and the CPU index */
|
||||
|
||||
l32r sp, .Lcpu1_bottomofstack
|
||||
|
||||
/* REVIST: Does it make since to have co-processors enabled on the IDLE thread? */
|
||||
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
/* Write a known value to the IDLE thread stack to support stack
|
||||
* monitoring logic
|
||||
*/
|
||||
|
||||
mov a0, sp
|
||||
l32r a1, .Lcpu1_bottomofstack
|
||||
l32r a2, .Lcpu1_stackcolor
|
||||
|
||||
1:
|
||||
s32i a2, a1, 0
|
||||
addi a2, a2, 4
|
||||
bne a1, a2, 1b
|
||||
#endif
|
||||
|
||||
/* Set up the intiali PS */
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
movi a0, (PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_EXCM)
|
||||
#else
|
||||
movi a0, (PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_EXCM | PS_WOE | PS_CALLINC(1))
|
||||
#endif
|
||||
wsr a0, PS
|
||||
|
||||
/* Finish initialization in C */
|
||||
|
||||
movi a2, 1 /* Argument 1: CPU ID */
|
||||
call0 xtensa_start_handler
|
||||
|
||||
/* xtensa_start_handler() does not return */
|
||||
|
||||
2: j 2b
|
||||
.size __cpu1_start, . - __cpu1_start
|
||||
#endif /* CONFIG_SMP */
|
@ -36,6 +36,16 @@
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Address of the CPU0 IDLE thread */
|
||||
|
||||
uint32_t g_cpu1_idlestack[CPU1_IDLETHREAD_STACKWORDS]
|
||||
__attribute__((aligned(16) section(".noinit")));
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -39,6 +39,7 @@
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "xtensa_abi.h"
|
||||
#include "chip_macros.h"
|
||||
|
||||
/****************************************************************************
|
||||
@ -71,6 +72,8 @@
|
||||
.type up_cpu_index, @function
|
||||
|
||||
up_cpu_index:
|
||||
ENTRY(16)
|
||||
getcoreid a2
|
||||
ret
|
||||
RET(16)
|
||||
|
||||
.size up_cpu_index, . - up_cpu_index
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
@ -52,6 +53,8 @@
|
||||
#include "esp32_cpuint.h"
|
||||
#include "xtensa.h"
|
||||
|
||||
#include "sched/sched.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
@ -147,6 +150,17 @@
|
||||
#define ESP32_MAX_PRIORITY 5
|
||||
#define ESP32_PRIO_INDEX(p) ((p) - ESP32_MIN_PRIORITY)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Maps a CPU interrupt to the IRQ of the attached peripheral interrupt */
|
||||
|
||||
uint8_t g_cpu0_intmap[ESP32_NCPUINTS];
|
||||
#ifdef CONFIG_SMP
|
||||
uint8_t g_cpu1_intmap[ESP32_NCPUINTS];
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@ -156,18 +170,19 @@
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
static uint32_t g_intenable[CONFIG_SMP_NCPUS];
|
||||
|
||||
#else
|
||||
|
||||
static uint32_t g_intenable[1];
|
||||
|
||||
#endif
|
||||
|
||||
/* Bitsets for free, unallocated CPU interrupts */
|
||||
/* Bitsets for free, unallocated CPU interrupts available to peripheral
|
||||
* devices.
|
||||
*/
|
||||
|
||||
static uint32_t g_free_cpuints = 0xffffffff;
|
||||
static uint32_t g_cpu0_freeints = EPS32_CPUINT_PERIPHSET;
|
||||
#ifdef CONFIG_SMP
|
||||
static uint32_t g_cpu1_freeints = EPS32_CPUINT_PERIPHSET;
|
||||
#endif
|
||||
|
||||
/* Bitsets for each interrupt priority 1-5 */
|
||||
|
||||
@ -184,11 +199,27 @@ static const uint32_t g_priority[5] =
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_disable_all
|
||||
****************************************************************************/
|
||||
|
||||
static inline void xtensa_disable_all(void)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a2, 0\n"
|
||||
"xsr a2, INTENABLE\n"
|
||||
: : : "a2"
|
||||
);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_alloc_cpuint
|
||||
*
|
||||
* Description:
|
||||
* Allocate a CPU interrupt
|
||||
* Allocate a CPU interrupt for a peripheral device. This function will
|
||||
* not allocate any of the pre-allocated CPU interrupts for internal
|
||||
* devices.
|
||||
*
|
||||
* Input Parameters:
|
||||
* intmask - mask of candidate CPU interrupts. The CPU interrupt will be
|
||||
@ -205,6 +236,7 @@ static const uint32_t g_priority[5] =
|
||||
int esp32_alloc_cpuint(uint32_t intmask)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t *freeints;
|
||||
uint32_t bitmask;
|
||||
uint32_t intset;
|
||||
int cpuint;
|
||||
@ -216,7 +248,18 @@ int esp32_alloc_cpuint(uint32_t intmask)
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
intset = g_free_cpuints & intmask;
|
||||
#ifdef CONFIG_SMP
|
||||
if (this_cpu() != 0)
|
||||
{
|
||||
freeints = &g_cpu1_freeints;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
freeints = &g_cpu0_freeints;
|
||||
}
|
||||
|
||||
intset = *freeints & intmask;
|
||||
if (intset != 0)
|
||||
{
|
||||
/* Skip over initial unavailable CPU interrupts quickly in groups
|
||||
@ -224,7 +267,7 @@ int esp32_alloc_cpuint(uint32_t intmask)
|
||||
*/
|
||||
|
||||
for (cpuint = 0, bitmask = 0xff;
|
||||
cpuint <= ESP32_CPUINT_MAX;
|
||||
cpuint <= ESP32_CPUINT_MAX && (intset & bitmask) == 0;
|
||||
cpuint += 8, bitmask <<= 8);
|
||||
|
||||
/* Search for an unallocated CPU interrupt number in the remaining
|
||||
@ -242,7 +285,7 @@ int esp32_alloc_cpuint(uint32_t intmask)
|
||||
{
|
||||
/* Got it! */
|
||||
|
||||
g_free_cpuints &= ~bitmask;
|
||||
*freeints &= ~bitmask;
|
||||
ret = cpuint;
|
||||
break;
|
||||
}
|
||||
@ -257,6 +300,94 @@ int esp32_alloc_cpuint(uint32_t intmask)
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_cpuint_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize CPU interrupts
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; A negated errno value is returned on
|
||||
* any failre.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32_cpuint_initialize(void)
|
||||
{
|
||||
uintptr_t regaddr;
|
||||
uint8_t *intmap;
|
||||
#ifdef CONFIG_SMP
|
||||
int cpu;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Which CPU are we initializing */
|
||||
|
||||
cpu = up_cpu_index();
|
||||
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS);
|
||||
#endif
|
||||
|
||||
/* Disable all CPU interrupts on this CPU */
|
||||
|
||||
xtensa_disable_all();
|
||||
|
||||
/* Detach all peripheral sources PRO CPU interrupts */
|
||||
|
||||
for (i = 0; i < ESP32_NPERIPHERALS; i++)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
if (cpu != 0)
|
||||
{
|
||||
regaddr = DPORT_APP_MAP_REGADDR(i);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
regaddr = DPORT_PRO_MAP_REGADDR(i);
|
||||
}
|
||||
|
||||
putreg32(NO_CPUINT, regaddr);
|
||||
}
|
||||
|
||||
/* Initialize CPU interrupt-to-IRQ mapping table */
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (cpu != 0)
|
||||
{
|
||||
intmap = g_cpu1_intmap;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
intmap = g_cpu0_intmap;
|
||||
}
|
||||
|
||||
/* Indiate that no peripheral interrupts are assigned to CPU interrupts */
|
||||
|
||||
memset(intmap, CPUINT_UNASSIGNED, ESP32_NCPUINTS);
|
||||
|
||||
/* Special case the 6 internal interrupts.
|
||||
*
|
||||
* CPU interrupt bit IRQ number
|
||||
* --------------------------- ---------------------
|
||||
* ESP32_CPUINT_TIMER0 6 XTENSA_IRQ_TIMER0 0
|
||||
* SP32_CPUINT_SOFTWARE0 7 Not yet defined
|
||||
* ESP32_CPUINT_PROFILING 11 Not yet defined
|
||||
* ESP32_CPUINT_TIMER1 15 XTENSA_IRQ_TIMER1 1
|
||||
* ESP32_CPUINT_TIMER2 16 XTENSA_IRQ_TIMER2 2
|
||||
* ESP32_CPUINT_SOFTWARE1 29 Not yet defined
|
||||
*/
|
||||
|
||||
intmap[ESP32_CPUINT_TIMER0] = XTENSA_IRQ_TIMER0;
|
||||
intmap[ESP32_CPUINT_TIMER1] = XTENSA_IRQ_TIMER1;
|
||||
intmap[ESP32_CPUINT_TIMER2] = XTENSA_IRQ_TIMER2;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_disable_irq
|
||||
*
|
||||
@ -327,7 +458,7 @@ int esp32_alloc_levelint(int priority)
|
||||
uint32_t intmask;
|
||||
|
||||
DEBUGASSERT(priority >= ESP32_MIN_PRIORITY &&
|
||||
priority <= ESP32_MAX_PRIORITY)
|
||||
priority <= ESP32_MAX_PRIORITY);
|
||||
|
||||
/* Check if there are any level CPU interrupts available at the requested
|
||||
* interrupt priority.
|
||||
@ -359,7 +490,7 @@ int esp32_alloc_edgeint(int priority)
|
||||
uint32_t intmask;
|
||||
|
||||
DEBUGASSERT(priority >= ESP32_MIN_PRIORITY &&
|
||||
priority <= ESP32_MAX_PRIORITY)
|
||||
priority <= ESP32_MAX_PRIORITY);
|
||||
|
||||
/* Check if there are any edge CPU interrupts available at the requested
|
||||
* interrupt priority.
|
||||
@ -386,6 +517,7 @@ int esp32_alloc_edgeint(int priority)
|
||||
void esp32_free_cpuint(int cpuint)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t *freeints;
|
||||
uint32_t bitmask;
|
||||
|
||||
DEBUGASSERT(cpuint >= 0 && cpuint < ESP32_CPUINT_NEDGEPERIPHS);
|
||||
@ -394,8 +526,20 @@ void esp32_free_cpuint(int cpuint)
|
||||
|
||||
bitmask = (1ul << cpuint);
|
||||
flags = enter_critical_section();
|
||||
DEBUGASSERT((g_free_cpuints & bitmask) == 0);
|
||||
g_free_cpuints |= bitmask;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (this_cpu() != 0)
|
||||
{
|
||||
freeints = &g_cpu1_freeints;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
freeints = &g_cpu0_freeints;
|
||||
}
|
||||
|
||||
DEBUGASSERT((*freeints & bitmask) == 0);
|
||||
*freeints |= bitmask;
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
@ -407,8 +551,10 @@ void esp32_free_cpuint(int cpuint)
|
||||
*
|
||||
* Input Parameters:
|
||||
* cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU
|
||||
* periphid - The peripheral number from ira.h to be assigned.
|
||||
* periphid - The peripheral number from ira.h to be assigned to
|
||||
* a CPU interrupt.
|
||||
* cpuint - The CPU interrupt to receive the peripheral interrupt
|
||||
* assignment.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
@ -418,6 +564,7 @@ void esp32_free_cpuint(int cpuint)
|
||||
void esp32_attach_peripheral(int cpu, int periphid, int cpuint)
|
||||
{
|
||||
uintptr_t regaddr;
|
||||
uint8_t *intmap;
|
||||
|
||||
DEBUGASSERT(periphid >= 0 && periphid < ESP32_NPERIPHERALS);
|
||||
DEBUGASSERT(cpuint >= 0 && cpuint <= ESP32_CPUINT_MAX);
|
||||
@ -427,13 +574,18 @@ void esp32_attach_peripheral(int cpu, int periphid, int cpuint)
|
||||
if (cpu != 0)
|
||||
{
|
||||
regaddr = DPORT_APP_MAP_REGADDR(periphid);
|
||||
intmap = g_cpu1_intmap;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
regaddr = DPORT_PRO_MAP_REGADDR(periphid);
|
||||
intmap = g_cpu0_intmap;
|
||||
}
|
||||
|
||||
DEBUGASSERT(intmap[cpuint] == CPUINT_UNASSIGNED);
|
||||
intmap[cpuint] = periphid + XTENSA_IRQ_FIRSTPERIPH;
|
||||
|
||||
putreg32(cpuint, regaddr);
|
||||
}
|
||||
|
||||
@ -444,17 +596,21 @@ void esp32_attach_peripheral(int cpu, int periphid, int cpuint)
|
||||
* Detach a peripheral interupt from a CPU interrupt.
|
||||
*
|
||||
* Input Parameters:
|
||||
* cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU
|
||||
* periphid - The peripheral number from ira.h to be assigned.
|
||||
* cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU
|
||||
* periphid - The peripheral number from irq.h to be detached from the
|
||||
* CPU interrupt.
|
||||
* cpuint - The CPU interrupt from which the peripheral interrupt will
|
||||
* be detached.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32_detach_peripheral(int cpu, int periphid)
|
||||
void esp32_detach_peripheral(int cpu, int periphid, int cpuint)
|
||||
{
|
||||
uintptr_t regaddr;
|
||||
uint8_t *intmap;
|
||||
|
||||
DEBUGASSERT(periphid >= 0 && periphid < ESP32_NPERIPHERALS);
|
||||
#ifdef CONFIG_SMP
|
||||
@ -463,12 +619,17 @@ void esp32_detach_peripheral(int cpu, int periphid)
|
||||
if (cpu != 0)
|
||||
{
|
||||
regaddr = DPORT_APP_MAP_REGADDR(periphid);
|
||||
intmap = g_cpu1_intmap;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
regaddr = DPORT_PRO_MAP_REGADDR(periphid);
|
||||
intmap = g_cpu0_intmap;
|
||||
}
|
||||
|
||||
DEBUGASSERT(intmap[cpuint] != CPUINT_UNASSIGNED);
|
||||
intmap[cpuint] = CPUINT_UNASSIGNED;
|
||||
|
||||
putreg32(NO_CPUINT, regaddr);
|
||||
}
|
||||
|
@ -42,10 +42,46 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define CPUINT_UNASSIGNED 0xff /* No peripheral assigned to this CPU interrupt */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Maps a CPU interrupt to the IRQ of the attached peripheral interrupt */
|
||||
|
||||
extern uint8_t g_cpu0_intmap[ESP32_NCPUINTS];
|
||||
#ifdef CONFIG_SMP
|
||||
extern uint8_t g_cpu1_intmap[ESP32_NCPUINTS];
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_cpuint_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize CPU interrupts
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; A negated errno value is returned on
|
||||
* any failre.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32_cpuint_initialize(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_alloc_levelint
|
||||
*
|
||||
@ -108,8 +144,10 @@ void esp32_free_cpuint(int cpuint);
|
||||
*
|
||||
* Input Parameters:
|
||||
* cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU
|
||||
* periphid - The peripheral number from ira.h to be attached.
|
||||
* periphid - The peripheral number from ira.h to be assigned to
|
||||
* a CPU interrupt.
|
||||
* cpuint - The CPU interrupt to receive the peripheral interrupt
|
||||
* assignment.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
@ -125,14 +163,17 @@ void esp32_attach_peripheral(int cpu, int periphid, int cpuint);
|
||||
* Detach a peripheral interupt from a CPU interrupt.
|
||||
*
|
||||
* Input Parameters:
|
||||
* cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU
|
||||
* periphid - The peripheral number from ira.h to be detached.
|
||||
* cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU
|
||||
* periphid - The peripheral number from irq.h to be detached from the
|
||||
* CPU interrupt.
|
||||
* cpuint - The CPU interrupt from which the peripheral interrupt will
|
||||
* be detached.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32_detach_peripheral(int cpu, int periphid);
|
||||
void esp32_detach_peripheral(int cpu, int periphid, int cpuint);
|
||||
|
||||
#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_CPUINT_H */
|
||||
|
@ -41,32 +41,38 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/sched_note.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "xtensa.h"
|
||||
#include "chip/esp32_dport.h"
|
||||
#include "chip/esp32_rtccntl.h"
|
||||
#include "esp32_region.h"
|
||||
#include "esp32_cpuint.h"
|
||||
#include "esp32_smp.h"
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#warning REVISIT Need ets_set_appcpu_boot_addr() prototype
|
||||
void ets_set_appcpu_boot_addr(uint32_t);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static volatile bool g_appcpu_started;
|
||||
static sem_t g_appcpu_interlock;
|
||||
static volatile spinlock_t g_appcpu_interlock SP_SECTION;
|
||||
|
||||
/****************************************************************************
|
||||
* ROM function prototypes
|
||||
****************************************************************************/
|
||||
|
||||
void Cache_Flush(int cpu);
|
||||
void Cache_Read_Enable(int cpu);
|
||||
void ets_set_appcpu_boot_addr(uint32_t start);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
@ -88,20 +94,6 @@ static inline void xtensa_registerdump(FAR struct tcb_s *tcb)
|
||||
# define xtensa_registerdump(tcb)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_disable_all
|
||||
****************************************************************************/
|
||||
|
||||
static inline void xtensa_disable_all(void)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a2, 0\n"
|
||||
"xsr a2, INTENABLE\n"
|
||||
: : : "a2"
|
||||
);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_attach_fromcpu0_interrupt
|
||||
****************************************************************************/
|
||||
@ -136,25 +128,52 @@ static inline void xtensa_attach_fromcpu0_interrupt(void)
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_start_handler
|
||||
* Name: xtensa_appcpu_start
|
||||
*
|
||||
* Description:
|
||||
* This is the handler for SGI1. This handler simply returns from the
|
||||
* interrupt, restoring the state of the new task at the head of the ready
|
||||
* to run list.
|
||||
* This is the entry point used with the APP CPU was started via
|
||||
* up_cpu_start(). The actually start-up logic in in ROM and we boot up
|
||||
* in C code.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Standard interrupt handling
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
* None, does not return
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int xtensa_start_handler(int irq, FAR void *context)
|
||||
void xtensa_appcpu_start(void)
|
||||
{
|
||||
FAR struct tcb_s *tcb = this_task();
|
||||
int i;
|
||||
register uint32_t sp;
|
||||
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
{
|
||||
register uint32_t *ptr;
|
||||
register int i;
|
||||
|
||||
/* If stack debug is enabled, then fill the stack with a recognizable value
|
||||
* that we can use later to test for high water marks.
|
||||
*/
|
||||
|
||||
for (i = 0, ptr = (uint32_t *)tcb->stack_alloc_ptr;
|
||||
i < tcb->adj_stack_size;
|
||||
i += sizeof(uint32_t))
|
||||
{
|
||||
*ptr++ = STACK_COLOR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Move to the stack assigned to us by up_smp_start immediately. Although
|
||||
* we were give a stack pointer at start-up, we don't know where that stack
|
||||
* pointer is positioned respect to our memory map. The only safe option
|
||||
* is to switch to a well-known IDLE thread stack.
|
||||
*/
|
||||
|
||||
sp = (uint32_t)tcb->adj_stack_ptr;
|
||||
__asm__ __volatile__("mov sp, %0\n" : : "r"(sp));
|
||||
|
||||
sinfo("CPU%d Started\n", up_cpu_index());
|
||||
|
||||
@ -167,7 +186,7 @@ int xtensa_start_handler(int irq, FAR void *context)
|
||||
/* Handle interlock*/
|
||||
|
||||
g_appcpu_started = true;
|
||||
sem_post(&g_appcpu_interlock);
|
||||
spin_unlock(&g_appcpu_interlock);
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
@ -181,9 +200,9 @@ int xtensa_start_handler(int irq, FAR void *context)
|
||||
|
||||
esp32_region_protection();
|
||||
|
||||
/* Disable all PRO CPU interrupts */
|
||||
/* Initialize CPU interrupts */
|
||||
|
||||
xtensa_disable_all();
|
||||
(void)esp32_cpuint_initialize();
|
||||
|
||||
/* Attach and emable internal interrupts */
|
||||
|
||||
@ -193,13 +212,6 @@ int xtensa_start_handler(int irq, FAR void *context)
|
||||
xtensa_attach_fromcpu0_interrupt();
|
||||
#endif
|
||||
|
||||
/* Detach all peripheral sources APP CPU interrupts */
|
||||
|
||||
for (i = 0; i < ESP32_NPERIPHERALS; i++)
|
||||
{
|
||||
esp32_detach_peripheral(1, i);;
|
||||
}
|
||||
|
||||
#if 0 /* Does it make since to have co-processors enabled on the IDLE thread? */
|
||||
#if XTENSA_CP_ALLSET != 0
|
||||
/* Set initial co-processor state */
|
||||
@ -224,7 +236,6 @@ int xtensa_start_handler(int irq, FAR void *context)
|
||||
*/
|
||||
|
||||
xtensa_context_restore(tcb->xcp.regs);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -261,7 +272,6 @@ int up_cpu_start(int cpu)
|
||||
if (!g_appcpu_started)
|
||||
{
|
||||
uint32_t regval;
|
||||
int ret;
|
||||
|
||||
/* Start CPU1 */
|
||||
|
||||
@ -277,8 +287,24 @@ int up_cpu_start(int cpu)
|
||||
* have priority inheritance enabled.
|
||||
*/
|
||||
|
||||
sem_init(&g_appcpu_interlock, 0, 0);
|
||||
sem_setprotocol(&g_appcpu_interlock, SEM_PRIO_NONE);
|
||||
spin_initialize(&g_appcpu_interlock, SP_LOCKED);
|
||||
|
||||
/* Flush and enable I-cache for APP CPU */
|
||||
|
||||
Cache_Flush(cpu);
|
||||
Cache_Read_Enable(cpu);
|
||||
|
||||
/* Unstall the APP CPU */
|
||||
|
||||
regval = getreg32(RTC_CNTL_SW_CPU_STALL_REG);
|
||||
regval &= ~RTC_CNTL_SW_STALL_APPCPU_C1_M;
|
||||
putreg32(regval, RTC_CNTL_SW_CPU_STALL_REG);
|
||||
|
||||
regval = getreg32(RTC_CNTL_OPTIONS0_REG);
|
||||
regval &= ~RTC_CNTL_SW_STALL_APPCPU_C0_M;
|
||||
putreg32(regval, RTC_CNTL_OPTIONS0_REG);
|
||||
|
||||
/* Enable clock gating for the APP CPU */
|
||||
|
||||
regval = getreg32(DPORT_APPCPU_CTRL_B_REG);
|
||||
regval |= DPORT_APPCPU_CLKGATE_EN;
|
||||
@ -288,6 +314,8 @@ int up_cpu_start(int cpu)
|
||||
regval &= ~DPORT_APPCPU_RUNSTALL;
|
||||
putreg32(regval, DPORT_APPCPU_CTRL_C_REG);
|
||||
|
||||
/* Reset the APP CPU */
|
||||
|
||||
regval = getreg32(DPORT_APPCPU_CTRL_A_REG);
|
||||
regval |= DPORT_APPCPU_RESETTING;
|
||||
putreg32(regval, DPORT_APPCPU_CTRL_A_REG);
|
||||
@ -298,20 +326,12 @@ int up_cpu_start(int cpu)
|
||||
|
||||
/* Set the CPU1 start address */
|
||||
|
||||
ets_set_appcpu_boot_addr((uint32_t)__cpu1_start);
|
||||
ets_set_appcpu_boot_addr((uint32_t)xtensa_appcpu_start);
|
||||
|
||||
/* And way for the initial task to run on CPU1 */
|
||||
/* And wait for the initial task to run on CPU1 */
|
||||
|
||||
while (!g_appcpu_started)
|
||||
{
|
||||
ret = sem_wait(&g_appcpu_interlock);
|
||||
if (ret < 0)
|
||||
{
|
||||
DEBUGASSERT(errno == EINTR);
|
||||
}
|
||||
}
|
||||
|
||||
sem_destroy(&g_appcpu_interlock);
|
||||
spin_lock(&g_appcpu_interlock);
|
||||
DEBUGASSERT(g_appcpu_started);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -39,29 +39,32 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <nuttx/sched.h>
|
||||
#include <arch/chip/irq.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip/esp32_dport.h"
|
||||
#include "xtensa.h"
|
||||
#include "esp32_cpuint.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static const uint8_t g_baseirq[3] =
|
||||
{
|
||||
ESP32_IRQ_SREG0,
|
||||
ESP32_IRQ_SREG1,
|
||||
ESP32_IRQ_SREG2
|
||||
};
|
||||
/****************************************************************************
|
||||
* Name: xtensa_intclear
|
||||
****************************************************************************/
|
||||
|
||||
static const uint8_t g_nirqs[3] =
|
||||
static inline void xtensa_intclear(uint32_t mask)
|
||||
{
|
||||
ESP32_NIRQS_SREG0,
|
||||
ESP32_NIRQS_SREG1,
|
||||
ESP32_NIRQS_SREG2
|
||||
};
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a2, 0\n"
|
||||
"wsr %0, INTCLEAR\n"
|
||||
: "=r"(mask) : :
|
||||
);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@ -75,80 +78,74 @@ static const uint8_t g_nirqs[3] =
|
||||
* handling to the registered interrupt handler via xtensa_irq_dispatch().
|
||||
*
|
||||
* Input Parameters:
|
||||
* regs - Saves processor state on the stack
|
||||
* cpuints - Set of pending interrupts valid for this level
|
||||
* regs - Saves processor state on the stack
|
||||
*
|
||||
* Returned Value:
|
||||
* Normally the same vale as regs is returned. But, in the event of an
|
||||
* Normally the same value as regs is returned. But, in the event of an
|
||||
* interrupt level context switch, the returned value will, instead point
|
||||
* to the saved processor state in the TCB of the newly started task.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t *xtensa_int_decode(uint32_t *regs)
|
||||
uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs)
|
||||
{
|
||||
uintptr_t regaddr;
|
||||
uint32_t regval;
|
||||
uint8_t *intmap;
|
||||
uint32_t mask;
|
||||
int regndx;
|
||||
int bit;
|
||||
int baseirq;
|
||||
int nirqs;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
int cpu;
|
||||
#endif
|
||||
|
||||
/* Select PRO or APP interrupt status registers */
|
||||
#ifdef CONFIG_SMP
|
||||
/* Select PRO or APP CPU interrupt mapping table */
|
||||
|
||||
cpu = up_cpu_index();
|
||||
if (cpu == 0)
|
||||
if (cpu != 0)
|
||||
{
|
||||
regaddr = DPORT_PRO_INTR_STATUS_0_REG;
|
||||
intmap = g_cpu1_intmap;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
regaddr = DPORT_APP_INTR_STATUS_0_REG;
|
||||
intmap = g_cpu0_intmap;
|
||||
}
|
||||
|
||||
/* Process each pending interrupt in each of the three interrupt status
|
||||
* registers.
|
||||
*/
|
||||
/* Skip over zero bits, eight at a time */
|
||||
|
||||
for (regndx = 0; regndx < 3; regndx++)
|
||||
for (bit = 0, mask = 0xff;
|
||||
bit < ESP32_NCPUINTS && (cpuints & mask) == 0;
|
||||
bit += 8, mask <<= 8);
|
||||
|
||||
/* Process each pending CPU interrupt */
|
||||
|
||||
for (; bit < ESP32_NCPUINTS && cpuints != 0; bit++)
|
||||
{
|
||||
/* Fetch the next register status register */
|
||||
|
||||
regval = getreg32(regaddr);
|
||||
regaddr += sizeof(uint32_t);
|
||||
|
||||
/* Set up the search */
|
||||
|
||||
baseirq = g_baseirq[regndx];
|
||||
nirqs = g_nirqs[regndx];
|
||||
|
||||
/* Decode and dispatch each pending bit in the interrupt status
|
||||
* register.
|
||||
*/
|
||||
|
||||
for (bit = 0; regval != 0 && bit < nirqs; bit++)
|
||||
mask = (1 << bit);
|
||||
if ((cpuints & mask) != 0)
|
||||
{
|
||||
/* Check if this interrupt is pending */
|
||||
/* Extract the IRQ number from the mapping table */
|
||||
|
||||
mask = (1 << bit);
|
||||
if ((regval & mask) != 0)
|
||||
{
|
||||
/* Yes.. Dispatch the interrupt. Note that regs may be
|
||||
* altered in the case of an interrupt level context switch.
|
||||
*/
|
||||
uint8_t irq = intmap[bit];
|
||||
DEBUGASSERT(irq != CPUINT_UNASSIGNED);
|
||||
|
||||
regs = xtensa_irq_dispatch(baseirq + bit, regs);
|
||||
/* Clear software or edge-triggered interrupt */
|
||||
|
||||
/* Clear this bit in the sampled status register so that
|
||||
* perhaps we can exit this loop sooner.
|
||||
*/
|
||||
xtensa_intclear(mask);
|
||||
|
||||
regval &= ~mask;
|
||||
}
|
||||
/* Dispatch the CPU interrupt.
|
||||
*
|
||||
* NOTE that regs may be altered in the case of an interrupt
|
||||
* level context switch.
|
||||
*/
|
||||
|
||||
regs = xtensa_irq_dispatch((int)irq, regs);
|
||||
|
||||
/* Clear the bit in the pending interrupt so that perhaps
|
||||
* we can exit the look early.
|
||||
*/
|
||||
|
||||
cpuints &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,6 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <sched.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
@ -86,7 +85,7 @@ static int esp32_fromcpu_interrupt(int fromcpu)
|
||||
int intcode;
|
||||
int tocpu;
|
||||
|
||||
DEBUGASSERT(regs != NULL);
|
||||
DEBUGASSERT((unsigned)fromcpu < CONFIG_SMP_NCPUS);
|
||||
|
||||
/* Clear the interrupt from the other CPU */
|
||||
|
||||
@ -155,14 +154,8 @@ int xtensa_intercpu_interrupt(int tocpu, int intcode)
|
||||
{
|
||||
int fromcpu;
|
||||
|
||||
DEBUGASSERT((unsigned)cpu < CONFIG_SMP_NCPUS &&
|
||||
(unsigned)incode <= UINT8_MAX);
|
||||
|
||||
/* Disable context switching so that some other thread does not attempt to
|
||||
* take the spinlock on the same CPU.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
DEBUGASSERT((unsigned)tocpu < CONFIG_SMP_NCPUS &&
|
||||
(unsigned)intcode <= UINT8_MAX);
|
||||
|
||||
/* Make sure that each inter-cpu event is atomic. The spinlock should
|
||||
* only be locked if we just completed sending an interrupt to this
|
||||
@ -195,7 +188,6 @@ int xtensa_intercpu_interrupt(int tocpu, int intcode)
|
||||
putreg32(DPORT_CPU_INTR_FROM_CPU_1, DPORT_CPU_INTR_FROM_CPU_1_REG);
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -98,20 +98,6 @@ static void esp32_irq_dump(const char *msg, int irq)
|
||||
# define esp32_irq_dump(msg, irq)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_disable_all
|
||||
****************************************************************************/
|
||||
|
||||
static inline void xtensa_disable_all(void)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a2, 0\n"
|
||||
"xsr a2, INTENABLE\n"
|
||||
: : : "a2"
|
||||
);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_attach_fromcpu1_interrupt
|
||||
****************************************************************************/
|
||||
@ -151,20 +137,11 @@ static inline void xtensa_attach_fromcpu1_interrupt(void)
|
||||
|
||||
void xtensa_irq_initialize(void)
|
||||
{
|
||||
int i;
|
||||
/* Initialize CPU interrupts */
|
||||
|
||||
/* Disable all PRO CPU interrupts */
|
||||
(void)esp32_cpuint_initialize();
|
||||
|
||||
xtensa_disable_all();
|
||||
|
||||
/* Detach all peripheral sources PRO CPU interrupts */
|
||||
|
||||
for (i = 0; i < ESP32_NPERIPHERALS; i++)
|
||||
{
|
||||
esp32_detach_peripheral(0, i);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
#if defined(CONFIG_STACK_COLORATION) && defined(HAVE_INTERRUPTSTACK)
|
||||
/* Colorize the interrupt stack for debug purposes */
|
||||
|
||||
#warning Missing logic
|
||||
@ -187,7 +164,7 @@ void xtensa_irq_initialize(void)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
/* And finally, enable interrupts */
|
||||
/* And finally, enable interrupts. Also clears PS.EXCM */
|
||||
|
||||
up_irq_enable();
|
||||
#endif
|
||||
|
@ -146,7 +146,7 @@
|
||||
|
||||
struct esp32_config_s
|
||||
{
|
||||
const uint32_t uartbase; /* Base address of UART registers */
|
||||
const uint32_t uartbase; /* Base address of UART registers */
|
||||
xcpt_t handler; /* Interrupt handler */
|
||||
uint8_t periph; /* UART peripheral ID */
|
||||
uint8_t irq; /* IRQ number assigned to the peripheral */
|
||||
@ -455,8 +455,8 @@ static void esp32_disableallints(struct esp32_dev_s *priv, uint32_t *intena)
|
||||
|
||||
static int esp32_setup(struct uart_dev_s *dev)
|
||||
{
|
||||
struct esp32_dev_s *priv = (struct esp32_dev_s *)dev->priv;
|
||||
#ifndef CONFIG_SUPPRESS_UART_CONFIG
|
||||
struct esp32_dev_s *priv = (struct esp32_dev_s *)dev->priv;
|
||||
uint32_t clkdiv;
|
||||
uint32_t regval;
|
||||
uint32_t conf0;
|
||||
@ -586,6 +586,19 @@ static int esp32_setup(struct uart_dev_s *dev)
|
||||
static void esp32_shutdown(struct uart_dev_s *dev)
|
||||
{
|
||||
struct esp32_dev_s *priv = (struct esp32_dev_s *)dev->priv;
|
||||
uint32_t status;
|
||||
|
||||
/* Wait for outgoing FIFO to clear. The ROM bootloader does not flush
|
||||
* the FIFO before handing over to user code, so some of this output is
|
||||
* not currently seen when the UART is reconfigured in early stages of
|
||||
* startup.
|
||||
*/
|
||||
|
||||
do
|
||||
{
|
||||
status = esp32_serialin(priv, UART_STATUS_OFFSET);
|
||||
}
|
||||
while ((status & UART_TXFIFO_CNT_M) != 0);
|
||||
|
||||
/* Disable all UART interrupts */
|
||||
|
||||
@ -642,7 +655,9 @@ static int esp32_attach(struct uart_dev_s *dev)
|
||||
priv->cpuint = esp32_alloc_levelint(1);
|
||||
if (priv->cpuint < 0)
|
||||
{
|
||||
ret = priv->cpuint;
|
||||
/* Failed to allocate a CPU interrupt of this type */
|
||||
|
||||
return priv->cpuint;
|
||||
}
|
||||
|
||||
/* Set up to receive peripheral interrupts on the current CPU */
|
||||
@ -701,7 +716,7 @@ static void esp32_detach(struct uart_dev_s *dev)
|
||||
cpu = 0;
|
||||
#endif
|
||||
|
||||
esp32_detach_peripheral(cpu, priv->config->periph);
|
||||
esp32_detach_peripheral(cpu, priv->config->periph, priv->cpuint);
|
||||
|
||||
/* And release the CPU interrupt */
|
||||
|
||||
@ -725,6 +740,8 @@ static int esp32_interrupt(struct uart_dev_s *dev)
|
||||
struct esp32_dev_s *priv;
|
||||
uint32_t regval;
|
||||
uint32_t status;
|
||||
uint32_t enabled;
|
||||
unsigned int nfifo;
|
||||
int passes;
|
||||
bool handled;
|
||||
|
||||
@ -741,28 +758,48 @@ static int esp32_interrupt(struct uart_dev_s *dev)
|
||||
handled = false;
|
||||
priv->status = esp32_serialin(priv, UART_INT_RAW_OFFSET);
|
||||
status = esp32_serialin(priv, UART_STATUS_OFFSET);
|
||||
enabled = esp32_serialin(priv, UART_INT_ENA_OFFSET);
|
||||
|
||||
/* Clear pending interrupts */
|
||||
|
||||
regval = (UART_RXFIFO_FULL_INT_CLR_S | UART_FRM_ERR_INT_CLR_S |
|
||||
UART_RXFIFO_TOUT_INT_CLR_S | UART_TX_DONE_INT_CLR_S |
|
||||
UART_TXFIFO_EMPTY_INT_CLR_S);
|
||||
regval = (UART_RXFIFO_FULL_INT_CLR | UART_FRM_ERR_INT_CLR |
|
||||
UART_RXFIFO_TOUT_INT_CLR | UART_TX_DONE_INT_CLR |
|
||||
UART_TXFIFO_EMPTY_INT_CLR);
|
||||
esp32_serialout(priv, UART_INT_CLR_OFFSET, regval);
|
||||
|
||||
if ((status & UART_RXFIFO_CNT_M) > 0)
|
||||
/* Are Rx interrupts enabled? The upper layer may hold off Rx input
|
||||
* by disabling the Rx interrupts if there is no place to saved the
|
||||
* data, possibly resulting in an overrun error.
|
||||
*/
|
||||
|
||||
if ((enabled & (UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA)) != 0)
|
||||
{
|
||||
/* Is there any data waiting in the Rx FIFO? */
|
||||
|
||||
nfifo = (status & UART_RXFIFO_CNT_M) >> UART_RXFIFO_CNT_S;
|
||||
if (nfifo > 0)
|
||||
{
|
||||
/* Received data in the RXFIFO! ... Process incoming bytes */
|
||||
|
||||
uart_recvchars(dev);
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Are Tx interrupts enabled? The upper layer will disable Tx interrupts
|
||||
* when it has nothing to send.
|
||||
*/
|
||||
|
||||
if ((enabled & (UART_TX_DONE_INT_ENA | UART_TXFIFO_EMPTY_INT_ENA)) != 0)
|
||||
{
|
||||
/* Received data in the RXFIFO ... process incoming bytes */
|
||||
nfifo = (status & UART_TXFIFO_CNT_M) >> UART_TXFIFO_CNT_S;
|
||||
if (nfifo < 0x7f)
|
||||
{
|
||||
/* The TXFIFO is not full ... process outgoing bytes */
|
||||
|
||||
uart_recvchars(dev);
|
||||
handled = true;
|
||||
}
|
||||
|
||||
if ((status & UART_TXFIFO_CNT_M) < 0x7f)
|
||||
{
|
||||
/* The TXFIFO is not full ... process outgoing bytes */
|
||||
|
||||
uart_xmitchars(dev);
|
||||
handled = true;
|
||||
uart_xmitchars(dev);
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1032,8 +1069,11 @@ static int esp32_receive(struct uart_dev_s *dev, unsigned int *status)
|
||||
static void esp32_rxint(struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
struct esp32_dev_s *priv = (struct esp32_dev_s *)dev->priv;
|
||||
irqstate_t flags;
|
||||
int regval;
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
if (enable)
|
||||
{
|
||||
/* Receive an interrupt when their is anything in the Rx data register (or an Rx
|
||||
@ -1042,8 +1082,8 @@ static void esp32_rxint(struct uart_dev_s *dev, bool enable)
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
|
||||
regval = esp32_serialin(priv, UART_INT_ENA_OFFSET);
|
||||
regval |= (UART_RXFIFO_FULL_INT_CLR_S | UART_FRM_ERR_INT_CLR_S |
|
||||
UART_RXFIFO_TOUT_INT_CLR_S);
|
||||
regval |= (UART_RXFIFO_FULL_INT_ENA | UART_FRM_ERR_INT_ENA |
|
||||
UART_RXFIFO_TOUT_INT_ENA);
|
||||
esp32_serialout(priv, UART_INT_ENA_OFFSET, regval);
|
||||
#endif
|
||||
}
|
||||
@ -1051,10 +1091,13 @@ static void esp32_rxint(struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
/* Disable the RX interrupts */
|
||||
|
||||
esp32_serialout(priv, UART_INT_CLR_OFFSET,
|
||||
(UART_RXFIFO_FULL_INT_CLR_S | UART_FRM_ERR_INT_CLR_S |
|
||||
UART_RXFIFO_TOUT_INT_CLR_S));
|
||||
regval = esp32_serialin(priv, UART_INT_ENA_OFFSET);
|
||||
regval &= ~(UART_RXFIFO_FULL_INT_ENA | UART_FRM_ERR_INT_ENA |
|
||||
UART_RXFIFO_TOUT_INT_ENA);
|
||||
esp32_serialout(priv, UART_INT_ENA_OFFSET, regval);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1099,20 +1142,19 @@ static void esp32_txint(struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
struct esp32_dev_s *priv = (struct esp32_dev_s *)dev->priv;
|
||||
irqstate_t flags;
|
||||
int regval;
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
if (enable)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Set to receive an interrupt when the TX holding register register
|
||||
* is empty
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
|
||||
regval = esp32_serialin(priv, UART_INT_ENA_OFFSET);
|
||||
regval |= (UART_TX_DONE_INT_ENA_S | UART_TXFIFO_EMPTY_INT_ENA_S);
|
||||
regval |= (UART_TX_DONE_INT_ENA | UART_TXFIFO_EMPTY_INT_ENA);
|
||||
esp32_serialout(priv, UART_INT_ENA_OFFSET, regval);
|
||||
|
||||
/* Fake a TX interrupt here by just calling uart_xmitchars() with
|
||||
@ -1126,8 +1168,9 @@ static void esp32_txint(struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
/* Disable the TX interrupt */
|
||||
|
||||
esp32_serialout(priv, UART_INT_CLR_OFFSET,
|
||||
(UART_TX_DONE_INT_CLR_S | UART_TXFIFO_EMPTY_INT_CLR_S));
|
||||
regval = esp32_serialin(priv, UART_INT_ENA_OFFSET);
|
||||
regval &= ~(UART_TX_DONE_INT_ENA | UART_TXFIFO_EMPTY_INT_ENA);
|
||||
esp32_serialout(priv, UART_INT_ENA_OFFSET, regval);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
@ -1253,7 +1296,7 @@ int up_putc(int ch)
|
||||
/* Add CR */
|
||||
|
||||
while(!esp32_txready(&CONSOLE_DEV));
|
||||
esp32_send(&CONSOLE_DEV, 'r');
|
||||
esp32_send(&CONSOLE_DEV, '\r');
|
||||
}
|
||||
|
||||
while(!esp32_txready(&CONSOLE_DEV));
|
||||
|
@ -44,6 +44,20 @@
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-procesor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* An IDLE thread stack size for CPU0 must be defined */
|
||||
|
||||
#if !defined(CONFIG_SMP_IDLETHREAD_STACKSIZE)
|
||||
# error CONFIG_SMP_IDLETHREAD_STACKSIZE is not defined
|
||||
#elif CONFIG_SMP_IDLETHREAD_STACKSIZE < 16
|
||||
# error CONFIG_SMP_IDLETHREAD_STACKSIZE is to small
|
||||
#endif
|
||||
|
||||
#define CPU1_IDLETHREAD_STACKSIZE ((CONFIG_SMP_IDLETHREAD_STACKSIZE + 15) & ~15)
|
||||
#define CPU1_IDLETHREAD_STACKWORDS (CPU1_IDLETHREAD_STACKSIZE >> 2)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
@ -51,8 +65,7 @@
|
||||
|
||||
/* This is the CPU1 IDLE stack */
|
||||
|
||||
#define CPU1_IDLETHREAD_STACKSIZE (CONFIG_SMP_IDLETHREAD_STACKSIZE & ~15)
|
||||
extern uint32_t g_cpu1_idlestack[CPU1_IDLETHREAD_STACKSIZE / 34];
|
||||
extern uint32_t g_cpu1_idlestack[CPU1_IDLETHREAD_STACKWORDS];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
@ -33,14 +33,25 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/init.h>
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#include "xtensa.h"
|
||||
#include "xtensa_attr.h"
|
||||
|
||||
#include "chip/esp32_dport.h"
|
||||
#include "chip/esp32_rtccntl.h"
|
||||
#include "esp32_clockconfig.h"
|
||||
#include "esp32_region.h"
|
||||
#include "esp32_start.h"
|
||||
#include "xtensa.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Address of the CPU0 IDLE thread */
|
||||
|
||||
uint32_t g_idlestack[IDLETHREAD_STACKWORDS]
|
||||
__attribute__((aligned(16) section(".noinit")));
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@ -62,6 +73,7 @@
|
||||
void IRAM_ATTR __start(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
uint32_t sp;
|
||||
|
||||
/* Kill the watchdog timer */
|
||||
|
||||
@ -73,6 +85,39 @@ void IRAM_ATTR __start(void)
|
||||
regval &= ~(1 << 14);
|
||||
putreg32(regval, 0x6001f048);
|
||||
|
||||
/* Make sure that normal interrupts are disabled. This is really only an
|
||||
* issue when we are started in un-usual ways (such as from IRAM). In this
|
||||
* case, we can at least defer some unexpected interrupts left over from the
|
||||
* last program execution.
|
||||
*/
|
||||
|
||||
up_irq_disable();
|
||||
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
{
|
||||
register uint32_t *ptr;
|
||||
register int i;
|
||||
|
||||
/* If stack debug is enabled, then fill the stack with a recognizable value
|
||||
* that we can use later to test for high water marks.
|
||||
*/
|
||||
|
||||
for (i = 0, ptr = g_idlestack; i < IDLETHREAD_STACKWORDS; i++)
|
||||
{
|
||||
*ptr++ = STACK_COLOR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Move the stack to a known location. Although we were give a stack
|
||||
* pointer at start-up, we don't know where that stack pointer is positioned
|
||||
* respect to our memory map. The only safe option is to switch to a well-
|
||||
* known IDLE thread stack.
|
||||
*/
|
||||
|
||||
sp = (uint32_t)g_idlestack + IDLETHREAD_STACKSIZE;
|
||||
__asm__ __volatile__("mov sp, %0\n" : : "r"(sp));
|
||||
|
||||
/* Make page 0 access raise an exception */
|
||||
|
||||
esp32_region_protection();
|
||||
@ -108,4 +153,5 @@ void IRAM_ATTR __start(void)
|
||||
/* Bring up NuttX */
|
||||
|
||||
os_start();
|
||||
for(; ; ); /* Should not return */
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user