Serial write OS6xx usage

Can someone help me with OS 6xx serial functions (using Mbed Studio)?
Mbed continuing to redesign the wheel, I was hoping they had got bored by now :slight_smile:

I’m updating from earlier versions with serial put and get but hit a small snag.

Sending a bunch of characters is okay but,
To send a single byte or character I’m using this:

oled.write((char*)0x55,1);   // send byte for OLED to autodetect baudrate 

No red or yellow squiggly underlines with that so it might work, can’t tell until I’ve fixed the rest of the code.

However one function needs some extra bit manipulation, last two commands, not sure if I can do this inside the command or if I have to handle it outside…

void OLED160G1::drawLine(char x1, char y1, char x2, char y2, int color) {
    oled.write(OLED_LINE);      // Line
    oled.write(x1);
    oled.write(y1);
    oled.write(x2);
    oled.write(y2);
    oled.write(color >> 8);      // MSB      stuck here    
    oled.write(color & 0xFF);    // LSB      and here
    getResponse();
}

Any help would be appreciated.

Hello Paul,

that is nothing new, Mbed OS 6 was released in middle of 2020.

try it like this

   oled.write(&y2, sizeof(y2));
   char msb = color >> 8;
   char lsb = color & 0xFF;
   oled.write(&msb, sizeof(msb ));  
   oled.write(&lsb, sizeof(lsb));

BR, Jan

Hello Paul,

Your code can become something like this.

void OLED160G1::drawLine(char x1, char y1, char x2, char y2, int color) {
    char buffer[] = { OLED_LINE, x1, y1, x2, y2, color >> 8, color & 0xFF };
    oled.write(buffer, 7);
    getResponse();
}

Best regards,
Yannic

Thank you Yannic.

That looks a bit more os6 compliant. I’ll try that and later but this is far as I got, but not working.
Can’t seem to get serial interrupt callback working like before.

OLED160G1::OLED160G1(PinName serialTx, PinName serialRx, PinName resetPin)
    : Oled(serialTx, serialRx), reset(resetPin) {
  Oled.baud(BAUDRATE);
  Oled.format(8,                // bits
              SerialBase::None, // parity
              1                 // stop bit
  );
  resetDisplay();
}

void OLED160G1::oledcb() {    // serial callback if serial port receives data
    while (Oled.readable()){
        Oled.read(&oledbuff[bufferIndex],1);
        bufferIndex++;
        }
    oledrx=1;
}

void OLED160G1::resetDisplay() {
    char c;
    reset = 0;
    wait_us(10000);
    reset = 1;
    wait_us(500000);
    while (Oled.readable()){
        Oled.read(&c,1);     
        }
    c = 0x55;

    Oled.attach(callback(this,&OLED160G1::oledcb),SerialBase::RxIrq); 
    Oled.write(&c,1); // send byte for OLED to autodetect baudrate 

    getResponse();    
    setFontSize(FONT5X7);
    setTextBackgroundType(TEXT_OPAQUE);
    setFontColor(WHITE); 
    drawText(0,0,(FONT5X7),(char*)"Oled160g1",toRGB(100,100,100));
    drawText(0,2,(FONT5X7),(char*)"Ready > ",toRGB(100,100,100));       
}

void OLED160G1::getResponse() {  
  t.reset(); t.start();
  while (chrono::duration_cast<chrono::milliseconds>(t.elapsed_time()).count() < 500) {
    if (oledrx) {
        oledrx = 0;
        //debug("response: %d\n",oledbuff[0]);
      if (oledbuff[0] == 6) { // 0x06 byte sent successful
        break;
      }
      if (oledbuff[0] == 21) { // 0x15 byte sent unsuccessful
        break;
      }
    }
  }
  bufferIndex=0;
  t.stop();
  return;
}

Hello Paul,

The only part of your code that I find problematic is the oledcb() function.

It’s an IRQ function so there is nothing blocking it.
It is triggered with each received character, so there is no need to loop or test the return of readable().

void OLED160G1::oledcb() {    // serial callback if serial port receives data
    Oled.read(&oledbuff[bufferIndex++],1);
    oledrx=1;
}

Best regards,
Yannic

For what it’s worth, this is actually a good use case for the new Mbed 6 asynchronous buffered serial.

You can actually completely remove the attach() call and the callback, and replace your waiting loop with something like this:

while (chrono::duration_cast<chrono::milliseconds>(t.elapsed_time()).count() < 500) {
    while (Oled.readable()){
           // read a byte using Oled.read() and process it
        }
  }

You will also need to make sure Oled is a BufferedSerial and set it to nonblocking mode, e.g. by adding this to the constructor:

Oled.set_blocking(false);

There’s more info in my guide here: Hitchhiker's Guide to Printf in Mbed 6