Skip to content
Permalink
master
Go to file
 
 
Cannot retrieve contributors at this time
332 lines (286 sloc) 9.76 KB
#include <oled-exp.h>
// function prototypes:
void Usage (const char* progName);
int oledCommand (char *command, char *param);
// print the usage info
void usage(const char* progName)
{
onionPrint(ONION_SEVERITY_FATAL, "\n");
onionPrint(ONION_SEVERITY_FATAL, "Usage: oled-exp -i\n");
onionPrint(ONION_SEVERITY_FATAL, "\n");
onionPrint(ONION_SEVERITY_FATAL, "FUNCTIONALITY:\n");
onionPrint(ONION_SEVERITY_FATAL, " Initialize the OLED Display\n");
onionPrint(ONION_SEVERITY_FATAL, "\n\n");
onionPrint(ONION_SEVERITY_FATAL, "Usage: oled-exp -c\n");
onionPrint(ONION_SEVERITY_FATAL, "\n");
onionPrint(ONION_SEVERITY_FATAL, "FUNCTIONALITY:\n");
onionPrint(ONION_SEVERITY_FATAL, " Clear the OLED Display\n");
onionPrint(ONION_SEVERITY_FATAL, "\n\n");
onionPrint(ONION_SEVERITY_FATAL, "Usage: oled-exp [-icqv] COMMAND PARAMETER\n");
onionPrint(ONION_SEVERITY_FATAL, "\n");
onionPrint(ONION_SEVERITY_FATAL, "The following COMMANDs are available:\n");
onionPrint(ONION_SEVERITY_FATAL, " power <on|off> Turn the display on or off\n");
onionPrint(ONION_SEVERITY_FATAL, " write <message> Write the input string on the display\n");
onionPrint(ONION_SEVERITY_FATAL, " writeByte <byte> Write the input byte on the display\n");
onionPrint(ONION_SEVERITY_FATAL, " dim <on|off> Adjust the screen brightness\n");
onionPrint(ONION_SEVERITY_FATAL, " invert <on|off> Invert the colors on the display\n");
onionPrint(ONION_SEVERITY_FATAL, " cursor <row>,<column> Set the cursor to the specified row and column\n");
onionPrint(ONION_SEVERITY_FATAL, " cursorPixel <row>,<pixel> Set the cursor to the specified row and pixel\n");
onionPrint(ONION_SEVERITY_FATAL, " scroll <direction> Enable scrolling of screen content\n");
onionPrint(ONION_SEVERITY_FATAL, " available directions: left, right, diagonal-left, diagonal-right\n");
onionPrint(ONION_SEVERITY_FATAL, " to stop scrolling: stop\n");
onionPrint(ONION_SEVERITY_FATAL, " draw <lcd file> Draw the contents of an lcd file to the display\n");
onionPrint(ONION_SEVERITY_FATAL, "\n");
onionPrint(ONION_SEVERITY_FATAL, "COMMANDs can be cascaded one after another, they will execute in order.\n");
onionPrint(ONION_SEVERITY_FATAL, "\n");
onionPrint(ONION_SEVERITY_FATAL, "OPTIONS:\n");
onionPrint(ONION_SEVERITY_FATAL, " -i initialize display\n");
onionPrint(ONION_SEVERITY_FATAL, " -c clear the display\n");
onionPrint(ONION_SEVERITY_FATAL, " -q quiet: no output\n");
onionPrint(ONION_SEVERITY_FATAL, " -v verbose: lots of output\n");
onionPrint(ONION_SEVERITY_FATAL, " -h help: show this prompt\n");
onionPrint(ONION_SEVERITY_FATAL, "\n");
}
// execute a specified command
int oledCommand(char *command, char *param)
{
int status;
int val0, val1;
uint8_t *buffer;
// perform the specified command
onionPrint(ONION_SEVERITY_DEBUG_EXTRA, "command = '%s', param = '%s'\n", command, param);
if (strcmp(command, "write") == 0 ) {
status = oledWrite(param);
}
else if (strcmp(command, "writeByte") == 0 ) {
// parse the byte
if (param[0] == '0' && param[1] == 'x') {
sscanf(param, "0x%02x", &val0);
}
else {
sscanf(param, "%02x", &val0);
}
status = oledWriteByte(val0);
}
else if (strcmp(command, "brightness") == 0 ) {
status = oledSetBrightness( atoi(param) );
}
else if (strcmp(command, "invert") == 0 ) {
// interpret the parameter
val0 = 0; // off by default
if (strcmp(param, "on") == 0 ) {
val0 = 1;
}
status = oledSetDisplayMode( val0 );
}
else if (strcmp(command, "power") == 0 ) {
// interpret the parameter
val0 = 0; // off by default
if (strcmp(param, "on") == 0 ) {
val0 = 1;
}
status = oledSetDisplayPower(val0);
}
else if (strcmp(command, "dim") == 0 ) {
// interpret the parameter
val0 = 0; // off by default
if (strcmp(param, "on") == 0 ) {
val0 = 1;
}
status = oledSetDim(val0);
}
else if (strcmp(command, "cursor") == 0 ) {
// interpret the parameter
sscanf(param, "%d, %d", &val0, &val1);
onionPrint(ONION_SEVERITY_INFO, "> Setting cursor to (%d, %d)\n", val0, val1);
status = oledSetTextColumns();
status = oledSetCursor(val0, val1);
}
else if (strcmp(command, "cursorPixel") == 0 ) {
// interpret the parameter
sscanf(param, "%d, %d", &val0, &val1);
onionPrint(ONION_SEVERITY_INFO, "> Setting cursor to row: %d, pixel: %d\n", val0, val1);
status = oledSetImageColumns();
status = oledSetCursorByPixel(val0, val1);
}
else if (strcmp(command, "draw") == 0 ) {
// allocate memory for the buffer
buffer = malloc(OLED_EXP_WIDTH*OLED_EXP_HEIGHT/8 * sizeof *buffer);
memset(buffer, 0, OLED_EXP_WIDTH*OLED_EXP_HEIGHT/8 * sizeof *buffer); // FIXME: We should definitely do a #define for the buffer size calculation. This looks ugly.
// read the parameter
if ( strncmp(param, OLED_EXP_READ_LCD_DATA_IDENTIFIER, strlen(OLED_EXP_READ_LCD_DATA_IDENTIFIER) ) == 0 ) {
onionPrint(ONION_SEVERITY_INFO, "> Reading data from argument\n");
onionPrint(ONION_SEVERITY_DEBUG_EXTRA, " param length is %d\n", strlen(param) );
// remove the data identifier from the string
memmove ( param,
param + strlen(OLED_EXP_READ_LCD_DATA_IDENTIFIER),
strlen(param)
);
onionPrint(ONION_SEVERITY_DEBUG_EXTRA, " after move: param length is %d\n", strlen(param) );
// read the data into a buffer
status = oledReadLcdData(param, buffer);
}
else {
// read data from a file
onionPrint(ONION_SEVERITY_INFO, "> Reading data from file '%s'\n", param);
status = oledReadLcdFile(param, buffer);
}
if (status == EXIT_SUCCESS) {
status = oledDraw(buffer, OLED_EXP_WIDTH*OLED_EXP_HEIGHT/8);
}
else {
onionPrint(ONION_SEVERITY_FATAL, "ERROR: Cannot draw invalid data\n");
}
// deallocate memory for the buffer
if (buffer != NULL) {
onionPrint(ONION_SEVERITY_DEBUG_EXTRA, "> Deallocating buffer array\n");
free(buffer);
}
}
else if (strcmp(command, "scroll") == 0 ) {
// interpret the parameters
val0 = -1;
val1 = -1;
if (strcmp(param, "left") == 0) {
val0 = 0; // horizontal scrolling
val1 = 0; // scrolling left
}
else if (strcmp(param, "right") == 0) {
val0 = 0; // horizontal scrolling
val1 = 1; // scrolling right
}
else if (strcmp(param, "diagonal-left") == 0) {
val0 = 1; // vertical scrolling
val1 = 0; // scrolling up
}
else if (strcmp(param, "diagonal-right") == 0) {
val0 = 1; // vertical scrolling
val1 = 1; // scrolling down
}
if (val0 == -1) {
status = oledScrollStop();
}
else if (val0 == 0) {
// horizontal scrolling
status = oledScroll(val1, OLED_EXP_SCROLL_SPEED_5_FRAMES, 0, OLED_EXP_CHAR_ROWS-1);
}
else if (val0 == 1) {
// diagonal scrolling
status = oledScrollDiagonal ( val1, // direction
OLED_EXP_SCROLL_SPEED_5_FRAMES, // scroll speed
0, // # fixed rows
OLED_EXP_HEIGHT, // # scrolling rows
1, // rows to scroll by
0, // horizontal start page
OLED_EXP_CHAR_ROWS-1 // horizontal end page
);
}
}
else {
onionPrint(ONION_SEVERITY_FATAL, "> Unrecognized command '%s'\n", command );
}
return status;
}
int main(int argc, char** argv)
{
const char *progname;
char *command;
char *param;
int status;
int verbose;
int init;
int clear;
int ch;
// set the defaults
init = 0;
clear = 0;
verbose = ONION_VERBOSITY_NORMAL;
command = malloc(MAX_COMMAND_LENGTH * sizeof *command);
param = malloc(MAX_PARAM_LENGTH * sizeof *param);
// save the program name
progname = argv[0];
//// parse the option arguments
while ((ch = getopt(argc, argv, "vqhic")) != -1) {
switch (ch) {
case 'v':
// verbose output
verbose++;
break;
case 'q':
// quiet output
verbose = ONION_VERBOSITY_NONE;
break;
case 'i':
// perform init sequence
init = 1;
break;
case 'c':
// perform clear sequence
clear = 1;
break;
default:
usage(progname);
return 0;
}
}
// set the verbosity
onionSetVerbosity(verbose);
// advance past the option arguments
argc -= optind;
argv += optind;
//// OLED PROGRAMMING
// check if OLED Expansion is present
status = oledCheckInit();
// exit the app if i2c reads fail
if (status == EXIT_FAILURE) {
onionPrint(ONION_SEVERITY_FATAL, "> ERROR: OLED Expansion not found!\n");
return 0;
}
// initialize display
if ( init == 1 ) {
status = oledDriverInit();
if (status == EXIT_FAILURE) {
onionPrint(ONION_SEVERITY_FATAL, "main-oled-exp:: display init failed!\n");
}
}
// clear screen
if ( clear == 1 ) {
onionPrint(ONION_SEVERITY_INFO, "> Clearing display\n");
status = oledClear();
if (status == EXIT_FAILURE) {
onionPrint(ONION_SEVERITY_FATAL, "main-oled-exp:: display clear failed!\n");
}
}
// check if just option command
if ( argc == 0 ) {
// check if usage needs to be printed
if ( init == 0 && clear == 0) {
usage(progname);
}
return 0;
}
//// parse the command arguments
while ( argc > 0 ) {
if(strlen(argv[0]) > MAX_COMMAND_LENGTH || strlen(argv[1]) > MAX_PARAM_LENGTH) {
// FIXME: This error needs rewording. Also, the exit status should be less funny.
onionPrint(ONION_SEVERITY_FATAL, "Unsupported parameter length\n");
exit(13);
}
// first arg - command
strcpy(command, argv[0]);
// second arg - parameter (optional)
if ( argc > 1 ) {
strcpy(param, argv[1]);
}
// perform the specified command
status = oledCommand(command, param);
if (status != EXIT_SUCCESS) {
onionPrint(ONION_SEVERITY_FATAL, "ERROR: command '%s' failed!\n", command);
}
// decrement the number of arguments left
argc -= 2;
argv += 2;
onionPrint(ONION_SEVERITY_DEBUG, "> arguments remaining: %d\n", argc);
}
return 0;
}