summaryrefslogtreecommitdiff
path: root/nuttx/configs/skp16c26/src/up_leds.c
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/configs/skp16c26/src/up_leds.c')
-rw-r--r--nuttx/configs/skp16c26/src/up_leds.c167
1 files changed, 164 insertions, 3 deletions
diff --git a/nuttx/configs/skp16c26/src/up_leds.c b/nuttx/configs/skp16c26/src/up_leds.c
index a34b47756..a65d423a9 100644
--- a/nuttx/configs/skp16c26/src/up_leds.c
+++ b/nuttx/configs/skp16c26/src/up_leds.c
@@ -39,21 +39,91 @@
#include <nuttx/config.h>
#include <sys/types.h>
+
+#include <arch/board/board.h>
+#include "up_arch.h"
#include "up_internal.h"
+#include "chip.h"
+
+#ifdef CONFIG_ARCH_LEDS
+
+/************************************************************************************
+ * Preprocessor Definitions
+ ************************************************************************************/
+
+/* The SKP62C26 has 3 LEDs control by bits 0 and 2 in port 7 and bit 0 in port 8. */
+
+#define GREEN_LED (1 << 2) /* Bit 2, port 7 */
+#define YELLOW_LED (1 << 4) /* Bit 4, port 7 */
+#define RED_LED (1 << 0) /* Bit 0, port 8 */
+
+#define GREEN_LED_ON 0
+#define GREEN_LED_OFF GREEN_LED
+#define GREEN_LED_MASK GREEN_LED
+#define GREEN_LED_PORT M16C_P7
+
+#define YELLOW_LED_ON 0
+#define YELLOW_LED_OFF YELLOW_LED
+#define YELLOW_LED_MASK YELLOW_LED
+#define YELLOW_LED_PORT M16C_P7
+
+#define GREENYELLOW_LED_MASK (GREEN_LED_MASK|YELLOW_LED_MASK)
+#define GREENYELLOW_LED_PORT M16C_P7
+#define GREENYELLOW_DIR_PORT M16C_PD7
+
+#define RED_LED_ON 0
+#define RED_LED_OFF RED_LED
+#define RED_LED_MASK RED_LED
+#define RED_LED_PORT M16C_P8
+#define RED_DIR_PORT M16C_PD8
/************************************************************************************
- * Definitions
+ * Private Type Definitions
************************************************************************************/
/************************************************************************************
- * Private Data
+ * Private Data Definitions
************************************************************************************/
+static const ubyte g_ledstate[7] =
+{
+ (GREEN_LED_OFF | YELLOW_LED_OFF | RED_LED_OFF), /* LED_STARTED */
+ (GREEN_LED_ON | YELLOW_LED_OFF | RED_LED_OFF), /* LED_HEAPALLOCATE */
+ (GREEN_LED_OFF | YELLOW_LED_ON | RED_LED_OFF), /* LED_IRQSENABLED */
+ (GREEN_LED_ON | YELLOW_LED_ON | RED_LED_OFF), /* LED_STACKCREATED */
+
+ (GREEN_LED_ON | YELLOW_LED_OFF | RED_LED_ON ), /* LED_INIRQ */
+ (GREEN_LED_OFF | YELLOW_LED_ON | RED_LED_ON ), /* LED_SIGNAL */
+ (GREEN_LED_ON | YELLOW_LED_ON | RED_LED_ON ) /* LED_ASSERTION */
+};
+
+static ubyte g_prevled[3];
+static ubyte g_nestlevel;
+
/************************************************************************************
* Private Functions
************************************************************************************/
/************************************************************************************
+ * Name: up_ledinit
+ ************************************************************************************/
+
+static void up_setleds(ubyte gybits, ubyte rbit)
+{
+ ubyte regval;
+
+ regval = getreg8(GREENYELLOW_LED_PORT);
+ regval &= ~GREENYELLOW_LED_MASK;
+ regval |= gybits;
+ putreg8(regval, GREENYELLOW_LED_PORT);
+
+ regval = getreg8(RED_LED_PORT);
+ regval &= ~RED_LED_MASK;
+ regval |= rbit;
+ putreg8(regval, RED_LED_PORT);
+}
+
+/************************************************************************************
* Public Functions
************************************************************************************/
@@ -61,9 +131,29 @@
* Name: up_ledinit
************************************************************************************/
-#ifdef CONFIG_ARCH_LEDS
void up_ledinit(void)
{
+ register ubyte regval;
+
+ /* Make sure that the LEDs are in the OFF state */
+
+ regval = getreg8(GREENYELLOW_LED_PORT);
+ regval |= (GREEN_LED_OFF |YELLOW_LED_OFF);
+ putreg8(regval, GREENYELLOW_LED_PORT);
+
+ regval = getreg8(RED_LED_PORT);
+ regval |= RED_LED_OFF;
+ putreg8(regval, RED_LED_PORT);
+
+ /* Set the direction to output */
+
+ regval = getreg8(GREENYELLOW_DIR_PORT);
+ regval |= (GREEN_LED |YELLOW_LED);
+ putreg8(regval, GREENYELLOW_DIR_PORT);
+
+ regval = getreg8(RED_DIR_PORT);
+ regval |= RED_LED;
+ putreg8(regval, RED_DIR_PORT);
}
/************************************************************************************
@@ -72,6 +162,34 @@ void up_ledinit(void)
void up_ledon(int led)
{
+ ubyte ledset;
+
+ /* If this is the ASSERTION led, preserve the Y&G bits from the last setting and
+ * set the RED LED on.
+ */
+
+ if (led == LED_ASSERTION)
+ {
+ ledset = g_ledstate[g_prevled[g_nestlevel]];
+ up_setleds(ledset & GREENYELLOW_LED_MASK, RED_LED_ON);
+ }
+ else if (led < LED_ASSERTION)
+ {
+ /* Otherwise, just show the LEDs corresponding to this state */
+
+ ledset = g_ledstate[led];
+ up_setleds(ledset & GREENYELLOW_LED_MASK, ledset & RED_LED_MASK);
+
+ /* If this was a nested states (INIRQ, SIGNAL, or ASSERTION) then
+ * stack up the previous value.
+ */
+
+ if (led > LED_STACKCREATED)
+ {
+ g_nestlevel++;
+ }
+ g_prevled[g_nestlevel] = led;
+ }
}
/************************************************************************************
@@ -80,5 +198,48 @@ void up_ledon(int led)
void up_ledoff(int led)
{
+ ubyte ledset;
+
+ /* If this is the ASSERTION led then what we do depends on the previous state */
+
+ if (led == LED_ASSERTION)
+ {
+ /* If the previous state was one of the nested states (INIRQ, SIGNAL, or ASSERTION),
+ * then turn the green and yellow LEDs all off. That way we can distinguish
+ * that case from the simple cases.
+ */
+
+ if (g_nestlevel > 0)
+ {
+ ledset = 0;
+ }
+ else
+ {
+ ledset = g_ledstate[g_prevled[0]];
+ }
+ up_setleds(ledset & GREENYELLOW_LED_MASK, RED_LED_OFF);
+ }
+ else if (led > 0 && led < LED_ASSERTION)
+ {
+ /* If this was one of the nested states, then we want to back to the LED setting
+ * before entering that nested statel.
+ */
+
+ if (g_nestlevel > 0)
+ {
+ g_nestlevel--;
+ led = g_prevled[g_nestlevel];
+ }
+ else if (led > LED_STACKCREATED)
+ {
+ /* This shouldn't happen */
+
+ led--;
+ }
+ ledset = g_ledstate[led];
+ up_setleds(ledset & GREENYELLOW_LED_MASK, ledset & RED_LED_MASK);
+ g_prevled[g_nestlevel]= led;
+ }
}
+
#endif /* CONFIG_ARCH_LEDS */