lcdctrl

external lcd control
Author: Ricard Wanderlof
License: BSD
Github: ricard/disp/lcdctrl.axo

Inlets

None

Outlets

None

Attributes

combo LCD D4 pin

combo LCD D5 pin

combo LCD D6 pin

combo LCD D7 pin

combo LCD RS pin

combo LCD E pin

spinner Number of potential strings in print queue

Declaration
int data;
int state;    // 0..2 output high nybble, 3..5 output low, 6 ... delay for slow
              // commands
int endstate; // final state, 6 for normal commands, 18 for slow
const char *initstr; // initialization string
__attribute__((noinline)) void print(const char *printstr) {
  if (strings[wrindex])
    return; // if queue full, drop string
  strings[wrindex++] = printstr;
  if (wrindex >= attr_qsize)
    wrindex = 0;
}
const char *strings[attr_qsize]; // strings to output
int rdindex;                     // read index in circular string queue
int wrindex;                     // write index in circular string queue
Init
palWritePad(attr_e, 0);
palSetPadMode(attr_d4, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(attr_d5, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(attr_d6, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(attr_d7, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(attr_rs, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(attr_e, PAL_MODE_OUTPUT_PUSHPULL);
state = 0;

// init: 0011, long wait - set 8 bit mode
//       0011, short wait - set 8 bit mode
//       0011, short wait - set 8 bit mode
//       0010, short wait - set 4 bit mode
//       0010 1000, short wait - 4 bit, function set:
//            NFxx: N=1 => 2 lines, F=0 => 5x8 font
//       0000 1000, short wait - display off
//       0000 0001, long wait - display clear, set cursor and write addr home
//       0000 0110, short wait - entry mode set
//              IS: I=1 => increment, S=0 => no shift
//       0000 1100, short wait - display on
//             DCS: D=1 => display on, C=0 => no cursor, B=0 => no cursor blink
initstr = "\xf3\xb3\xb3\xb2\xb2\xb8\xb0\xb8\xb0\xf1\xb0\xb6\xb0\xbc"
          "\x83"
          "Axoloti on P6!";
strings[0] = initstr; // print initstring first
for (int i = 1; i < attr_qsize; i++) {
  strings[i] = 0;
}
rdindex = 0; // start printing the init data
wrindex = 1; // next string to write
Control Rate
// LCD Data: when bit 7 is clear, output ASCII data with RS=1
// with bit 7 is set, set cursor position: bit 6 = line (0/1),
// bit 5..0 = column (0..47, 0..39 used normally)
// when bits 5,4 are 1,1 (i.e. column would have ben 48 and above)
// bits 3,2,1,0 are output in 4 bit mode, and bit 6 indicates delay
// (0=> normal (100µs), 1=>4.1ms
// states 0,1,2 are for high nybble (output data,rs, then e=0,1,0)
// states 3,4,5 are for low nybble (output data (rs unchanged), then e=0,1,0)
// state >=6 are for long delay, just bump state until reached endstate
switch (state) {
  int rs;
case 0:
  if (!strings[rdindex])
    break; // nothing to print
  data = *strings[rdindex]++;
  if (data == 0) {          // NUL
    strings[rdindex++] = 0; // mark as read
    if (rdindex >= attr_qsize)
      rdindex = 0;
    break; // start printing next time around
  }
  // we assume e is low here
  endstate = 4;      // default is fast timing
  rs = 1;            // default register is data register
  if (data & 0x80) { // control when bit 7 set
                     // else output ASCII to display data RAM
    rs = 0;          // command register
    if ((data & 0x30) ==
        0x30) { // special 4-bit
                // else display write position (no further conditioning needed)
      if (data & 0x40)
        endstate = 16; // long delay: 4 states + 12*0.33ms (i.e. 4ms)
      data <<= 4;      // 4-bit data is in low nybble
      state = 2; // next state pulses e high, then low, then we're done (modulo
                 // potential delay)
    }
  }
  palWritePad(attr_rs, rs);
  palWritePad(attr_d4, (data >> 4) & 1); // high nybble first in LCD 4 bit mode
  palWritePad(attr_d5, (data >> 5) & 1);
  palWritePad(attr_d6, (data >> 6) & 1);
  palWritePad(attr_d7, (data >> 7) & 1);
  palWritePad(attr_e, 1);
  state++;
  break;
case 2:
  palWritePad(attr_d4,
              (data >> 0) & 1); // low nybble after first in LCD 4 bit mode
  palWritePad(attr_d5, (data >> 1) & 1);
  palWritePad(attr_d6, (data >> 2) & 1);
  palWritePad(attr_d7, (data >> 3) & 1);
  palWritePad(attr_e, 1);
  state++;
  break;
case 1:
case 3:
  palWritePad(attr_e, 0);
  // fall through
default:
  state++;
  if (state >= endstate)
    state = 0; // restart cycle when endstate reached
  break;
}

Privacy

© 2024 Zrna Research