I'm trying to get going with this i2c display device: https://www.newhavendisplay.com/specs/NHD-C160100DiZ-FSW-FBW.pdf

On Arduino, I've been able to initialise the device using the wire library and the following code:

#include <Wire.h>

#define Addr 0x3F 

const int resetPin = 2;       
const int chipSelectPin = 3;  
const char comsend = 0x00;

void DiZ_init()
{
  Wire.beginTransmission(Addr);
  Wire.write(comsend);
  Wire.write(0x38); //mode set
  Wire.write(0x04); //FR[3:0] = 0000, BE = 1, EXT = 0 (normal instruction mode)
  Wire.write(0xAB); //OSC ON
  Wire.write(0x66); //set DC-DC step up
  Wire.write(0x26); //set regulator resistor
  Wire.write(0x81); //set reference voltage select mode
  Wire.write(0x1C); //set reference voltage register
  Wire.write(0x56); //set 1/11 bias
  Wire.write(0x2C); //set power control
  Wire.write(0x2E); //set power control
  Wire.write(0x2F); //set power control
  Wire.write(0xAF); //display ON
  Wire.endTransmission();
}

void setup()
{
  pinMode(resetPin, OUTPUT);
  pinMode(chipSelectPin, OUTPUT);
  digitalWrite(chipSelectPin, LOW);
  digitalWrite(resetPin, LOW);
  
  delay(150);
  digitalWrite(resetPin, HIGH);
  delay(150);
  
  Wire.begin();
  delay(5);

  DiZ_init();
}

I'm now trying to communicate with the device using Bela, but so far to no avail. I've tried to recreate the Arduino code exactly - here are the relevant bits from my render.cpp:

#include "Display.h"

#define DISPLAY_CHIP_SEL_PIN P9_12
#define DISPLAY_RESET_PIN P9_14

Display display;

bool setup(BelaContext *context, void *userData)
{
	pinMode(context, 0, DISPLAY_CHIP_SEL_PIN, OUTPUT);
   	pinMode(context, 0, DISPLAY_RESET_PIN, OUTPUT);
    	
    digitalWrite(context, 0, DISPLAY_CHIP_SEL_PIN, GPIO_LOW);
    digitalWrite(context, 0, DISPLAY_RESET_PIN, GPIO_LOW);
    
  	usleep(150000);
  	digitalWrite(context, 0, DISPLAY_RESET_PIN, GPIO_HIGH);
  	usleep(150000);
    
	if(!display.begin())
	{
		rt_printf("Error initialising Newhaven display device\n");
	}
	
	usleep(5000);
	int result = display.initDisplay();
	usleep(5000);
	
	rt_printf("result = %d\n", result);
	return true;
}

and Display.cpp

const char COM_SEND = 0x00;

boolean Display::begin(uint8_t bus, uint8_t i2caddr) 
{
    mI2c_address = i2caddr;
    
    if(initI2C_RW(bus, i2caddr, 0) > 0)
        return false;

    return true;
}

int Display::initDisplay()
{
	uint8_t initTable[] = {COM_SEND, 0x38, 0x04, 0xAB, 0x66, 0x26, 0x81, 0x1C, 0x56, 0x2C, 0x2E, 0x2F, 0xAF};
	int result = write(i2C_file, initTable, 13);
	return result;
}

If I run i2cdetect -y -r 1 on the command line once the reset pin is set high, the device (0x3f) is found, so I assume it's a problem with my code and not the hardware/connections.

The result returned by initDisplay is -1. From the Bela i2c example class (I2C_MPR121) I gathered that the write(i2C_file...) method could be used to transmit individual bytes in the same way as Wire.write() on Arduino, but perhaps I have misunderstood?

Small update - the error number returned by the write(..) method is 121 (EREMOTEIO = Remote I/O error), if that helps anyone...

Oh, and for completeness, from Display.h:

#define DISPLAY_I2C_ADDR_DEFAULT 0x3F	

class Display : public I2c
{
public:
    
    Display();
    
    boolean begin(uint8_t bus = 1, uint8_t i2caddr = DISPLAY_I2C_ADDR_DEFAULT);
...

when you call any of the ...Read() or ...Write() functions, unlike on Arduino, the board does not actually stop and write/read that value to/from the output, rather it writes it to a location in memory that is then written to the output at a constant sample rate. This is a good starting point reference: https://forum.bela.io/d/454-shift-register/3

So if you want to do some stuff like what you are doing in setup() you may want to use the Gpio class, which allows to toggle or read a digital pin immediately as the code is executed.
Note that if you use one the 16 Bela digitals through the Gpio API, it would work fine in setup(), but it would then be "owned" by the Bela engine once render() starts being called, which means you will not be able to control it from the Gpio API any longer. If you use a different Gpio pin, you can still safely use it from render(), but be aware that having usleep() in render() is not a good idea, as it WILL cause glitches in the audio.

a month later