Beispiel #1
0
static void lcd_writech(uint8_t ch, uint8_t row, uint8_t column)
{
  uint8_t addr;

  /* Set the cursor position.  Internally, the HD44780U supports a display
   * size of up to 2x40 addressed as follows:
   *
   * Column  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 ... 39
   * Row 0  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ... 27
   * Ro1 1  40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f ... 67
  */

  addr = column;
  if (row > 0)
    {
      addr |= HD4478OU_DDRAM_ROW1;
    }

  lcd_wrcommand(HD4478OU_DDRAM_AD(addr));

  /* And write the character here */

  lcd_wrdata(ch);
}
Beispiel #2
0
int up_lcd1602_initialize(void)
{
  uint32_t regval;
  int ret = OK;

  /* Only initialize the driver once. */

  if (!g_lcd1602.initialized)
    {
      lcdvdbg("Initializing\n");

      /* PMP Master mode configuration */
      /* Make sure that interrupts are disabled */

      putreg32(INT_PMP, PIC32MX_INT_IEC1CLR);

      /* Stop and reset the PMP module and clear the mode and control registers. */

      putreg32(0, PIC32MX_PMP_MODE);
      putreg32(0, PIC32MX_PMP_AEN);
      putreg32(0, PIC32MX_PMP_CON);
      putreg32(0, PIC32MX_PMP_ADDR);

      /* Set LCD timing values, PMP master mode 3, 8-bit mode, no address
       * increment, and no interrupts.
       */

      regval = (PMP_MODE_WAITE_RD(0) | PMP_MODE_WAITM(3) | PMP_MODE_WAITB_1TPB |
                PMP_MODE_MODE_MODE1 | PMP_MODE_MODE8 | PMP_MODE_INCM_NONE |
                PMP_MODE_IRQM_NONE);
      putreg32(regval, PIC32MX_PMP_MODE);

      /* Enable the PMP for reading and writing
       *   PMRD/PMWR is active high (1=RD; 0=WR)
       *   PMENB is active high.
       *   No chip selects
       *   Address latch is active high
       *   Enable PMRD/PMWR, PMENB, and the PMP.
       */


      regval = (PMP_CON_RDSP | PMP_CON_WRSP | PMP_CON_ALP |
                PMP_CON_CSF_ADDR1415 | PMP_CON_PTRDEN | PMP_CON_PTWREN |
                PMP_CON_ADRMUX_NONE | PMP_CON_ON);
      putreg32(regval, PIC32MX_PMP_CON);

      /* Configure and enable the LCD */
      /* Wait > 15 milliseconds afer Vdd > 4.5V */

      up_mdelay(100);

      /* Select the 8-bit interface. BF cannot be checked before this command.
       * This needs to be done a few times with some magic delays.
       */

      lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_DL8D | HD4478OU_FUNC_N1);
      up_mdelay(50);
      lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_DL8D | HD4478OU_FUNC_N1);
      up_udelay(50);
      lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_DL8D | HD4478OU_FUNC_N1);
      lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_DL8D | HD4478OU_FUNC_N1);

      /* Configure the display */

      lcd_wrcommand(HD4478OU_DISPLAY);                       /* Display, cursor, and blink off */
      lcd_wrcommand(HD4478OU_CLEAR);                         /* Clear the display */
      lcd_wrcommand(HD4478OU_INPUT | HD4478OU_INPUT_INCR);   /* Increment mode */
      lcd_wrcommand(HD4478OU_DISPLAY | HD4478OU_DISPLAY_ON); /* Display on, cursor and blink off */
      lcd_wrcommand(HD4478OU_DDRAM_AD(0));                   /* Select DDRAM RAM AD=0 */

      /* Register the LCD device driver */

      ret = register_driver("/dev/lcd1602", &g_lcdops, 0644, &g_lcd1602);
      g_lcd1602.initialized = true;
    }

  return ret;
}
Beispiel #3
0
static void lcd_action(enum slcdcode_e code, uint8_t count)
{
  lcdvdbg("Action: %d count: %d\n", code, count);
  lcd_dumpstate("BEFORE ACTION");

  switch (code)
    {
      /* Erasure */

      case SLCDCODE_BACKDEL:         /* Backspace (backward delete) N characters */
        {
          int tmp;

          /* If we are at the home position or if the count is zero, then ignore the action */

          if (g_lcd1602.curcol < 1 || count < 1)
            {
              break;
            }

          /* Otherwise, BACKDEL is like moving the cursor back N characters then doing a
           * forward deletion.  Decrement the cursor position and fall through.
           */

           tmp = (int)g_lcd1602.curcol - count;
           if (tmp < 0)
             {
               tmp   = 0;
               count = g_lcd1602.curcol;
             }

           /* Save the updated cursor positions */

           g_lcd1602.curcol = tmp;
         }

      case SLCDCODE_FWDDEL:          /* DELete (forward delete) N characters moving text */
        if (count > 0)
          {
            int nchars;
            int nmove;
            int i;

            /* How many characters are to the right of the cursor position
             * (including the one at the cursor position)?  Then get the
             * number of characters to move.
             */

            nchars = LCD_NCOLUMNS - g_lcd1602.curcol;
            nmove  = MIN(nchars, count) - 1;

            /* Move all characters after the current cursor position left by 'nmove' characters */

            for (i = g_lcd1602.curcol + nmove; i < LCD_NCOLUMNS - 1; i++)
              {
                uint8_t ch = lcd_readch(g_lcd1602.currow, i);
                lcd_writech(ch, g_lcd1602.currow, i - nmove);
              }

            /* Erase the last 'nmove' characters on the display */

            for (i = LCD_NCOLUMNS - nmove; i < LCD_NCOLUMNS; i++)
              {
                lcd_writech(' ', i, 0);
              }
          }
        break;

      case SLCDCODE_ERASE:           /* Erase N characters from the cursor position */
        if (count > 0)
          {
            int last;
            int i;

            /* Get the last position to clear and make sure that the last
             * position is on the SLCD.
             */

            last = g_lcd1602.curcol + count - 1;
            if (last >= LCD_NCOLUMNS)
              {
                last = LCD_NCOLUMNS - 1;
              }

            /* Erase N characters after the current cursor position left by one */

            for (i = g_lcd1602.curcol; i < last; i++)
              {
                lcd_writech(' ', g_lcd1602.currow, i);
              }
          }
        break;

      case SLCDCODE_CLEAR:           /* Home the cursor and erase the entire display */
        {
          /* Clear the display */

          lcd_wrcommand(HD4478OU_CLEAR);

          /* And home the cursor */

          g_lcd1602.currow = 0;
          g_lcd1602.curcol = 0;
        }
        break;

      case SLCDCODE_ERASEEOL:        /* Erase from the cursor position to the end of line */
        {
          int i;

          /* Erase characters after the current cursor position to the end of the line */

          for (i = g_lcd1602.curcol; i < LCD_NCOLUMNS; i++)
            {
              lcd_writech(' ', g_lcd1602.currow, i);
            }
        }
        break;

      /* Cursor movement */

      case SLCDCODE_HOME:            /* Cursor home */
        {
          g_lcd1602.currow = 0;
          g_lcd1602.curcol = 0;
        }
        break;

      case SLCDCODE_END:             /* Cursor end */
        {
          g_lcd1602.curcol = LCD_NCOLUMNS - 1;
        }
        break;

      case SLCDCODE_LEFT:            /* Cursor left by N characters */
        {
          int tmp = (int)g_lcd1602.curcol - count;

          /* Don't permit movement past the beginning of the SLCD */

          if (tmp < 0)
            {
              tmp = 0;
            }

          /* Save the new cursor position */

          g_lcd1602.curcol = (uint8_t)tmp;
        }
        break;

      case SLCDCODE_RIGHT:           /* Cursor right by N characters */
        {
          int tmp = (int)g_lcd1602.curcol + count;

          /* Don't permit movement past the end of the SLCD */

          if (tmp >= LCD_NCOLUMNS)
            {
              tmp = LCD_NCOLUMNS - 1;
            }

          /* Save the new cursor position */

          g_lcd1602.curcol = (uint8_t)tmp;
        }
        break;

      case SLCDCODE_UP:              /* Cursor up by N lines */
        {
          int tmp = (int)g_lcd1602.currow - count;

          /* Don't permit movement past the top of the SLCD */

          if (tmp < 0)
            {
              tmp = 0;
            }

          /* Save the new cursor position */

          g_lcd1602.currow = (uint8_t)tmp;
        }
        break;

      case SLCDCODE_DOWN:            /* Cursor down by N lines */
        {
          int tmp = (int)g_lcd1602.currow + count;

          /* Don't permit movement past the bottom of the SLCD */

          if (tmp >= LCD_NROWS)
            {
              tmp = LCD_NROWS - 1;
            }

          /* Save the new cursor position */

          g_lcd1602.currow = (uint8_t)tmp;
        }
        break;

      case SLCDCODE_PAGEUP:          /* Cursor up by N pages */
      case SLCDCODE_PAGEDOWN:        /* Cursor down by N pages */
        break;                       /* Not supportable on this SLCD */

      /* Blinking */

      case SLCDCODE_BLINKSTART:      /* Start blinking with current cursor position */
      case SLCDCODE_BLINKEND:        /* End blinking after the current cursor position */
      case SLCDCODE_BLINKOFF:        /* Turn blinking off */
        break;                       /* Not implemented */

      /* These are actually unreportable errors */

      default:
      case SLCDCODE_NORMAL:          /* Not a special keycode */
        break;
    }

  lcd_dumpstate("AFTER ACTION");
}
Beispiel #4
0
int up_lcd1602_initialize(void)
{
  int ret = OK;

  /* Only initialize the driver once. */

  if (!g_lcd1602.initialized)
    {
      lcdinfo("Initializing\n");

      /* Configure GPIO pins */

      putreg16(0, PIC32MX_IOPORTE_TRIS);       /* Set DB0-15 as outputs */
      pic32mx_configgpio(GPIO_LCD_RS);         /* RS: Selects commnand or data */
      pic32mx_configgpio(GPIO_LCD_RW);         /* RW: Selects read or write */
      pic32mx_configgpio(GPIO_LCD_E);          /* E:  Starts transfer */

      /* Configure LCD power in the OFF state */

      pic32mx_configgpio(GPIO_LCD_LIGHT);       /* K */
      pic32mx_configgpio(GPIO_LCD_COMP);        /* Vo */
      pic32mx_configgpio(GPIO_LCD_PWR);         /* Vbuson/AN5/RB5 controls +5V USB */
      g_lcd1602.brightness = 0;                 /* Remember tht the light is off */

      /* A small delay is necessary between when GPIO_LCD_E was set up as an
       * output with initial value of 0 and this operation.  That delay should
       * be well covered by the intervening GPIO configurations.
       */

      pic32mx_gpiowrite(GPIO_LCD_E, true);     /* Enable transfer */

      /* Configure and enable the LCD */
      /* Delay for 4.1MS or more */

      up_mdelay(5);

      /* Select the 8-bit interface. BF cannot be checked before this command.
       * This needs to be done a few times with some magic delays.
       *
       * Function set: 5x7 Style | N=2R | DL=8D
       */

      lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_F5x7 | HD4478OU_FUNC_N1 | HD4478OU_FUNC_DL8D);
      up_udelay(100);            /* Delay more than 100uS */

      lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_F5x7 | HD4478OU_FUNC_N1 | HD4478OU_FUNC_DL8D);
      up_udelay(40);             /* Delay more than 40uS */
      lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_F5x7 | HD4478OU_FUNC_N1 | HD4478OU_FUNC_DL8D);
      lcd_waitbusy();

      lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_F5x7 | HD4478OU_FUNC_N1 | HD4478OU_FUNC_DL8D);
      lcd_waitbusy();

      /* Display ON, cursor OFF, blink OFF */

      lcd_wrcommand(HD4478OU_DISPLAY | HD4478OU_DISPLAY_ON);
      lcd_waitbusy();

      /* Clear the display and home the cursor */

      lcd_wrcommand(HD4478OU_CLEAR); /* Clear display */
      lcd_waitbusy();

      lcd_wrcommand(HD4478OU_RETURN); /* Return home: AC=0 */
      lcd_waitbusy();

      /* Entry Mode Set:
       *
       * - Increment address by one,
       * - Shift cursor to right (display is not shifted)
       */

      lcd_wrcommand(HD4478OU_INPUT | HD4478OU_INPUT_INCR);

      /* Register the LCD device driver */

      ret = register_driver("/dev/lcd1602", &g_lcdops, 0644, &g_lcd1602);
      g_lcd1602.initialized = true;
    }

  return ret;
}