summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-06-23 09:05:20 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-06-23 09:05:20 -0600
commitc82f81e5736e0c833e2c62603542e1cbbd83fed7 (patch)
tree6ffe5856e7cb323ef66000ea837d08801a6ff68f
parentbc275cdcafb407c3f95626e606e753872c25dbf1 (diff)
downloadnuttx-c82f81e5736e0c833e2c62603542e1cbbd83fed7.tar.gz
nuttx-c82f81e5736e0c833e2c62603542e1cbbd83fed7.tar.bz2
nuttx-c82f81e5736e0c833e2c62603542e1cbbd83fed7.zip
SAM4L Xplained SLCD driver is complete
-rw-r--r--nuttx/ChangeLog2
-rw-r--r--nuttx/arch/arm/src/sam34/chip/sam4l_lcdca.h8
-rw-r--r--nuttx/configs/sam4l-xplained/README.txt5
-rw-r--r--nuttx/configs/sam4l-xplained/src/sam_slcd.c194
-rw-r--r--nuttx/configs/stm32ldiscovery/src/stm32_lcd.c1
5 files changed, 152 insertions, 58 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 9693f75aa..03ba24550 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -5030,3 +5030,5 @@
in (2013-6-21).
* drivers/net/enc28j60.c: Change buffer ordering to work around Errata
#5. From Dave (ziggurat29, 2013-6-22).
+ * configs/sam4l-xplained/src/sam_slcd.c: LED1 segment LCD module is now
+ functional (2013-6-23).
diff --git a/nuttx/arch/arm/src/sam34/chip/sam4l_lcdca.h b/nuttx/arch/arm/src/sam34/chip/sam4l_lcdca.h
index 7e17ba347..7d179cb02 100644
--- a/nuttx/arch/arm/src/sam34/chip/sam4l_lcdca.h
+++ b/nuttx/arch/arm/src/sam34/chip/sam4l_lcdca.h
@@ -56,6 +56,9 @@
#define SAM_LCDCA_TIM_OFFSET 0x0008 /* Timing Register */
#define SAM_LCDCA_SR_OFFSET 0x000c /* Status Register */
#define SAM_LCDCA_SCR_OFFSET 0x0010 /* Status Clear Register */
+
+#define SAM_LCDCA_DRL_OFFSET(n) (0x0014+((n)<<3))
+#define SAM_LCDCA_DRH_OFFSET(n) (0x0018+((n)<<3))
#define SAM_LCDCA_DRL0_OFFSET 0x0014 /* Data Register Low 0 */
#define SAM_LCDCA_DRH0_OFFSET 0x0018 /* Data Register High 0 */
#define SAM_LCDCA_DRL1_OFFSET 0x001c /* Data Register Low 1 */
@@ -64,6 +67,7 @@
#define SAM_LCDCA_DRH2_OFFSET 0x0028 /* Data Register High 2 */
#define SAM_LCDCA_DRL3_OFFSET 0x002c /* Data Register Low 3 */
#define SAM_LCDCA_DRH3_OFFSET 0x0030 /* Data Register High 3 */
+
#define SAM_LCDCA_IADR_OFFSET 0x0034 /* Indirect Access Data Register */
#define SAM_LCDCA_BCFG_OFFSET 0x0038 /* Blink Configuration Register */
#define SAM_LCDCA_CSRCFG_OFFSET 0x003c /* Circular Shift Register Configuration */
@@ -85,6 +89,9 @@
#define SAM_LCDCA_TIM (SAM_LCDCA_BASE+SAM_LCDCA_TIM_OFFSET)
#define SAM_LCDCA_SR (SAM_LCDCA_BASE+SAM_LCDCA_SR_OFFSET)
#define SAM_LCDCA_SCR (SAM_LCDCA_BASE+SAM_LCDCA_SCR_OFFSET)
+
+#define SAM_LCDCA_DRL(n) (SAM_LCDCA_BASE+SAM_LCDCA_DRL_OFFSET(n))
+#define SAM_LCDCA_DRH(n) (SAM_LCDCA_BASE+SAM_LCDCA_DRH_OFFSET(n))
#define SAM_LCDCA_DRL0 (SAM_LCDCA_BASE+SAM_LCDCA_DRL0_OFFSET)
#define SAM_LCDCA_DRH0 (SAM_LCDCA_BASE+SAM_LCDCA_DRH0_OFFSET)
#define SAM_LCDCA_DRL1 (SAM_LCDCA_BASE+SAM_LCDCA_DRL1_OFFSET)
@@ -93,6 +100,7 @@
#define SAM_LCDCA_DRH2 (SAM_LCDCA_BASE+SAM_LCDCA_DRH2_OFFSET)
#define SAM_LCDCA_DRL3 (SAM_LCDCA_BASE+SAM_LCDCA_DRL3_OFFSET)
#define SAM_LCDCA_DRH3 (SAM_LCDCA_BASE+SAM_LCDCA_DRH3_OFFSET)
+
#define SAM_LCDCA_IADR (SAM_LCDCA_BASE+SAM_LCDCA_IADR_OFFSET)
#define SAM_LCDCA_BCFG (SAM_LCDCA_BASE+SAM_LCDCA_BCFG_OFFSET)
#define SAM_LCDCA_CSRCFG (SAM_LCDCA_BASE+SAM_LCDCA_CSRCFG_OFFSET)
diff --git a/nuttx/configs/sam4l-xplained/README.txt b/nuttx/configs/sam4l-xplained/README.txt
index dfdd362a1..17971ba4d 100644
--- a/nuttx/configs/sam4l-xplained/README.txt
+++ b/nuttx/configs/sam4l-xplained/README.txt
@@ -755,7 +755,7 @@ Configuration sub-directories
This is a test
nsh>
- 1. If the LCD1 module is connected to the SAM4L Xplained Pro, then
+ 2. If the LCD1 module is connected to the SAM4L Xplained Pro, then
support for the SLCDt can be enabled by making the following
changes to the configuration:
@@ -784,3 +784,6 @@ Configuration sub-directories
Application Configuration -> NSH Library
CONFIG_NSH_ARCHINIT=y
+
+ NOTE: In order to use the segment LCD you *must* open the VLCD_A and
+ VLCD_BC jumpers or the SLD will not be powered!
diff --git a/nuttx/configs/sam4l-xplained/src/sam_slcd.c b/nuttx/configs/sam4l-xplained/src/sam_slcd.c
index f0acba70a..898c7e883 100644
--- a/nuttx/configs/sam4l-xplained/src/sam_slcd.c
+++ b/nuttx/configs/sam4l-xplained/src/sam_slcd.c
@@ -115,6 +115,7 @@
#define SLCD_NROWS 1
#define SLCD_NCHARS 5
+#define SLCD_NBARS 4
#define SLCD_MAXCONTRAST 63
#define BOARD_SLCD_NCOM 4
@@ -216,6 +217,37 @@
#define SLCD_NG 8 /* Number of 'G' segments G0-G7 */
#define SLCD_NE 8 /* Number of 'E' segments G0-G7 */
+/* Named pixels */
+
+#define SLCD_MINUS (&g_binfo[0])
+#define SLCD_H (&g_binfo[1])
+#define SLCD_M (&g_binfo[2])
+#define SLCD_DP0 (&g_binfo[3])
+#define SLCD_DP1 (&g_binfo[4])
+#define SLCD_DP2 (&g_binfo[5])
+#define SLCD_DP3 (&g_binfo[6])
+#define SLCD_DP4 (&g_binfo[7])
+#define SLCD_CENTIGRADE (&g_binfo[8])
+#define SLCD_FAHRENHEIT (&g_binfo[9])
+
+#define SLCD_ATMEL (&g_ginfo[0])
+#define SLCD_BAR0 (&g_ginfo[1])
+#define SLCD_BAR1 (&g_ginfo[2])
+#define SLCD_BAR2 (&g_ginfo[3])
+#define SLCD_BAR3 (&g_ginfo[4])
+#define SLCD_COLON (&g_ginfo[5])
+#define SLCD_USB (&g_ginfo[6])
+#define SLCD_PAY (&g_ginfo[7])
+
+#define SLCD_RNG0 (&g_einfo[0])
+#define SLCD_RNG1 (&g_einfo[1])
+#define SLCD_RNG2 (&g_einfo[2])
+#define SLCD_RNG3 (&g_einfo[3])
+#define SLCD_MV (&g_einfo[4])
+#define SLCD_V (&g_einfo[5])
+#define SLCD_PM (&g_einfo[6])
+#define SLCD_AM (&g_einfo[7])
+
/* Debug ********************************************************************/
#ifdef CONFIG_DEBUG_LCD
@@ -276,17 +308,13 @@ static void slcd_dumpslcd(FAR const char *msg);
static void slcd_clear(void);
#endif
static void slcd_setpixel(FAR const struct slcd_pixel_s *info);
-#if 0 /* Not used */
static void slcd_clrpixel(FAR const struct slcd_pixel_s *info);
-#endif
-static void slcd_setdp(uint8_t curpos);
-#if 0 /* Not used */
-static void slcd_clrdp(uint8_t curpos);
-#endif
+static inline void slcd_setdp(uint8_t curpos);
+static inline void slcd_clrdp(uint8_t curpos);
static int slcd_getstream(FAR struct lib_instream_s *instream);
static uint8_t slcd_getcontrast(void);
static int slcd_setcontrast(unsigned int contrast);
-static void slcd_writech(uint8_t ch, uint8_t curpos);
+static void slcd_writech(uint8_t ch, uint8_t curpos, uint8_t options);
static void slcd_action(enum slcdcode_e code, uint8_t count);
/* Character driver methods */
@@ -403,12 +431,12 @@ static void slcd_dumpslcd(FAR const char *msg)
lcdvdbg(" CFG: %08x TIM: %08x SR: %08x\n",
getreg32(SAM_LCDCA_CFG), getreg32(SAM_LCDCA_TIM),
getreg32(SAM_LCDCA_SR));
- lcdvdbg(" DR0: %08x %08x DR1: %08x %08x\n",
- getreg32(SAM_LCDCA_DRL0), getreg32(SAM_LCDCA_DRH0),
- getreg32(SAM_LCDCA_DRL1), getreg32(SAM_LCDCA_DRH1));
- lcdvdbg(" DR2: %08x %08x DR3: %08x %08x\n",
- getreg32(SAM_LCDCA_DRL2), getreg32(SAM_LCDCA_DRH2),
- getreg32(SAM_LCDCA_DRL3), getreg32(SAM_LCDCA_DRH3));
+ lcdvdbg(" DR0: %02x %08x DR1: %02x %08x\n",
+ getreg32(SAM_LCDCA_DRH0), getreg32(SAM_LCDCA_DRL0),
+ getreg32(SAM_LCDCA_DRH1), getreg32(SAM_LCDCA_DRL1));
+ lcdvdbg(" DR2: %02x %08x DR3: %02x %08x\n",
+ getreg32(SAM_LCDCA_DRH2), getreg32(SAM_LCDCA_DRL2),
+ getreg32(SAM_LCDCA_DRH3), getreg32(SAM_LCDCA_DRL3));
lcdvdbg(" BCFG: %08x CSRCFG: %08x CMCFG: %08x ACMCFG: %08x\n",
getreg32(SAM_LCDCA_BCFG), getreg32(SAM_LCDCA_CSRCFG),
getreg32(SAM_LCDCA_CMCFG), getreg32(SAM_LCDCA_ACMCFG));
@@ -442,7 +470,7 @@ static void slcd_setpixel(FAR const struct slcd_pixel_s *info)
uintptr_t regaddr;
uint32_t regval;
- regaddr = info->com ? SAM_LCDCA_DRL0 : SAM_LCDCA_DRL3;
+ regaddr = SAM_LCDCA_DRL(info->com);
regval = getreg32(regaddr);
regval |= (1 << info->segment);
putreg32(regval, regaddr);
@@ -452,24 +480,22 @@ static void slcd_setpixel(FAR const struct slcd_pixel_s *info)
* Name: slcd_clrpixel
****************************************************************************/
-#if 0 /* Not used */
static void slcd_clrpixel(FAR const struct slcd_pixel_s *info)
{
uintptr_t regaddr;
uint32_t regval;
- regaddr = info->com ? SAM_LCDCA_DRL0 : SAM_LCDCA_DRL3;
+ regaddr = SAM_LCDCA_DRL(info->com);
regval = getreg32(regaddr);
regval &= ~(1 << info->segment);
putreg32(regval, regaddr);
}
-#endif
/****************************************************************************
* Name: slcd_setdp
****************************************************************************/
-static void slcd_setdp(uint8_t curpos)
+static inline void slcd_setdp(uint8_t curpos)
{
/* Set the decimal point before the current cursor position
*
@@ -478,15 +504,13 @@ static void slcd_setdp(uint8_t curpos)
*/
slcd_setpixel(&g_binfo[curpos + 3]);
- g_slcdstate.options[curpos] |= SLCD_DP;
}
/****************************************************************************
* Name: slcd_clrdp
****************************************************************************/
-#if 0 /* Not used */
-static void slcd_clrdp(uint8_t curpos)
+static inline void slcd_clrdp(uint8_t curpos)
{
/* Set the decimal point before the current cursor position
*
@@ -495,9 +519,7 @@ static void slcd_clrdp(uint8_t curpos)
*/
slcd_clrpixel(&g_binfo[curpos + 3]);
- g_slcdstate.options[curpos] &= ~SLCD_DP;
}
-#endif
/****************************************************************************
* Name: slcd_getstream
@@ -597,7 +619,7 @@ static int slcd_setcontrast(unsigned int contrast)
* Name: slcd_writech
****************************************************************************/
-static void slcd_writech(uint8_t ch, uint8_t curpos)
+static void slcd_writech(uint8_t ch, uint8_t curpos, uint8_t options)
{
uint8_t segment;
@@ -620,9 +642,21 @@ static void slcd_writech(uint8_t ch, uint8_t curpos)
putreg32(LCDCA_CMCFG_TDG_14S4C | LCDCA_CMCFG_STSEG(segment), SAM_LCDCA_CMCFG);
putreg32(ch, SAM_LCDCA_CMDR);
+ /* Check if we need to decorate the character with a preceding dot. */
+
+ if ((options & SLCD_DP) != 0)
+ {
+ slcd_setdp(curpos);
+ }
+ else
+ {
+ slcd_clrdp(curpos);
+ }
+
/* Save these values in the state structure */
g_slcdstate.buffer[curpos] = ch;
+ g_slcdstate.options[curpos] = options;
slcd_dumpstate("AFTER WRITE");
}
@@ -681,18 +715,21 @@ static void slcd_action(enum slcdcode_e code, uint8_t count)
nchars = SLCD_NCHARS - g_slcdstate.curpos;
nmove = MIN(nchars, count) - 1;
- /* Move all characters after the current cursor position left by 'nmove' characters */
+ /* Move all characters after the current cursor position left by
+ * 'nmove' characters
+ */
for (i = g_slcdstate.curpos + nmove; i < SLCD_NCHARS - 1; i++)
{
- slcd_writech(g_slcdstate.buffer[i-nmove], i);
+ slcd_writech(g_slcdstate.buffer[i-nmove], i,
+ g_slcdstate.options[i-nmove]);
}
/* Erase the last 'nmove' characters on the display */
for (i = SLCD_NCHARS - nmove; i < SLCD_NCHARS; i++)
{
- slcd_writech(' ', i);
+ slcd_writech(' ', i, 0);
}
}
break;
@@ -717,7 +754,7 @@ static void slcd_action(enum slcdcode_e code, uint8_t count)
for (i = g_slcdstate.curpos; i < last; i++)
{
- slcd_writech(' ', i);
+ slcd_writech(' ', i, 0);
}
}
break;
@@ -739,7 +776,7 @@ static void slcd_action(enum slcdcode_e code, uint8_t count)
for (i = g_slcdstate.curpos; i < SLCD_NCHARS; i++)
{
- slcd_writech(' ', i);
+ slcd_writech(' ', i, 0);
}
}
break;
@@ -861,9 +898,9 @@ static ssize_t slcd_write(FAR struct file *filp,
struct slcd_instream_s instream;
struct slcdstate_s state;
enum slcdret_e result;
- bool dotneeded;
uint8_t ch;
uint8_t count;
+ uint8_t options;
/* Initialize the stream for use with the SLCD CODEC */
@@ -872,9 +909,13 @@ static ssize_t slcd_write(FAR struct file *filp,
instream.buffer = buffer;
instream.nbytes = len;
+ /* Initialize the SLCD decode state buffer */
+
+ memset(&state, 0, sizeof(struct slcdstate_s));
+
/* Decode and process every byte in the input buffer */
- dotneeded = false;
+ options = 0;
while ((result = slcd_decode(&instream.stream, &state, &ch, &count)) != SLCDRET_EOF)
{
lcdvdbg("slcd_decode returned result=%d char=%d count=%d\n",
@@ -903,7 +944,7 @@ static ssize_t slcd_write(FAR struct file *filp,
/* Ignore dots before control characters (all of them?) */
- dotneeded = false;
+ options = 0;
}
/* Handle characters decoreated with a preceding period */
@@ -912,7 +953,7 @@ static ssize_t slcd_write(FAR struct file *filp,
{
/* The next character will need a dot in front of it */
- dotneeded = true;
+ options |= SLCD_DP;
}
/* Handle ASCII_DEL */
@@ -922,27 +963,19 @@ static ssize_t slcd_write(FAR struct file *filp,
/* Perform the foward deletion */
slcd_action(SLCDCODE_FWDDEL, 1);
- dotneeded = false;
+ options = 0;
}
/* The rest of the 7-bit ASCII characters are fair game */
else if (ch < 128)
{
- lcdvdbg("ch: %c[%02x]\n", ch, ch);
+ lcdvdbg("ch: %c[%02x] options: %02x\n", ch, ch, options);
/* Write the character at the current cursor position */
- slcd_writech(ch, g_slcdstate.curpos);
-
- /* Check if we need to decorate the character with a preceding
- * dot.
- */
-
- if (dotneeded)
- {
- slcd_setdp(g_slcdstate.curpos);
- }
+ slcd_writech(ch, g_slcdstate.curpos, options);
+ options = 0;
/* And advance the cursor position */
@@ -997,7 +1030,7 @@ static int slcd_ioctl(FAR struct file *filp, int cmd, unsigned long arg)
attr->nrows = SLCD_NROWS;
attr->ncolumns = SLCD_NCHARS;
- attr->nbars = 0;
+ attr->nbars = SLCD_NBARS;
attr->maxcontrast = SLCD_MAXCONTRAST;
attr->maxbrightness = 0;
}
@@ -1009,7 +1042,6 @@ static int slcd_ioctl(FAR struct file *filp, int cmd, unsigned long arg)
* returned
*/
-
case SLCDIOC_CURPOS:
{
FAR struct slcd_curpos_s *curpos = (FAR struct slcd_curpos_s *)((uintptr_t)arg);
@@ -1026,6 +1058,53 @@ static int slcd_ioctl(FAR struct file *filp, int cmd, unsigned long arg)
}
break;
+ /* SLCDIOC_SETBAR: Set bars on a bar display
+ *
+ * argument: 32-bit bitset, with each bit corresponding to one bar.
+ */
+
+ case SLCDIOC_SETBAR:
+ {
+ lcdvdbg("SLCDIOC_SETBAR: arg=0x%02lx\n", arg);
+
+ if ((arg & 1) != 0)
+ {
+ slcd_setpixel(SLCD_RNG0);
+ }
+ else
+ {
+ slcd_clrpixel(SLCD_RNG0);
+ }
+
+ if ((arg & 2) != 0)
+ {
+ slcd_setpixel(SLCD_RNG1);
+ }
+ else
+ {
+ slcd_clrpixel(SLCD_RNG1);
+ }
+
+ if ((arg & 4) != 0)
+ {
+ slcd_setpixel(SLCD_RNG2);
+ }
+ else
+ {
+ slcd_clrpixel(SLCD_RNG2);
+ }
+
+ if ((arg & 8) != 0)
+ {
+ slcd_clrpixel(SLCD_RNG3);
+ }
+ else
+ {
+ slcd_setpixel(SLCD_RNG3);
+ }
+ }
+ break;
+
/* SLCDIOC_GETCONTRAST: Get the current contrast setting
*
* argument: Pointer type int that will receive the current contrast
@@ -1063,7 +1142,6 @@ static int slcd_ioctl(FAR struct file *filp, int cmd, unsigned long arg)
}
break;
- case SLCDIOC_SETBAR: /* Get bar levels */
case SLCDIOC_GETBRIGHTNESS: /* Get the current brightness setting */
case SLCDIOC_SETBRIGHTNESS: /* Set the brightness to a new value */
default:
@@ -1219,14 +1297,18 @@ int sam_slcd_initialize(void)
/* Initialize display memory */
- putreg32(LCDCA_DRL_MASK, SAM_LCDCA_DRL0);
- putreg32(LCDCA_DRH_MASK, SAM_LCDCA_DRH0);
- putreg32(LCDCA_DRL_MASK, SAM_LCDCA_DRL1);
- putreg32(LCDCA_DRH_MASK, SAM_LCDCA_DRH1);
- putreg32(LCDCA_DRL_MASK, SAM_LCDCA_DRL2);
- putreg32(LCDCA_DRH_MASK, SAM_LCDCA_DRH2);
- putreg32(LCDCA_DRL_MASK, SAM_LCDCA_DRL3);
- putreg32(LCDCA_DRH_MASK, SAM_LCDCA_DRH3);
+ putreg32(0, SAM_LCDCA_DRL0);
+ putreg32(0, SAM_LCDCA_DRH0);
+ putreg32(0, SAM_LCDCA_DRL1);
+ putreg32(0, SAM_LCDCA_DRH1);
+ putreg32(0, SAM_LCDCA_DRL2);
+ putreg32(0, SAM_LCDCA_DRH2);
+ putreg32(0, SAM_LCDCA_DRL3);
+ putreg32(0, SAM_LCDCA_DRH3);
+
+ /* Turn on the Atmel pixel */
+
+ slcd_setpixel(SLCD_ATMEL);
/* Register the LCD device driver */
diff --git a/nuttx/configs/stm32ldiscovery/src/stm32_lcd.c b/nuttx/configs/stm32ldiscovery/src/stm32_lcd.c
index 1dc9e25d2..c74836959 100644
--- a/nuttx/configs/stm32ldiscovery/src/stm32_lcd.c
+++ b/nuttx/configs/stm32ldiscovery/src/stm32_lcd.c
@@ -1350,7 +1350,6 @@ static int slcd_ioctl(FAR struct file *filp, int cmd, unsigned long arg)
* returned
*/
-
case SLCDIOC_CURPOS:
{
FAR struct slcd_curpos_s *curpos = (FAR struct slcd_curpos_s *)((uintptr_t)arg);