LPC17xx GPIO interrupt fixes: lpc17_setintedge() must be atomic. Can't disable interrupts from interrupt handlers because they are automatically re-enabled. Try re-configuring pin instead.
This commit is contained in:
parent
a3906f2f72
commit
141fb6a32b
@ -4523,4 +4523,10 @@
|
||||
* arch/arm/src/lpc17_gpiodbg.c: Updated so that it correctly
|
||||
reports LPC177x/8x GPIO registers when GPIO debug is enabled
|
||||
(2013-4-05).
|
||||
|
||||
* arch/arm/src/Makefile: The variable NUTTX already includes
|
||||
the extension $(EXEEXT). So remove the second extension
|
||||
$(NUTTX)$(EXEEXT) in two places (2013-4-7).
|
||||
* arch/arm/src/lpc17xx/lpc17_gpioint.c: Disable interrrupts in
|
||||
lpc17_setintedge(). This logic must be atomic because it can be
|
||||
re-entered before it completes enabled interrupts, sometimes
|
||||
leaving the interrupts in a strange state (2013-4-7).
|
||||
|
2
TODO
2
TODO
@ -364,8 +364,6 @@ o Kernel Build
|
||||
A similar issue exists in NSH that uses some internal OS
|
||||
interfaces that would not be available in a kernel build
|
||||
(such as foreach_task, foreach_mountpoint, etc.).
|
||||
|
||||
See also "Memory Management" for another kernel build issue.
|
||||
Status: Open
|
||||
Priority: Low -- the kernel build configuration is not fully fielded
|
||||
yet.
|
||||
|
@ -99,7 +99,7 @@
|
||||
#define GPIO_SSP1_MISO_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN8)
|
||||
#define GPIO_MAT2p2_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN8)
|
||||
#define GPIO_RTC_EV1_1 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN8)
|
||||
#define GPIO_LCD_VD16 (GPIO_ALT7 | GPIO_FLOA | GPIO_HYSTERESIST | GPIO_PORT0 | GPIO_PIN8)
|
||||
#define GPIO_LCD_VD16 (GPIO_ALT7 | GPIO_FLOAT | GPIO_HYSTERESIS | GPIO_PORT0 | GPIO_PIN8)
|
||||
|
||||
#define GPIO_I2S_TXSDA_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN9)
|
||||
#define GPIO_SSP1_MOSI_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN9)
|
||||
|
@ -116,8 +116,13 @@ static unsigned int lpc17_getintedge(unsigned int port, unsigned int pin)
|
||||
static void lpc17_setintedge(uint32_t intbase, unsigned int pin,
|
||||
unsigned int edges)
|
||||
{
|
||||
irqstate_t flags;
|
||||
int regval;
|
||||
|
||||
/* These must be atomic */
|
||||
|
||||
flags = irqsave();
|
||||
|
||||
/* Set/clear the rising edge enable bit */
|
||||
|
||||
regval = getreg32(intbase + LPC17_GPIOINT_INTENR_OFFSET);
|
||||
@ -145,6 +150,7 @@ static void lpc17_setintedge(uint32_t intbase, unsigned int pin,
|
||||
}
|
||||
|
||||
putreg32(regval, intbase + LPC17_GPIOINT_INTENF_OFFSET);
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -389,9 +395,10 @@ static void lpc17_gpiodemux(uint32_t intbase, uint32_t intmask,
|
||||
* Name: lpc17_gpiointerrupt
|
||||
*
|
||||
* Description:
|
||||
* Handle the EINT3 interrupt that also indicates that a GPIO interrupt has
|
||||
* occurred. NOTE: This logic will have to be extended if EINT3 is
|
||||
* actually used for External Interrupt 3.
|
||||
* Handle the GPIO interrupt. For the LPC176x family, that interrupt could
|
||||
* also that also indicates that an EINT3 interrupt has occurred. NOTE:
|
||||
* This logic would have to be extended if EINT3 is actually used for
|
||||
* External Interrupt 3 on an LPC176x platform.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
@ -12,6 +12,7 @@ CONTENTS
|
||||
o Buttons
|
||||
o FPU
|
||||
o Using OpenOCD with the Olimex ARM-USB-OCD
|
||||
o Loading Code with the ISP Board
|
||||
o Configuration
|
||||
|
||||
LEDs
|
||||
@ -245,27 +246,53 @@ Using OpenOCD with the Olimex ARM-USB-OCD
|
||||
(gdb) monitor halt
|
||||
|
||||
NOTES:
|
||||
|
||||
1. The MCU must be halted using 'monitor halt' prior to loading code.
|
||||
|
||||
2. 'monitor reset' will restart the processor after loading code.
|
||||
|
||||
3. The 'monitor' command can be abbreviated as just 'mon'.
|
||||
|
||||
After starting GDB, you can load the NuttX ELF file:
|
||||
After starting GDB, you can load the NuttX ELF file like this:
|
||||
|
||||
(gdb) mon halt
|
||||
(gdb) load nuttx
|
||||
|
||||
NOTES:
|
||||
|
||||
1. NuttX should have been built so that it has debugging symbols
|
||||
(by setting CONFIG_DEBUG_SYMBOLS=y in the .config file).
|
||||
|
||||
2. The MCU must be halted prior to loading code.
|
||||
3. I find that there are often undetected write failures. I usually
|
||||
load nuttx twice to assure good FLASH contents:
|
||||
|
||||
3. I find that there are often undetected write failures when using
|
||||
the Olimex ARM-USB-OCD debugber and that if you start the program
|
||||
with a bad FLASH failure, it will lock up OpenOCD. I usually
|
||||
oad nuttx twice, restarting OpenOCD in between in order to assure
|
||||
good FLASH contents:
|
||||
|
||||
(gdb) mon halt
|
||||
(gdb) load nuttx
|
||||
(gdb) mon reset
|
||||
|
||||
Exit GDB, kill the OpenOCD server, recycle power on the board,
|
||||
restart the OpenOCD server and GDB, then:
|
||||
|
||||
(gdb) mon halt
|
||||
(gdb) load nuttx
|
||||
(gdb) mon reset
|
||||
|
||||
Other debuggers may not have these issues and such drastic steps may
|
||||
not be necessary.
|
||||
|
||||
Loading Code with the ISP Board
|
||||
===============================
|
||||
|
||||
Use can also load code onto the board using the WaveShare and the UART0
|
||||
ISP/VCOM board. I use the FlashMagic program for Windows available here:
|
||||
http://www.flashmagictool.com/ . It is so easy to use that no further
|
||||
explanation should be necessary: Just select the LPC1788, the ISP COM
|
||||
port, and the NuttX .hex file and program it.
|
||||
|
||||
CONFIGURATION
|
||||
=============
|
||||
@ -452,13 +479,18 @@ CONFIGURATION
|
||||
on the 4.3" LCD module by modifying the configuration in the
|
||||
following ways:
|
||||
|
||||
Drivers:
|
||||
CONFIG_INPUT=y : Enable support for input devices
|
||||
CONFIG_INPUT_ADS7843E=y : Enable support for the XPT2048
|
||||
CONFIG_ADS7843E_SPIDEV=1 : Use SSP1 for communication
|
||||
CONFIG_SPI=y : Enable SPI support
|
||||
CONFIG_SPI_EXCHANGE=n : exchange() method is not supported
|
||||
|
||||
System Type:
|
||||
CONFIG_GPIO_IRQ=y : GPIO interrupt support
|
||||
CONFIG_LPC17_SSP1=y : Enable support for SSP1
|
||||
|
||||
Applicaton Configuration:
|
||||
CONFIG_EXAMPLES_TOUCHSCREEN=y : Enable the touchscreen built-int test
|
||||
CONFIG_EXAMPLES_TOUCHSCREEN_BUILTIN=y
|
||||
|
||||
@ -470,15 +502,21 @@ CONFIGURATION
|
||||
There is a jumper on board that enables the CD pin. OR, you can simply
|
||||
remove the SD module so that it does not drive the CD pin.
|
||||
|
||||
Drivers:
|
||||
CONFIG_MMCSD=n : No MMC/SD driver support
|
||||
|
||||
System Type:
|
||||
CONFIG_LPC17_GPDMA=n : No DMA
|
||||
CONFIG_ARCH_DMA=n
|
||||
CONFIG_LPC17_SDCARD=n : No SD card driver
|
||||
CONFIG_SDIO_DMA=n : No SD card DMA
|
||||
CONFIG_MMCSD=n : No MMC/SD driver support
|
||||
CONFIG_ARCH_DMA=n
|
||||
|
||||
File Systems:
|
||||
CONFIG_FS_FAT=n : No FAT file system support
|
||||
|
||||
For touchscreen debug output:
|
||||
|
||||
Build Setup:
|
||||
CONFIG_DEBUG=y
|
||||
CONFIG_DEBUG_VERBOSE=y
|
||||
CONFIG_DEBUG_INPUT=y
|
||||
|
@ -178,11 +178,21 @@ static void tsc_enable(FAR struct ads7843e_config_s *state, bool enable)
|
||||
ivdbg("enable:%d\n", enable);
|
||||
if (enable)
|
||||
{
|
||||
/* Configure the PENIRQ GPIO as an interrupting enable and enable the interrupt */
|
||||
|
||||
(void)lpc17_configgpio(GPIO_TC_PENIRQ);
|
||||
up_enable_irq(LPC17_IRQ_PENIRQ);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable PENIRQ interrupts and reconfigure the pin as a normal input pin.
|
||||
* We have to do this because the PENIRQ interrupt will be disabled from
|
||||
* interrupt handling logic and, in that case, will be automatically re-enabled
|
||||
* when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_disable_irq(LPC17_IRQ_PENIRQ);
|
||||
(void)lpc17_configgpio(GPIO_TC_PEN);
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,9 +288,12 @@ int arch_tcinitialize(int minor)
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
/* Configure and enable the XPT2046 PENIRQ pin as an interrupting input. */
|
||||
/* Configure and enable the XPT2046 PENIRQ pin as a normal input. It
|
||||
* will be reconfigured as an interrupting input when tsc_enable is
|
||||
* called to enable the PENIRQ interrupt.
|
||||
*/
|
||||
|
||||
(void)lpc17_configgpio(GPIO_TC_PENIRQ);
|
||||
(void)lpc17_configgpio(GPIO_TC_PEN);
|
||||
|
||||
/* Configure the XPT2046 BUSY pin as a normal input. */
|
||||
|
||||
@ -336,4 +349,3 @@ void arch_tcuninitialize(void)
|
||||
}
|
||||
|
||||
#endif /* CONFIG_INPUT_ADS7843E */
|
||||
|
||||
|
@ -132,6 +132,7 @@
|
||||
* Pins are configured as floating because there are pullups on the module.
|
||||
*/
|
||||
|
||||
#define GPIO_TC_PEN (GPIO_INPUT | GPIO_FLOAT | GPIO_PORT2 | GPIO_PIN15)
|
||||
#define GPIO_TC_PENIRQ (GPIO_INTBOTH | GPIO_FLOAT | GPIO_PORT2 | GPIO_PIN15)
|
||||
#define GPIO_TC_BUSY (GPIO_INPUT | GPIO_FLOAT | GPIO_PORT2 | GPIO_PIN14)
|
||||
#define GPIO_TC_CS (GPIO_OUTPUT | GPIO_VALUE_ONE | GPIO_PORT1 | GPIO_PIN8)
|
||||
|
Loading…
Reference in New Issue
Block a user