Skip to content

Instantly share code, notes, and snippets.

@githubnemo
Last active November 27, 2019 09:06
Show Gist options
  • Save githubnemo/2b228e256e55bf7d65e24b5d8524d60e to your computer and use it in GitHub Desktop.
Save githubnemo/2b228e256e55bf7d65e24b5d8524d60e to your computer and use it in GitHub Desktop.
const int SCK_PIN = 5;
const int RCK_PIN = 9;
const int NOE_PIN = 8;
const int DIN_PIN = 6;
const int WTF_PIN = 3;
static void cycle_sck(void) {
digitalWrite(SCK_PIN, HIGH);
//delay(1);
digitalWrite(SCK_PIN, LOW);
//delay(1);
}
static void cycle_rck(void) {
digitalWrite(RCK_PIN, HIGH);
//delay(1);
digitalWrite(RCK_PIN, LOW);
//delay(1);
}
/*
CREG bits
QA/0: ?
QB/1: ?
QC/2: ? display
QD/3: ?
QE/4: !status led
QF/5: backlight
QG/6: ? display
QH/7: ? display
*/
uint8_t writeCtrl(uint8_t b) {
// write bits to shift-register
writeData(b);
// copy from shift register to
// backing register
cycle_rck();
return b;
}
void writeData(uint8_t b) {
for (int i=0; i < 8; i++) {
if (b & 1) {
digitalWrite(DIN_PIN, HIGH);
} else {
digitalWrite(DIN_PIN, LOW);
}
cycle_sck();
b >>= 1;
}
}
/*
* assumption: RGB interface.
* from SPFD54122B datasheet (p.10) we have the following pins:
* - HSYNC
* - VSYNC
* - DE (HIGH=valid data on DB[0;7])
* - PCLK
*
* PCLK might be WTF_PIN, DEN
* " So, controller (host) must always transfer PCLK, VS, HS and DE signals to SPFD54122B"
*
* Signal description on p.137
*
* - The host changes D[17:0], VS, HS and DE lines [on] falling edge of PCLK
* - The driver read the D[17:0], VS, HS and DE lines [on] rising edge of PCLK
*
* Detailled description on p.143 to write a new frame (see also p.138 for HS/VS details):
*
* 0. HSYNC=1, VSYNC=1, DE=0
* 1. toggle VSYNC low - high
* 128 times:
* 1. toggle HSYNC low - high
* 2. set DE=1
* 3. write pixels via DB for 128 PCLK cycles
* 4. set DE=0
*
* For each change, PCLK low first, after change, PCLK up.
*/
void rgbtest(void) {
const int PCLK = WTF_PIN;
// bit assignments in CREG
// available: 0, 1, 5
// H V D
// 0 1 5 x
// 1 0 5 x
// 0 5 1 x none of this works
// 1 5 0 x
// 5 0 1 x
// 5 1 0 x
// alternative: 2, 6, 7
const int HSYNC = 0;
const int VSYNC = 1;
const int DE = 5;
const int LED = 3;
int CREG = 0b0000100;
// CREG:
// 0b00100011
// ^ ^^-.
// d1 d2 d3
// step 0; init
digitalWrite(PCLK, LOW);
writeCtrl(CREG | (1 << HSYNC) | (1 << VSYNC));
digitalWrite(PCLK, HIGH);
// step 1; toggle VSYNC
digitalWrite(PCLK, LOW);
writeCtrl(CREG | (1 << HSYNC));
digitalWrite(PCLK, HIGH);
digitalWrite(PCLK, LOW);
writeCtrl(CREG | (1 << HSYNC) | (1 << VSYNC));
digitalWrite(PCLK, HIGH);
for (int i=0; i < 128; i++) {
// toggle status LED every second row
if (i % 2 == 0) {
CREG ^= (1 << LED);
}
// step 1: toggle HSYNC
digitalWrite(PCLK, LOW);
writeCtrl(CREG | (1 << VSYNC));
digitalWrite(PCLK, HIGH);
digitalWrite(PCLK, LOW);
writeCtrl(CREG | (1 << HSYNC) | (1 << VSYNC));
digitalWrite(PCLK, HIGH);
// step 2: set DE=1
digitalWrite(PCLK, LOW);
writeCtrl(CREG | (1 << HSYNC) | (1 << VSYNC) | (1 << DE));
digitalWrite(PCLK, HIGH);
// step 3: write pixels
for (int j=0; j < 128; j++) {
digitalWrite(PCLK, LOW);
writeData(0xAA);
digitalWrite(PCLK, HIGH);
}
// step 4: set DE=0
digitalWrite(PCLK, LOW);
writeCtrl(CREG | (1 << HSYNC) | (1 << VSYNC));
digitalWrite(PCLK, HIGH);
}
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(NOE_PIN, OUTPUT);
pinMode(DIN_PIN, OUTPUT);
pinMode(SCK_PIN, OUTPUT);
pinMode(RCK_PIN, OUTPUT);
pinMode(WTF_PIN, OUTPUT);
digitalWrite(DIN_PIN, LOW);
digitalWrite(SCK_PIN, LOW);
digitalWrite(RCK_PIN, LOW);
digitalWrite(WTF_PIN, HIGH);
// disable output
digitalWrite(NOE_PIN, HIGH);
delay(100);
// enable output
digitalWrite(NOE_PIN, LOW);
// toggle backlight off, on
writeCtrl(0b0000000);
delay(100);
writeCtrl(0b0000100);
delay(100);
while (true) {
rgbtest();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment