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
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();
}
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;
}
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;
}
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: