Add support for M16C buttons and LEDs
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1519 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
1c7918916c
commit
37a6ef033a
@ -71,25 +71,6 @@
|
||||
|
||||
#define M16C_XIN_FREQ 20000000 /* 20MHz */
|
||||
|
||||
/* Switches */
|
||||
|
||||
#define S1 p8_3
|
||||
#define S2 p8_2
|
||||
#define S3 p8_1
|
||||
#define S1_DDR pd8_3
|
||||
#define S2_DDR pd8_2
|
||||
#define S3_DDR pd8_1
|
||||
|
||||
/* LEDs */
|
||||
|
||||
#define RED_LED p8_0
|
||||
#define YLW_LED p7_4
|
||||
#define GRN_LED p7_2
|
||||
|
||||
#define RED_DDR pd8_0 /* LED port direction register */
|
||||
#define YLW_DDR pd7_4
|
||||
#define GRN_DDR pd7_2
|
||||
|
||||
/* Interrupt Priority Levels ********************************************************/
|
||||
|
||||
/* IPL settings */
|
||||
@ -126,21 +107,29 @@
|
||||
#undef M16C_INT0_PRIO /* INT0 interrupt priority */
|
||||
#undef M16C_INT1_PRIO /* INT1 interrupt priority */
|
||||
|
||||
/********************************************************************************/
|
||||
/* Macro Definitions */
|
||||
/********************************************************************************/
|
||||
/* LED definitions **********************************************************/
|
||||
|
||||
#define LED_ON 0
|
||||
#define LED_OFF 1
|
||||
/* GREEN YELLOW RED */
|
||||
#define LED_STARTED 0 /* OFF OFF OFF */
|
||||
#define LED_HEAPALLOCATE 1 /* ON OFF OFF */
|
||||
#define LED_IRQSENABLED 2 /* OFF ON OFF */
|
||||
#define LED_STACKCREATED 3 /* ON ON OFF */
|
||||
#define LED_INIRQ 4 /* ON OFF ON */
|
||||
#define LED_SIGNAL 5 /* OFF ON ON */
|
||||
#define LED_ASSERTION 6 /* ON ON ON */
|
||||
#define LED_PANIC 7 /* NC** NC** ON* */
|
||||
|
||||
/* Use these macros for switch inputs */
|
||||
/* *=FLASHING **=if INIRQ, SIGNAL, or ASSERTION will be flashing */
|
||||
|
||||
#define ENABLE_SWITCHES {S1_DDR = 0; S2_DDR = 0; S3_DDR = 0;}
|
||||
/* BUTTON definitions **************************************************************/
|
||||
|
||||
/* Use these macros to control the LEDs */
|
||||
#define SW1_PRESSED 0x01 /* Bit 0: 1=SW1 pressed */
|
||||
#define SW2_PRESSED 0x02 /* Bit 1: 1=SW2 pressed */
|
||||
#define SW3_PRESSED 0x04 /* Bit 2: 1=SW3 pressed */
|
||||
|
||||
#define LED(led, state) ((led) = !state)
|
||||
#define ENABLE_LEDS {RED_LED = LED_OFF; YLW_LED = LED_OFF; GRN_LED = LED_OFF; RED_DDR = 1; YLW_DDR = 1; GRN_DDR = 1; }
|
||||
/************************************************************************************
|
||||
* Macro Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Inline Functions
|
||||
|
@ -60,6 +60,7 @@
|
||||
# used during interrupt handling.
|
||||
# CONFIG_ARCH_STACKDUMP - Do stack dumps after assertions
|
||||
# CONFIG_ARCH_LEDS - Use LEDs to show state. Unique to skp16c26.
|
||||
# CONFIG_ARCH_BUTTONS - Provide button APIs. Unique to skp16c26.
|
||||
# CONFIG_ARCH_LCD - Configure LCD. Unique to skp16c26.
|
||||
|
||||
CONFIG_ARCH=sh
|
||||
@ -76,7 +77,8 @@ CONFIG_DRAM_END=(CONFIG_DRAM_START+CONFIG_DRAM_SIZE)
|
||||
CONFIG_BOARD_LOOPSPERMSEC=16945
|
||||
CONFIG_ARCH_INTERRUPTSTACK=128
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_ARCH_LEDS=n
|
||||
CONFIG_ARCH_LEDS=y
|
||||
CONFIG_ARCH_BUTTONS=y
|
||||
CONFIG_ARCH_LCD=y
|
||||
|
||||
#
|
||||
|
@ -48,6 +48,14 @@
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* The SKP62C26 has 3 buttons control by bits 1, 2, and 3 in port 8. */
|
||||
|
||||
#define SW1_BIT (1 << 3) /* Bit 3, port 8 */
|
||||
#define SW2_BIT (1 << 2) /* Bit 2, port 8 */
|
||||
#define SW3_BIT (1 << 1) /* Bit 1, port 8 */
|
||||
|
||||
#define SW_PRESSED(p,b) (((p) & (b)) == 0)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@ -67,6 +75,11 @@
|
||||
#ifdef CONFIG_ARCH_BUTTONS
|
||||
void up_buttoninit(void)
|
||||
{
|
||||
ubyte regval;
|
||||
|
||||
regval = getreg8(M16C_PD8);
|
||||
regval |= (SW1_BIT | SW2_BIT | SW3_BIT);
|
||||
putreg8(regval, M16C_PD8);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -75,5 +88,24 @@ void up_buttoninit(void)
|
||||
|
||||
ubyte up_buttons(void)
|
||||
{
|
||||
ubyte swset = 0;
|
||||
ubyte regval = getreg8(M16C_P8);
|
||||
|
||||
if (SW_PRESSED(regval, SW1_BIT))
|
||||
{
|
||||
swset |= SW1_PRESSED;
|
||||
}
|
||||
|
||||
if (SW_PRESSED(regval, SW2_BIT))
|
||||
{
|
||||
swset |= SW2_PRESSED;
|
||||
}
|
||||
|
||||
if (SW_PRESSED(regval, SW3_BIT))
|
||||
{
|
||||
swset |= SW3_PRESSED;
|
||||
}
|
||||
|
||||
return swset;
|
||||
}
|
||||
#endif /* CONFIG_ARCH_BUTTONS */
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "up_internal.h"
|
||||
@ -50,24 +51,35 @@
|
||||
* Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/* LCD dimensions *******************************************************************/
|
||||
|
||||
#define LCD_NLINES 2 /* Two lines */
|
||||
#define LCD_NCHARS 8 /* Eight characters per line */
|
||||
|
||||
/* LCD commands *********************************************************************/
|
||||
|
||||
#define LCD_CLEAR 0x01 /* Clear LCD display and home cursor */
|
||||
#define LCD_HOME_L1 0x80 /* move cursor to line 1 */
|
||||
#define LCD_HOME_L2 0xc0 /* move cursor to line 2 */
|
||||
#define CURSOR_MODE_DEC 0x04 /* Cursor auto decrement after R/W */
|
||||
#define CURSOR_MODE_INC 0x06 /* Cursor auto increment after R/W */
|
||||
#define FUNCTION_SET 0x28 /* Setup, 4 bits,2 lines, 5X7 */
|
||||
#define LCD_CURSOR_ON 0x0e /* Display ON with Cursor */
|
||||
#define LCD_CURSOR_OFF 0x0c /* Display ON with Cursor off */
|
||||
#define LCD_CURSOR_BLINK 0x0d /* Display on with blinking cursor */
|
||||
#define LCD_CURSOR_LEFT 0x10 /* Move Cursor Left One Position */
|
||||
#define LCD_CURSOR_RIGHT 0x14 /* Move Cursor Right One Position */
|
||||
#define LCD_CLEAR 0x01 /* Clear LCD display and home cursor */
|
||||
#define CURSOR_MODE_DEC 0x04 /* Cursor auto decrement after R/W */
|
||||
#define CURSOR_MODE_INC 0x06 /* Cursor auto increment after R/W */
|
||||
#define LCD_CURSOR_ON 0x0e /* Display ON with Cursor */
|
||||
#define LCD_CURSOR_OFF 0x0c /* Display ON with Cursor off */
|
||||
#define LCD_CURSOR_BLINK 0x0d /* Display on with blinking cursor */
|
||||
#define LCD_CURSOR_LEFT 0x10 /* Move Cursor Left One Position */
|
||||
#define LCD_CURSOR_RIGHT 0x14 /* Move Cursor Right One Position */
|
||||
#define FUNCTION_SET 0x28 /* Setup, 4 bits,2 lines, 5X7 */
|
||||
#define LCD_CGRAM 0x40 /* Map characters to CG RAM */
|
||||
#define LCD_POS_L1(p) (0x80 | p) /* Move cursor to line 1, character p+1 */
|
||||
#define LCD_POS_L2(p) (0xc0 | p) /* Move cursor to line 2, character p+1 */
|
||||
#define LCD_HOME_L1 0x80 /* Move cursor to line 1 */
|
||||
#define LCD_HOME_L2 0xc0 /* Move cursor to line 2 */
|
||||
|
||||
/************************************************************************************
|
||||
* Private Data
|
||||
************************************************************************************/
|
||||
|
||||
static ubyte g_nchars; /* Number of characters in lines 2 */
|
||||
static ubyte g_line[LCD_NCHARS]; /* The content of lines 2 */
|
||||
|
||||
/************************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
@ -165,6 +177,32 @@ void up_lcdwrite(boolean data, ubyte ch)
|
||||
up_enpulse(data);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_scroll
|
||||
************************************************************************************/
|
||||
|
||||
static void up_scroll(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Clear the display and position the cursor at the beginning of line 1 */
|
||||
|
||||
up_lcdwrite(FALSE, LCD_CLEAR);
|
||||
up_lcdwrite(FALSE, LCD_HOME_L1);
|
||||
|
||||
/* Copy line 2 to line 1 */
|
||||
|
||||
for (i = 0; i < g_nchars; i++)
|
||||
{
|
||||
up_lcdwrite(TRUE, g_line[i]);
|
||||
}
|
||||
|
||||
/* Position the cursor at the beginning of line 2 */
|
||||
|
||||
up_lcdwrite(FALSE, LCD_HOME_L2);
|
||||
g_nchars = 0;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
@ -220,7 +258,23 @@ void up_lcdinit(void)
|
||||
|
||||
void up_lcdputc(char ch)
|
||||
{
|
||||
up_lcdwrite(TRUE, ch);
|
||||
/* Check for new line */
|
||||
|
||||
if (ch == '\n')
|
||||
{
|
||||
up_scroll();
|
||||
}
|
||||
|
||||
/* Should we wrap to truncate at the end of line??? Let's truncate. In either
|
||||
* case, let's ignore all other non-printable characters.
|
||||
*/
|
||||
|
||||
else if (g_nchars < LCD_NCHARS && isprint(ch))
|
||||
{
|
||||
up_lcdwrite(TRUE, ch);
|
||||
g_line[g_nchars] = ch;
|
||||
g_nchars++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ARCH_LCD */
|
||||
|
@ -39,20 +39,90 @@
|
||||
|
||||
#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
|
||||
|
||||
/************************************************************************************
|
||||
* Definitions
|
||||
* 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
|
||||
|
||||
/************************************************************************************
|
||||
* 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 */
|
||||
|
Loading…
Reference in New Issue
Block a user