Squashed commit of the following:

arch/arm/src/max326xx and configs/max32660-evsys/src:  Fix some issues with GPIO setup of output pins.  Correct polarity of on-board LED output.  The on-board LED is now functional.

    arch/arm/src/max326xx: WFI instruction in IDLE loop seems to interfere with stability.  Commented out for now.  Needs to be investigated further.
This commit is contained in:
Gregory Nutt 2018-11-28 11:20:31 -06:00
parent 5da7dbaf98
commit a6682a9bef
8 changed files with 128 additions and 46 deletions

View File

@ -200,6 +200,55 @@
#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
#define NVIC_SYSH_PRIORITY_STEP 0x20 /* Eight priority levels in steps 0x20 */
/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled
* by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most
* interrupts will not have execution priority. SVCall must have execution
* priority in all cases.
*
* In the normal cases, interrupts are not nest-able and all interrupts run
* at an execution priority between NVIC_SYSH_PRIORITY_MIN and
* NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall).
*
* If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special
* high priority interrupts are supported. These are not "nested" in the
* normal sense of the word. These high priority interrupts can interrupt
* normal processing but execute outside of OS (although they can "get back
* into the game" via a PendSV interrupt).
*
* In the normal course of things, interrupts must occasionally be disabled
* using the up_irq_save() inline function to prevent contention in use of
* resources that may be shared between interrupt level and non-interrupt
* level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT,
* do we disable all interrupts (except SVCall), or do we only disable the
* "normal" interrupts. Since the high priority interrupts cannot interact
* with the OS, you may want to permit the high priority interrupts even if
* interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be
* used to select either behavior:
*
* ----------------------------+--------------+----------------------------
* CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES
* ----------------------------+--------------+--------------+-------------
* CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO
* ----------------------------+--------------+--------------+-------------
* | | | SVCall
* | SVCall | SVCall | HIGH
* Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL
* | | MAXNORMAL |
* ----------------------------+--------------+--------------+-------------
*/
#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL)
# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP)
# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY
# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
#else
# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY
# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
#endif
/************************************************************************************
* Public Types
************************************************************************************/

View File

@ -176,10 +176,12 @@ void up_idle(void)
up_idlepm();
#if 0 /* REVISIT: "wfi" causes instability */
/* Sleep until an interrupt occurs to save power */
BEGIN_IDLE();
asm("WFI");
END_IDLE();
#endif
#endif
}

View File

@ -312,9 +312,8 @@ void up_irqinitialize(void)
/* Make sure that we are using the correct vector table. The default
* vector address is 0x0000:0000 but if we are executing code that is
* positioned in SRAM or in external FLASH, then we may need to reset
* the interrupt vector so that it refers to the table in SRAM or in
* external FLASH.
* positioned in SRAM, then we need to reset the interrupt vector so
* that it refers to the table in SRAM.
*/
putreg32((uint32_t)_vectors, NVIC_VECTAB);
@ -385,7 +384,7 @@ void up_irqinitialize(void)
up_enable_irq(MAX326_IRQ_MEMFAULT);
#endif
/* Attach all other processor exceptions (except reset and sys tick) */
/* Attach all other processor exceptions (except reset and SysTick) */
#ifdef CONFIG_DEBUG_FEATURES
irq_attach(MAX326_IRQ_NMI, max326_nmi, NULL);

View File

