I’m working currently working with a spi screen using the FX30S and mangOH IOT Card P/N: 0107-10-R1.1 The spi screen is the NHD-0216CW
Things seem to not be working due to glitches in the clock signal (See below). I believe this is causing sent bytes to be wrongly interpreted as a similar code on Arduino reliably does the job.
Here’s my code for the FX30; logread shows success and no errors
#include "legato.h"
#include "interfaces.h"
#include <time.h>
#include <errno.h>
le_spi_DeviceHandleRef_t spiHandle;
void toggle();
unsigned char text1[] = {"TANKTRONIKS"};
unsigned char text2[] = {"DEVIL TEST"};
uint8_t reverseBits(uint8_t byte) {
byte = (byte & 0xF0) >> 4 | (byte & 0x0F) << 4;
byte = (byte & 0xCC) >> 2 | (byte & 0x33) << 2;
byte = (byte & 0xAA) >> 1 | (byte & 0x55) << 1;
return byte;
}
int msleep(long msec)
{
struct timespec ts;
int res;
if (msec < 0)
{
errno = EINVAL;
return -1;
}
ts.tv_sec = msec / 1000;
ts.tv_nsec = (msec % 1000) * 1000000;
do {
res = nanosleep(&ts, &ts);
} while (res && errno == EINTR);
return res;
}
void command(unsigned char c) {
uint8_t write_buffer_tx[1];
le_result_t res;
write_buffer_tx[0] = 0xF8;
res = le_spi_WriteHD(spiHandle, write_buffer_tx, NUM_ARRAY_MEMBERS(write_buffer_tx));
LE_FATAL_IF(res != LE_OK, "le_spi_WriteHD 0x1F error=%s", LE_RESULT_TXT(res));
write_buffer_tx[0] = reverseBits((c & 0x0F));
res = le_spi_WriteHD(spiHandle, write_buffer_tx, NUM_ARRAY_MEMBERS(write_buffer_tx));
LE_FATAL_IF(res != LE_OK, "le_spi_WriteHD 0x1F1 error=%s", LE_RESULT_TXT(res));
write_buffer_tx[0] = reverseBits(((c >> 4) & 0x0F));
res = le_spi_WriteHD(spiHandle, write_buffer_tx, NUM_ARRAY_MEMBERS(write_buffer_tx));
LE_FATAL_IF(res != LE_OK, "le_spi_WriteHD 0x1F2 error=%s", LE_RESULT_TXT(res));
}
void data(unsigned char d) {
uint8_t write_buffer_tx[1];
le_result_t res;
write_buffer_tx[0] = 0xFA;
res = le_spi_WriteHD(spiHandle, write_buffer_tx, NUM_ARRAY_MEMBERS(write_buffer_tx));
LE_FATAL_IF(res != LE_OK, "le_spi_WriteHD 0x1F error=%s", LE_RESULT_TXT(res));
write_buffer_tx[0] = reverseBits((d & 0x0F));
res = le_spi_WriteHD(spiHandle, write_buffer_tx, NUM_ARRAY_MEMBERS(write_buffer_tx));
LE_FATAL_IF(res != LE_OK, "le_spi_WriteHD 0x1F1 error=%s", LE_RESULT_TXT(res));
write_buffer_tx[0] = reverseBits(((d >> 4) & 0x0F));
res = le_spi_WriteHD(spiHandle, write_buffer_tx, NUM_ARRAY_MEMBERS(write_buffer_tx));
LE_FATAL_IF(res != LE_OK, "le_spi_WriteHD 0x1F2 error=%s", LE_RESULT_TXT(res));
}
void output() {
int i;
command(0x01); // Clear display
msleep(2);
for(i = 0; i < 11; i++) {
data(text1[i]);
}
command(0xA0);
for(i = 0; i < 10; i++) {
data(text2[i]);
}
}
COMPONENT_INIT
{
msleep(20);
LE_INFO("LCD Component");
le_gpioPin48_SetPushPullOutput(LE_GPIOPIN48_ACTIVE_HIGH, true);
le_gpioPin42_SetPushPullOutput(LE_GPIOPIN42_ACTIVE_LOW, true);
msleep(20);
le_gpioPin48_SetPushPullOutput(LE_GPIOPIN48_ACTIVE_LOW, true);
le_gpioPin42_SetPushPullOutput(LE_GPIOPIN42_ACTIVE_HIGH, true);
msleep(20);
LE_INFO("CONFIGURING SPI");
le_result_t res;
res = le_spi_Open("spidev1.0", &spiHandle);
LE_FATAL_IF(res != LE_OK, "le_spi_Open failed with result=%s", LE_RESULT_TXT(res));
if(res == LE_OK){
LE_INFO("Success");
}
le_spi_Configure(spiHandle, 3, 8, 960000, 0);
LE_INFO("Beginning LCD configuration");
command(0x2A); //function set (extended command set)
command(0x71); //function selection A, disable internal Vdd regulator
data(0x00);
command(0x28); //function set (fundamental command set)
command(0x08); //display off, cursor off, blink off
command(0x2A); //function set (extended command set)
command(0x79); //OLED command set enabled
command(0xD5); //set display clock divide ratio/oscillator frequency
command(0x70); //set display clock divide ratio/oscillator frequency
command(0x78); //OLED command set disabled
command(0x09); //extended function set (4-lines)
command(0x06); //COM SEG direction
command(0x72); //function selection B
data(0x00); //ROM CGRAM selection
command(0x2A); //function set (extended command set)
command(0x79); //OLED command set enabled
command(0xDA); //set SEG pins hardware configuration
command(0x10); //set SEG pins
command(0xDC); //function selection C
command(0x00); //function selection C
command(0x81); //set contrast control
command(0x7F); //set contrast control
command(0xD9); //set phase length
command(0xF1); //set phase length
command(0xDB); //set VCOMH deselect level
command(0x40); //set VCOMH deselect level
command(0x78); //OLED command set disabled
command(0x28); //function set (fundamental command set)
command(0x01); //clear display
command(0x80); //set DDRAM address to 0x00
command(0x0C); //display ON
msleep(100);
output();
msleep(2000);
LE_INFO("END");
le_spi_Close(spiHandle);
}
Here’s my arduino code:
#include <Wire.h>
#include <SPI.h>
int CS = 10;
int RES = 9;
unsigned char text1[] = {"TANKTRONIKSº"};
unsigned char text2[] = {"DEVIL TEST"};
#define MY_SPI_MODE SPI_MODE3
uint8_t reverseBits(uint8_t byte) {
byte = (byte & 0xF0) >> 4 | (byte & 0x0F) << 4;
byte = (byte & 0xCC) >> 2 | (byte & 0x33) << 2;
byte = (byte & 0xAA) >> 1 | (byte & 0x55) << 1;
return byte;
}
void command(unsigned char c) {
digitalWrite(CS, LOW);
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, MY_SPI_MODE));
SPI.transfer(0xF8); // Command mode transfer prefix
SPI.transfer(reverseBits(c & 0x0F)); // Transfer lower nibble
SPI.transfer(reverseBits((c >> 4) & 0x0F)); // Transfer upper nibble
SPI.endTransaction();
digitalWrite(CS, HIGH);
}
void data(unsigned char d) {
digitalWrite(CS, LOW);
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, MY_SPI_MODE));
SPI.transfer(0xFA); // Data mode transfer prefix
SPI.transfer(reverseBits(d & 0x0F)); // Transfer lower nibble
SPI.transfer(reverseBits((d >> 4) & 0x0F)); // Transfer upper nibble
SPI.endTransaction();
digitalWrite(CS, HIGH);
}
void output() {
int i;
command(0x01); // Clear display
delay(2);
for(i = 0; i < 11; i++) {
data(text1[i]);
}
command(0xA0);
for(i = 0; i < 10; i++) {
data(text2[i]);
}
}
void setup() {
pinMode(RES, OUTPUT);
pinMode(CS, OUTPUT);
digitalWrite(RES, HIGH);
digitalWrite(CS, HIGH);
delay(20);
SPI.begin();
// Initialize display
command(0x2A); // function set (extended command set)
command(0x71); // function selection A, disable internal Vdd regulator
data(0x00);
command(0x28); // function set (fundamental command set)
command(0x08); // display off, cursor off, blink off
command(0x2A); // function set (extended command set)
command(0x79); // OLED command set enabled
command(0xD5); // set display clock divide ratio/oscillator frequency
command(0x70); // set display clock divide ratio/oscillator frequency
command(0x78); // OLED command set disabled
command(0x09); // extended function set (4-lines)
command(0x06); // COM SEG direction
command(0x72); // function selection B
data(0x00); // ROM CGRAM selection
command(0x2A); // function set (extended command set)
command(0x79); // OLED command set enabled
command(0xDA); // set SEG pins hardware configuration
command(0x10); // set SEG pins
command(0xDC); // function selection C
command(0x00); // function selection C
command(0x81); // set contrast control
command(0x7F); // set contrast control
command(0xD9); // set phase length
command(0xF1); // set phase length
command(0xDB); // set VCOMH deselect level
command(0x40); // set VCOMH deselect level
command(0x78); // OLED command set disabled
command(0x28); // function set (fundamental command set)
command(0x01); // clear display
command(0x80); // set DDRAM address to 0x00
command(0x0C); // display ON
delay(100);
output();
}
void loop() {
}
Here is the glitch
As you can see the clock is period is smaller where noted, this happens randomly
Thanks