From 4c2b07c3887fa399a27d664c22e1c268ce3b174e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 19 Nov 2013 15:52:10 -0600 Subject: [PATCH] Olimex LPC_H3131: Add GPIO support for LEDs and for USB host power enable and overcurrent detection. --- configs/olimex-lpc-h3131/README.txt | 5 + configs/olimex-lpc-h3131/include/board.h | 81 ++++++++---- configs/olimex-lpc-h3131/src/lpc31_boot.c | 4 +- configs/olimex-lpc-h3131/src/lpc31_leds.c | 132 ++++++++++++++++++- configs/olimex-lpc-h3131/src/lpc31_usbhost.c | 17 ++- configs/olimex-lpc-h3131/src/lpc_h3131.h | 16 +++ 6 files changed, 221 insertions(+), 34 deletions(-) diff --git a/configs/olimex-lpc-h3131/README.txt b/configs/olimex-lpc-h3131/README.txt index 1bba06246a..d5113176ef 100644 --- a/configs/olimex-lpc-h3131/README.txt +++ b/configs/olimex-lpc-h3131/README.txt @@ -3,6 +3,11 @@ README This README file discusses the port of NuttX to the Olimex LPC-H3131 board. + NOTE: This is a minimal port to the Olimex LPC-H3131. According to Olimex + documentation, the LPC-H3131 is similar in design to the Embedded Artists + EA3131. As a consequence, it should be possible to leverage additional + functionality from configs/ea3131 without too much difficulty. + Contents ======== diff --git a/configs/olimex-lpc-h3131/include/board.h b/configs/olimex-lpc-h3131/include/board.h index e2181dc1b5..4ae3f8d758 100644 --- a/configs/olimex-lpc-h3131/include/board.h +++ b/configs/olimex-lpc-h3131/include/board.h @@ -100,17 +100,48 @@ (0) /* LED definitions ******************************************************************/ +/* If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in any + * way. The following definitions are used to access individual LEDs. + */ -#define LED_STARTED 0 -#define LED_HEAPALLOCATE 1 -#define LED_IRQSENABLED 2 -#define LED_STACKCREATED 3 -#define LED_INIRQ 4 -#define LED_SIGNAL 5 -#define LED_ASSERTION 6 -#define LED_PANIC 7 +/* LED index values for use with lpc31_setled() */ + +#define BOARD_LED1 0 +#define BOARD_LED2 1 +#define BOARD_NLEDS 2 + +/* LED bits for use with lpc31_setleds() */ + +#define BOARD_LED1_BIT (1 << BOARD_LED1) +#define BOARD_LED2_BIT (1 << BOARD_LED2) + +/* These LEDs are not used by the board port unless CONFIG_ARCH_LEDS is + * defined. In that case, the usage by the board port is as follows: + * + * SYMBOL Meaning LED state + * LED2 LED1 + * ------------------------ -------------------------- ------ ------ */ + +#define LED_STARTED 0 /* NuttX has been started OFF OFF */ +#define LED_HEAPALLOCATE 0 /* Heap has been allocated OFF OFF */ +#define LED_IRQSENABLED 0 /* Interrupts enabled OFF OFF */ +#define LED_STACKCREATED 1 /* Idle stack created ON OFF */ +#define LED_INIRQ 2 /* In an interrupt N/C N/C */ +#define LED_SIGNAL 2 /* In a signal handler N/C N/C */ +#define LED_ASSERTION 2 /* An assertion failed N/C N/C */ +#define LED_PANIC 3 /* The system has crashed N/C Blinking */ +#undef LED_IDLE /* MCU is is sleep mode Not used */ + +/* Thus if LED2 is statically on, NuttX has successfully booted and is, + * apparently, running normmally. If LED1 is flashing at approximately + * 2Hz, then a fatal error has been detected and the system has halted. + * + * NOTE: That LED2 is not used after completion of booting and may + * be used by other board-specific logic. + */ /* Button definitions ***************************************************************/ +/* The Olimex LPC_H3131 has no user buttons */ /************************************************************************************ * Public Data @@ -141,26 +172,28 @@ extern "C" { void lpc31_boardinitialize(void); -/************************************************************************************ - * Button support. - * - * Description: - * up_buttoninit() must be called to initialize button resources. After that, - * up_buttons() may be called to collect the state of all buttons. up_buttons() - * returns an 8-bit bit set with each bit associated with a button. See the - * BUTTON_* definitions above for the meaning of each bit. - * - ************************************************************************************/ - -#ifdef CONFIG_ARCH_BUTTONS -void up_buttoninit(void); -uint8_t up_buttons(void); -#endif - #undef EXTERN #if defined(__cplusplus) } #endif +/************************************************************************************ + * Name: lpc31_setled, and lpc31_setleds + * + * Description: + * These interfaces allow user control of the board LEDs. + * + * If CONFIG_ARCH_LEDS is defined, then NuttX will control both on-board LEDs up + * until the completion of boot. The it will continue to control LED1; LED2 is + * avaiable for application use. + * + * If CONFIG_ARCH_LEDS is not defined, then both LEDs are available for application + * use. + * + ************************************************************************************/ + +void lpc31_setled(int led, bool ledon); +void lpc31_setleds(uint8_t ledset); + #endif /* __ASSEMBLY__ */ #endif /* __CONFIGS_OLIMEX_LPC_H3131_INCLUDE_BOARD_H */ diff --git a/configs/olimex-lpc-h3131/src/lpc31_boot.c b/configs/olimex-lpc-h3131/src/lpc31_boot.c index c8cda3f3b3..46976c6fe4 100644 --- a/configs/olimex-lpc-h3131/src/lpc31_boot.c +++ b/configs/olimex-lpc-h3131/src/lpc31_boot.c @@ -114,9 +114,7 @@ void lpc31_boardinitialize(void) } #endif - /* Configure on-board LEDs if LED support has been selected. */ + /* Configure on-board LEDs in all cases */ -#ifdef CONFIG_ARCH_LEDS up_ledinit(); -#endif } diff --git a/configs/olimex-lpc-h3131/src/lpc31_leds.c b/configs/olimex-lpc-h3131/src/lpc31_leds.c index 05219f8803..5f4a94c5df 100644 --- a/configs/olimex-lpc-h3131/src/lpc31_leds.c +++ b/configs/olimex-lpc-h3131/src/lpc31_leds.c @@ -50,6 +50,8 @@ #include "up_internal.h" #include "lpc31_internal.h" +#include "lpc_h3131.h" + /**************************************************************************** * Definitions ****************************************************************************/ @@ -80,27 +82,153 @@ /**************************************************************************** * Name: up_ledinit + * + * Description: + * Configure LEDs. LEDs are left in the OFF state. + * ****************************************************************************/ -#ifdef CONFIG_ARCH_LEDS void up_ledinit(void) { + /* Turn off both LEDs */ + + gpio_outputlow(LPC31_IOCONFIG_GPIO, GPIO_LED1); + gpio_outputlow(LPC31_IOCONFIG_GPIO, GPIO_LED2); } /**************************************************************************** * Name: up_ledon + * + * Description: + * Select the "logical" ON state: + * + * SYMBOL Value Meaning LED state + * LED2 LED1 + * ---------------- ----- ----------------------- -------- -------- + * LED_STARTED 0 NuttX has been started OFF OFF + * LED_HEAPALLOCATE 0 Heap has been allocated OFF OFF + * LED_IRQSENABLED 0 Interrupts enabled OFF OFF + * LED_STACKCREATED 1 Idle stack created ON OFF + * LED_INIRQ 2 In an interrupt N/C N/C + * LED_SIGNAL 2 In a signal handler N/C N/C + * LED_ASSERTION 2 An assertion failed N/C N/C + * LED_PANIC 3 The system has crashed N/C Blinking + * LED_IDLE - MCU is is sleep mode Not used + * ****************************************************************************/ +#ifdef CONFIG_ARCH_LEDS void up_ledon(int led) { + switch (led) + { + case 0: + gpio_outputlow(LPC31_IOCONFIG_GPIO, GPIO_LED1); + gpio_outputlow(LPC31_IOCONFIG_GPIO, GPIO_LED2); + break; + + case 1: + gpio_outputlow(LPC31_IOCONFIG_GPIO, GPIO_LED1); + gpio_outputhigh(LPC31_IOCONFIG_GPIO, GPIO_LED2); + break; + + case 2: + break; + + case 3: + gpio_outputhigh(LPC31_IOCONFIG_GPIO, GPIO_LED1); + break; + } } +#endif /**************************************************************************** * Name: up_ledoff + * + * Description: + * Select the "logical" OFF state: + * + * SYMBOL Value Meaning LED state + * LED2 LED1 + * ---------------- ----- ----------------------- -------- -------- + * LED_STARTED 0 NuttX has been started OFF OFF + * LED_HEAPALLOCATE 0 Heap has been allocated OFF OFF + * LED_IRQSENABLED 0 Interrupts enabled OFF OFF + * LED_STACKCREATED 1 Idle stack created ON OFF + * LED_INIRQ 2 In an interrupt N/C N/C + * LED_SIGNAL 2 In a signal handler N/C N/C + * LED_ASSERTION 2 An assertion failed N/C N/C + * LED_PANIC 3 The system has crashed N/C Blinking + * LED_IDLE - MCU is is sleep mode Not used + * ****************************************************************************/ +#ifdef CONFIG_ARCH_LEDS void up_ledoff(int led) { + switch (led) + { + case 0: + case 1: + case 2: + break; + + case 3: + gpio_outputlow(LPC31_IOCONFIG_GPIO, GPIO_LED1); + break; + } +} +#endif + +/************************************************************************************ + * Name: lpc31_setled, and lpc31_setleds + * + * Description: + * These interfaces allow user control of the board LEDs. + * + * If CONFIG_ARCH_LEDS is defined, then NuttX will control both on-board LEDs up + * until the completion of boot. The it will continue to control LED2; LED1 is + * avaiable for application use. + * + * If CONFIG_ARCH_LEDS is not defined, then both LEDs are available for application + * use. + * + ************************************************************************************/ + +void lpc31_setled(int led, bool ledon) +{ + uint32_t bit; + +#ifndef CONFIG_ARCH_LEDS + if (led == BOARD_LED1) + { + bit = GPIO_LED1; + } + else +#endif + if (led == BOARD_LED2) + { + bit = GPIO_LED2; + } + else + { + return; + } + + if (ledon) + { + gpio_outputhigh(LPC31_IOCONFIG_GPIO, bit); + } + else + { + gpio_outputlow(LPC31_IOCONFIG_GPIO, bit); + } } -#endif /* CONFIG_ARCH_LEDS */ +void lpc31_setleds(uint8_t ledset) +{ +#ifndef CONFIG_ARCH_LEDS + lpc31_setled(BOARD_LED1, (ledset & BOARD_LED1_BIT) != 0); +#endif + lpc31_setled(BOARD_LED2, (ledset & BOARD_LED2_BIT) != 0); +} diff --git a/configs/olimex-lpc-h3131/src/lpc31_usbhost.c b/configs/olimex-lpc-h3131/src/lpc31_usbhost.c index e8155c1f91..cbf2b7c139 100644 --- a/configs/olimex-lpc-h3131/src/lpc31_usbhost.c +++ b/configs/olimex-lpc-h3131/src/lpc31_usbhost.c @@ -158,10 +158,15 @@ static int ehci_waiter(int argc, char *argv[]) void weak_function lpc31_usbhost_bootinitialize(void) { - /* Configure pin to drive VBUS power */ -#warning Missing logic + /* Configure output pin to drive VBUS power (initial state: power off) */ - /* Configure pin to detect overrcurrent errors */ + gpio_outputhigh(LPC31_IOCONFIG_GPIO, GPIO_NOTG_PWR_E); + + /* Configure input pin to detect overrcurrent errors */ + + gpio_outputhigh(LPC31_IOCONFIG_GPIO, GPIO_NOTG_OVRCR); + + /* Configure to receive interrupts on the overrcurrent input pin */ #warning Missing logic } @@ -256,12 +261,14 @@ void lpc31_usbhost_vbusdrive(int rhport, bool enable) if (enable) { /* Enable the Power Switch by driving the enable pin low */ -#warning Missing logic + + gpio_outputlow(LPC31_IOCONFIG_GPIO, GPIO_NOTG_PWR_E); } else { /* Disable the Power Switch by driving the enable pin high */ -#warning Missing logic + + gpio_outputhigh(LPC31_IOCONFIG_GPIO, GPIO_NOTG_PWR_E); } } } diff --git a/configs/olimex-lpc-h3131/src/lpc_h3131.h b/configs/olimex-lpc-h3131/src/lpc_h3131.h index 71805b6839..b6a86b7e16 100644 --- a/configs/olimex-lpc-h3131/src/lpc_h3131.h +++ b/configs/olimex-lpc-h3131/src/lpc_h3131.h @@ -61,6 +61,9 @@ * LED2 Green GPIO18 High output illuminates */ +#define GPIO_LED1 IOCONFIG_GPIO_GPIO17 +#define GPIO_LED2 IOCONFIG_GPIO_GPIO18 + /* USB HOST * * SIGNAL GPIO @@ -69,6 +72,9 @@ * #OTG_OVRCR GPIO20 */ +#define GPIO_NOTG_PWR_E IOCONFIG_GPIO_GPIO19 +#define GPIO_NOTG_OVRCR IOCONFIG_GPIO_GPIO20 + /* SPI Chip Selects */ /* SPI NOR flash is the only device on SPI. SPI_CS_OUT0 is its chip select */ @@ -151,6 +157,16 @@ void weak_function lpc31_usbhost_bootinitialize(void); int lpc31_usbhost_initialize(void); #endif +/**************************************************************************** + * Name: up_ledinit + * + * Description: + * Configure LEDs. LEDs are left in the OFF state. + * + ****************************************************************************/ + +void up_ledinit(void); + #endif /* __ASSEMBLY__ */ #endif /* __CONFIGS_OLIMEX_LPC_H3131_SRC_LPC_H3131_H */