187 lines
4.1 KiB
C++
187 lines
4.1 KiB
C++
|
#include "MicroBit.h"
|
||
|
#include "mbed.h"
|
||
|
|
||
|
/**
|
||
|
* Constructor.
|
||
|
* Create an instance of MicroBitSerial
|
||
|
*
|
||
|
* @param tx the Pin to be used for transmission
|
||
|
* @param rx the Pin to be used for receiving data
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* MicroBitSerial serial(USBTX, USBRX);
|
||
|
* @endcode
|
||
|
* @note the default baud rate is 115200
|
||
|
*/
|
||
|
MicroBitSerial::MicroBitSerial(PinName tx, PinName rx) : Serial(tx,rx)
|
||
|
{
|
||
|
this->baud(MICROBIT_SERIAL_DEFAULT_BAUD_RATE);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sends a managed string over serial.
|
||
|
*
|
||
|
* @param s the ManagedString to send
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* uBit.serial.printString("abc123");
|
||
|
* @endcode
|
||
|
*/
|
||
|
void MicroBitSerial::sendString(ManagedString s)
|
||
|
{
|
||
|
const int len = s.length();
|
||
|
const char *data = s.toCharArray();
|
||
|
|
||
|
Serial::write(data,len);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reads a ManagedString from serial
|
||
|
*
|
||
|
* @param len the buffer size for the string, default is defined by MICROBIT_SERIAL_BUFFER_SIZE
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* uBit.serial.readString();
|
||
|
* @endcode
|
||
|
*
|
||
|
* @note this member function will wait until either the buffer is full, or a \n is received
|
||
|
*/
|
||
|
ManagedString MicroBitSerial::readString(int len)
|
||
|
{
|
||
|
if(len < 3)
|
||
|
len = 3;
|
||
|
|
||
|
char buffer[len];
|
||
|
|
||
|
memset(buffer, 0, sizeof(buffer));
|
||
|
|
||
|
int length = readChars(buffer,len);
|
||
|
|
||
|
if(length == 0)
|
||
|
return ManagedString();
|
||
|
|
||
|
//add in a null terminator so bad things don't happen with ManagedString
|
||
|
buffer[length] = '\0';
|
||
|
|
||
|
return ManagedString(buffer);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sends a MicroBitImage over serial in csv format.
|
||
|
*
|
||
|
* @param i the instance of MicroBitImage you would like to send.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
|
||
|
* MicroBitImage i(10,5,heart);
|
||
|
* uBit.serial.sendImage(i);
|
||
|
* @endcode
|
||
|
*/
|
||
|
void MicroBitSerial::sendImage(MicroBitImage i)
|
||
|
{
|
||
|
sendString(i.toString());
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Reads a MicroBitImage over serial, in csv format.
|
||
|
*
|
||
|
*
|
||
|
* @return a MicroBitImage with the format described over serial
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* MicroBitImage i = uBit.serial.readImage(5,5);
|
||
|
* @endcode
|
||
|
*
|
||
|
* Example Serial Format:
|
||
|
* @code
|
||
|
* 0,10x0a0,10x0a // 0x0a is a LF terminal which is used as a delimeter
|
||
|
* @endcode
|
||
|
* @note this will finish once the dimensions are met.
|
||
|
*/
|
||
|
MicroBitImage MicroBitSerial::readImage(int width, int height)
|
||
|
{
|
||
|
int rowLength = width * 2;
|
||
|
int len = rowLength * height;
|
||
|
|
||
|
char buffer[len + 1];
|
||
|
|
||
|
memset(buffer, 0, sizeof(buffer));
|
||
|
|
||
|
//add in a null terminator so bad things don't happen with MicroBitImage
|
||
|
buffer[len] = '\0';
|
||
|
|
||
|
for(int i = 0; i < height; i++)
|
||
|
{
|
||
|
int offset = i * rowLength;
|
||
|
|
||
|
readChars(&buffer[offset],len - offset);
|
||
|
|
||
|
buffer[(offset + rowLength) - 1] = '\n';
|
||
|
}
|
||
|
|
||
|
return MicroBitImage(buffer);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sends the current pixel values, byte-per-pixel, over serial
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* uBit.serial.sendDisplayState();
|
||
|
* @endcode
|
||
|
*/
|
||
|
void MicroBitSerial::sendDisplayState()
|
||
|
{
|
||
|
for(int i = 0; i < MICROBIT_DISPLAY_HEIGHT; i++)
|
||
|
for(int j = 0; j < MICROBIT_DISPLAY_WIDTH; j++)
|
||
|
_putc(uBit.display.image.getPixelValue(j,i));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reads pixel values, byte-per-pixel, from serial, and sets the display.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* uBit.serial.readDisplayState();
|
||
|
* @endcode
|
||
|
*/
|
||
|
void MicroBitSerial::readDisplayState()
|
||
|
{
|
||
|
for(int i = 0; i < MICROBIT_DISPLAY_HEIGHT; i++)
|
||
|
for(int j = 0; j < MICROBIT_DISPLAY_WIDTH; j++)
|
||
|
{
|
||
|
int c = _getc();
|
||
|
uBit.display.image.setPixelValue(j,i,c);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ssize_t MicroBitSerial::readChars(void* buffer, size_t length, char eof) {
|
||
|
|
||
|
char* ptr = (char*)buffer;
|
||
|
char* end = ptr + length;
|
||
|
|
||
|
int eofAscii = (int)eof;
|
||
|
|
||
|
while (ptr != end) {
|
||
|
|
||
|
int c = _getc();
|
||
|
|
||
|
//check EOF
|
||
|
if (c == eofAscii)
|
||
|
break;
|
||
|
|
||
|
//store the character
|
||
|
*ptr++ = c;
|
||
|
}
|
||
|
|
||
|
return ptr - (const char*)buffer;
|
||
|
}
|
||
|
|
||
|
|