@ -244,6 +244,7 @@ void max326_default(uint32_t pinmask)
int max326_gpio_config(max326_pinset_t pinset)
{
irqstate_t flags;
max326_pinset_t subset;
unsigned int pin;
uint32_t pinmask;
uint32_t regval;
@ -284,20 +285,33 @@ int max326_gpio_config(max326_pinset_t pinset)
/* Enable pull up and pull down */
if ((pinset & GPIO_MODE_MASK) != GPIO_FLOAT)
subset = pinset & GPIO_MODE_MASK;
if (subset != GPIO_FLOAT)
{
/* Enable pull-down resistor */
bool upcap; /* True: GPIO_PULLUP supported */
if ((PULLUP_SET & pinmask) != 0 ||
(pinset & GPIO_MODE_MASK) == GPIO_PULLDOWN)
/* Enable pull-down resistor. All pins support pull down resisters,
* but it works differently:
*
* - For pins that support only pull-down, the PULLEN register
* selects the pull down resister.
* - For pins that support both pull-up and pull down, the PULLEN
* enables the feature but the PULLSEL registers selects the pull
* up or down direction.
*/
upcap = ((PULLUP_SET & pinmask) != 0);
if (upcap || subset == GPIO_PULLDOWN)
{
regval = getreg32(MAX326_GPIO0_PULLEN);
regval |= pinmask;
putreg32(regval, MAX326_GPIO0_PULLEN);
}
if ((PULLUP_SET & pinmask) != 0 &&
(pinset & GPIO_MODE_MASK) == GPIO_PULLUP)
/* Enable pull-ups (only certain pins support pull up resistors) */
if (upcap && subset == GPIO_PULLUP)
{
/* Enable pull-up resistor */
@ -309,12 +323,12 @@ int max326_gpio_config(max326_pinset_t pinset)
/* Set drive strength */
subset = pinset & GPIO_DRIVE_MASK;
if ((DS1_SET & pinmask) == 0)
{
/* Only two levels of drive strength */
if ((pinset & GPIO_DRIVE_MASK) != GPIO_DRIVE_MEDHI ||
(pinset & GPIO_DRIVE_MASK) != GPIO_DRIVE_HI)
if (subset == GPIO_DRIVE_MEDHI || subset == GPIO_DRIVE_HI)
{
regval = getreg32(MAX326_GPIO0_DS0SEL);
regval |= pinmask;
@ -331,16 +345,14 @@ int max326_gpio_config(max326_pinset_t pinset)
* HI DS0=1 DS1=1
*/
if ((pinset & GPIO_DRIVE_MASK) != GPIO_DRIVE_MEDLO ||
(pinset & GPIO_DRIVE_MASK) != GPIO_DRIVE_HI)
if (subset == GPIO_DRIVE_MEDLO || subset == GPIO_DRIVE_HI)
{
regval = getreg32(MAX326_GPIO0_DS0SEL);
regval |= pinmask;
putreg32(regval, MAX326_GPIO0_DS0SEL);
}
if ((pinset & GPIO_DRIVE_MASK) != GPIO_DRIVE_MEDHI ||
(pinset & GPIO_DRIVE_MASK) != GPIO_DRIVE_HI)
if (subset == GPIO_DRIVE_MEDHI || subset == GPIO_DRIVE_HI)
{
regval = getreg32(MAX326_GPIO0_DS1SEL);
regval |= pinmask;
@ -363,6 +375,7 @@ int max326_gpio_config(max326_pinset_t pinset)
regval = getreg32(MAX326_GPIO0_OUTEN); /* Enable output drivers */
regval |= pinmask;
putreg32(regval, MAX326_GPIO0_OUTEN);
break;
case GPIO_ALT1:
max326_altfunc(pinmask, AF_FUNC1);
@ -427,14 +440,14 @@ void max326_gpio_write(max326_pinset_t pinset, bool value)
/* Modification of registers must be atomic */
flags = spin_lock_irqsave();
regval = getreg32(MAX326_GPIO0_OUT); /* Set output high */
regval = getreg32(MAX326_GPIO0_OUT);
if (value)
{
regval |= (1 << pin);
regval |= (1 << pin); /* Set output high */
}
else
{
regval &= ~(1 << pin);
regval &= ~(1 << pin); /* Set output low */
}
putreg32(regval, MAX326_GPIO0_OUT);
@ -494,33 +507,33 @@ int max326_gpio_dump(max326_pinset_t pinset, const char *msg);
* Alternate Function 3 1 1
*/
regval = getre32(MAX326_GPIO0_AF0SEL);
regval = getreg32(MAX326_GPIO0_AF0SEL);
afmode = (regval & pinmask) != 0 ? 1 : 0;
regval = getre32(MAX326_GPIO0_AF1SEL);
regval = getreg32(MAX326_GPIO0_AF1SEL);
afmode |= (regval & pinmask) != 0 ? 2 : 0;
gpioinfo(" Mode: %d\n", g_afmode[afmode]);
regval = getre32(MAX326_GPIO0_OUTEN);
regval = getreg32(MAX326_GPIO0_OUTEN);
gpioinfo(" Output Enable: %s\n",
(regval & pinmask) != 0 ? "Yes" : "No");
regval = getre32(MAX326_GPIO0_OUT);
regval = getreg32(MAX326_GPIO0_OUT);
gpioinfo(" Output Value: %s\n",
(regval & pinmask) != 0 ? "High" : "Low");
regval = getre32(MAX326_GPIO0_IN);
regval = getreg32(MAX326_GPIO0_IN);
gpioinfo(" Input Value: %s\n",
(regval & pinmask) != 0 ? "High" : "Low");
regval = getre32(MAX326_GPIO0_INTMODE);
regval = getreg32(MAX326_GPIO0_INTMODE);
edge = (regval & pinmask) != 0
gpioinfo(" Intr Mode: %s\n", edge ? "Yes" : "No");
regval = getre32(MAX326_GPIO0_INTPOL);
regval = getreg32(MAX326_GPIO0_INTPOL);
if (edge)
{
uint32_t dualedge = getre32(MAX326_GPIO0_INTDUALEDGE);
uint32_t dualedge = getreg32(MAX326_GPIO0_INTDUALEDGE);
if ((dualedge & pinmask) != 0)
{
gpioinfo(" Intr Edge: Both edges\n");
@ -537,20 +550,20 @@ int max326_gpio_dump(max326_pinset_t pinset, const char *msg);
(regval & pinmask) != 0 ? "High" : "Low");
}
regval = getre32(MAX326_GPIO0_INTEN);
regval = getreg32(MAX326_GPIO0_INTEN);
gpioinfo(" Intr Enabled: %s\n",
(regval & pinmask) != 0 ? "Yes" : "No");
regval = getre32(MAX326_GPIO0_INTFL);
regval = getreg32(MAX326_GPIO0_INTFL);
gpioinfo(" Intr Pending: %s\n",
(regval & pinmask) != 0 ? "Yes" : "No");
regval = getre32(MAX326_GPIO0_WAKEEN);
regval = getreg32(MAX326_GPIO0_WAKEEN);
gpioinfo(" Wakeup Enabled: %s\n",
(regval & pinmask) != 0 ? "Yes" : "No");
pullmode = 0
regval = getre32(MAX326_GPIO0_PULLEN);
regval = getreg32(MAX326_GPIO0_PULLEN);
if ((regval & pinmask) != 0)
{
if ((PULLUP_SET & pinmask) == 0)
@ -559,7 +572,7 @@ int max326_gpio_dump(max326_pinset_t pinset, const char *msg);
}
else
{
regval = getre32(MAX326_GPIO0_PULLSEL);
regval = getreg32(MAX326_GPIO0_PULLSEL);
pullmode = (regval & pinmask) != 0 ? 2 : 1;
}
}
@ -567,7 +580,7 @@ int max326_gpio_dump(max326_pinset_t pinset, const char *msg);
gpioinfo(" Resister Mode: %s\n", g_pullmode[pullmode]);
dsmode = (PULLUP_SET & pinmask) == 0 ? 1 : 0;
regval = getre32(MAX326_GPIO0_DS0SEL);
regval = getreg32(MAX326_GPIO0_DS0SEL);
if ((regval & pinmask) != 0)
{
if (PULLUP_SET & pinmask) == 0)
@ -576,13 +589,13 @@ int max326_gpio_dump(max326_pinset_t pinset, const char *msg);
}
else
{
regval = getre32(MAX326_GPIO0_DS1SEL);
regval = getreg32(MAX326_GPIO0_DS1SEL);
dsmode = (regval & pinmask) != 0 ? 3 : 1;
}
}
else if (PULLUP_SET & pinmask) != 0)
{
regval = getre32(MAX326_GPIO0_DS1SEL);
regval = getreg32(MAX326_GPIO0_DS1SEL);
if (regval & pinmask) != 0)
{
dsmode = 2;
@ -591,11 +604,11 @@ int max326_gpio_dump(max326_pinset_t pinset, const char *msg);
gpioinfo(" Drive Strength: %s\n", g_dsmode[dsmode]);
regval = getre32(MAX326_GPIO0_INHYSEN);
regval = getreg32(MAX326_GPIO0_INHYSEN);
gpioinfo(" Hysteresis: %s\n",
(regval & pinmask) != 0 ? "Yes" : "No");
regval = getre32(MAX326_GPIO0_SRSEL);
regval = getreg32(MAX326_GPIO0_SRSEL);
gpioinfo(" Slew Enabled: %s\n",
(regval & pinmask) != 0 ? "Yes" : "No");
}

View File

@ -45,7 +45,7 @@ Status
up the board on bad configurations. The rest of the bring-up will
use this SRAM configuration.
Some successby the end of the day:
Some success the end of the day:
ACFH
@ -57,6 +57,10 @@ Status
issues. I comes up with 'NuttShell' then stops. I hit enter and
" (NSH) NuttX" comes out etc. So it looks like Rx input is driving
the Tx output.
2018-11-28: Found that the WFI instruction in the IDLE loop was causing
instability. System ran OK until it was in IDLE then it became
unstable. Commenting out the WIF restores stability. Also fixed the
on-board LED which now currently reflects the state.
Serial Console
==============
@ -150,7 +154,7 @@ Debugging from FLASH:
$ arm-none-eabi-gdb
(gdb) target remote localhost:3333
(gdb) mon reset
(gdb) mon reg pc 0x11c # Set PC to __start entry point
(gdb) mon reg pc __start # Set PC to __start entry point
(gdb) file nuttx
(gdb) b os_start
(gdb) c
@ -159,7 +163,17 @@ Debugging from FLASH:
Debugging from SRAM:
Same except that the __start entry point is 0x2000011c, not 0x11c.
Same except (1) that the __start entry point is 0x2000011c, not 0x11c, and
the code needs to be reloaded into SRAM each time:
(gdb) target remote localhost:3333
(gdb) mon reset
(gdb) mon halt
(gdb) load nuttx # Re-load code into SRAM
(gdb) mon reg pc __start # Set PC to __start entry point
(gdb) file nuttx
(gdb) b os_start
(gdb) c
Recovering from bad code in FLASH:

View File

@ -9,6 +9,7 @@ CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_IRQBUTTONS=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_ARMV7M_LAZYFPU=y
CONFIG_ARMV7M_USEBASEPRI=y
CONFIG_BOARD_LOOPSPERMSEC=8192
CONFIG_BUILTIN=y
CONFIG_DISABLE_POLL=y

View File

@ -46,13 +46,17 @@
* Pre-processor Definitions
****************************************************************************/
/* A single red LED is available driven by GPIO P0.13. */
/* A single red LED is available driven by GPIO P0.13.
* High illuminates, initial output is Low.
*/
#define GPIO_LED (GPIO_OUTPUT | GPIO_PORT0 | GPIO_PIN13)
#define GPIO_LED (GPIO_OUTPUT | GPIO_VALUE_ZERO | GPIO_PORT0 | GPIO_PIN13)
/* An single button is available on GPIO P0.12 for use by software. */
/* An single button is available on GPIO P0.12 for use by software.
* Interrupts are available on both edges.
*/
#define GPIO_BUTTON (GPIO_INPUT | GPIO_PORT0 | GPIO_PIN12)
#define GPIO_BUTTON (GPIO_INTBOTH | GPIO_PORT0 | GPIO_PIN12)
#define BUTTON_IRQ MAX326_IRQ_P0_12
/****************************************************************************

View File

@ -101,7 +101,7 @@ void board_autoled_on(int led)
{
if (led == 1 || led == 3)
{
max326_gpio_write(GPIO_LED, false); /* Low illuminates */
max326_gpio_write(GPIO_LED, true); /* High illuminates */
}
}
@ -113,7 +113,7 @@ void board_autoled_off(int led)
{
if (led == 3)
{
max326_gpio_write(GPIO_LED, true); /* High extinguishes */
max326_gpio_write(GPIO_LED, false); /* Low extinguishes */
}
}