207 lines
5.3 KiB
C++
207 lines
5.3 KiB
C++
|
|
/*
|
|
* Copyright (c) 2014-2017 Cesanta Software Limited
|
|
* All rights reserved
|
|
*/
|
|
|
|
#define USE_I2C true
|
|
#define USE_SPI false
|
|
#define SSD1306_64_48
|
|
|
|
#include <stdio.h>
|
|
#include "common/platform.h"
|
|
#include "common/cs_file.h"
|
|
#include "mgos_app.h"
|
|
#include "mgos_gpio.h"
|
|
#include "mgos_sys_config.h"
|
|
#include "mgos_timers.h"
|
|
#include "mgos_hal.h"
|
|
#include "mgos_dlsym.h"
|
|
#include "mjs.h"
|
|
|
|
#include <Arduino.h>
|
|
#include "Adafruit_SSD1306dj.h"
|
|
|
|
#include "mgos_rpc.h"
|
|
#include "common/cs_dbg.h"
|
|
#include "common/json_utils.h"
|
|
#include "frozen/frozen.h"
|
|
#include "mgos_net.h"
|
|
|
|
Adafruit_SSD1306 *d1 = nullptr, *d2 = nullptr;
|
|
static void timer_cb(void *arg);
|
|
|
|
#include "fremo_logo.xbm"
|
|
#include "test_pattern.xbm"
|
|
|
|
static void printTextPattern(Adafruit_SSD1306 *d) {
|
|
d->setTextSize(1);
|
|
d->setTextColor(WHITE);
|
|
d->setCursor(0, 18);
|
|
d->printf("%s", "abcdefghijk");
|
|
d->setCursor(0, 27);
|
|
d->printf("%s", "@+#$%[]|{}");
|
|
d->setCursor(0, 36);
|
|
d->printf("%s", "ABCDEFGHIJK");
|
|
// d->setCursor(0, 48);
|
|
// d->printf("%s", "01234567890");
|
|
// d->display();
|
|
}
|
|
|
|
static void show_num(Adafruit_SSD1306 *d, const char *s, int i) {
|
|
d->clearDisplay();
|
|
d->setTextSize(1);
|
|
d->setTextColor(WHITE);
|
|
// d->setCursor(0, 0);
|
|
// d->printf("%s", " ");
|
|
d->setCursor(0, 0);
|
|
d->printf("%s%d", s, i);
|
|
printTextPattern(d1);
|
|
}
|
|
|
|
static void show_msg(Adafruit_SSD1306 *d, const char *s) {
|
|
d->setTextSize(1);
|
|
d->setTextColor(WHITE);
|
|
// d->setCursor(0, 9);
|
|
// d->printf("%s", " ");
|
|
d->setCursor(0, 9);
|
|
d->printf("%s", s);
|
|
}
|
|
|
|
static void print_message_handler(struct mg_rpc_request_info *ri, void *cb_arg,
|
|
struct mg_rpc_frame_info *fi, struct mg_str args) {
|
|
struct mbuf fb;
|
|
struct json_out out = JSON_OUT_MBUF(&fb);
|
|
|
|
mbuf_init(&fb, 20);
|
|
|
|
const char *msg = "";
|
|
if (json_scanf(args.p, args.len, ri->args_fmt, &msg) == 1) {
|
|
json_printf(&out, "{result: %Q, msg: %Q}", "OK", msg);
|
|
} else {
|
|
json_printf(&out, "{error: %Q}", "num is required");
|
|
}
|
|
|
|
// mgos_gpio_toggle(LED_GPIO);
|
|
if (d1 != nullptr) {
|
|
show_msg(d1, msg);
|
|
d1->display();
|
|
}
|
|
|
|
printf("msg = %s\n", msg);
|
|
|
|
mg_rpc_send_responsef(ri, "%.*s", fb.len, fb.buf);
|
|
ri = NULL;
|
|
|
|
mbuf_free(&fb);
|
|
|
|
(void) cb_arg;
|
|
(void) fi;
|
|
}
|
|
|
|
// Draw RAM-resident XBitMap Files (*.xbm), exported from GIMP,
|
|
// Usage: Export from GIMP to *.xbm, rename *.xbm to *.c and open in editor.
|
|
// C Array can be directly used with this function.
|
|
void drawXBitmap(Adafruit_SSD1306 *display, int16_t x, int16_t y,
|
|
const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color, uint16_t bg) {
|
|
|
|
int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte
|
|
uint8_t byte = 0;
|
|
|
|
display->startWrite();
|
|
for (int16_t j=0; j<h; j++, y++) {
|
|
for (int16_t i=0; i<w; i++ ) {
|
|
if (i & 7) byte >>= 1;
|
|
else byte = bitmap[j * byteWidth + i / 8];
|
|
// Nearly identical to drawBitmap(), only the bit order
|
|
// is reversed here (left-to-right = LSB to MSB):
|
|
display->writePixel(x+i, y, (byte & 0x01) ? color:bg);
|
|
}
|
|
}
|
|
display->endWrite();
|
|
}
|
|
|
|
|
|
void setup(void) {
|
|
// I2C
|
|
d1 = new Adafruit_SSD1306(4 /* RST GPIO */, Adafruit_SSD1306::RES_64_48);
|
|
|
|
if (d1 != nullptr) {
|
|
d1->begin(SSD1306_SWITCHCAPVCC, 0x3c, true /* reset */);
|
|
d1->display();
|
|
}
|
|
// set codepage correctly / apply bug fix
|
|
d1->cp437(true);
|
|
d1->setTextWrap(false);
|
|
|
|
struct mg_rpc *c = mgos_rpc_get_global();
|
|
mg_rpc_add_handler(c, "Display.Message", "{msg: %s}", print_message_handler, NULL);
|
|
|
|
mgos_set_timer(3000 /* ms */, true /* repeat */, timer_cb, NULL);
|
|
}
|
|
|
|
static void timer_cb(void *arg) {
|
|
static int i = 0, j = 0;
|
|
static int startupStep = 0;
|
|
int posCenterX = d1->width()/2;
|
|
int posCenterY = d1->height()/2;
|
|
|
|
startupStep++;
|
|
switch (startupStep) {
|
|
case 1: break;
|
|
case 2:
|
|
d1->clearDisplay();
|
|
drawXBitmap(d1, 0, 0, (uint8_t *) FREMO_LOGO_bits, FREMO_LOGO_width, FREMO_LOGO_height, WHITE, BLACK);
|
|
break;
|
|
case 3: break;
|
|
case 4: break;
|
|
case 5:
|
|
d1->clearDisplay();
|
|
d1->drawBitmap(0, 0, (uint8_t *) TEST_PATTERN_bits, TEST_PATTERN_width, TEST_PATTERN_height, WHITE, BLACK);
|
|
break;
|
|
case 6: break;
|
|
case 7: break;
|
|
case 8: break;
|
|
case 9:
|
|
d1->clearDisplay();
|
|
show_msg(d1, "*Init'ed*");
|
|
break;
|
|
case 10:
|
|
d1->writeFastVLine(d1->width()-1, 0, d1->height(), WHITE);
|
|
break;
|
|
case 11:
|
|
d1->writeFastHLine(0, d1->height()-1, d1->width(), WHITE);
|
|
break;
|
|
case 12:
|
|
d1->clearDisplay();
|
|
d1->fillCircle(posCenterX, posCenterY, 20, WHITE);
|
|
d1->fillCircle(posCenterX, posCenterY, 10, BLACK);
|
|
break;
|
|
case 13:
|
|
d1->drawLine(0, 0, d1->width()-1, d1->height()-1, WHITE);
|
|
break;
|
|
case 14:
|
|
d1->drawLine(d1->width()-1, 0, 0, d1->height()-1, WHITE);
|
|
break;
|
|
case 15: break;
|
|
default:
|
|
show_num(d1, "i = ", i);
|
|
LOG(LL_INFO, ("i = %d, j = %d", i, j));
|
|
if (i % 10 == 0) {
|
|
switch (i/10) {
|
|
case 1: show_msg(d1, "-> 1st dec"); break;
|
|
case 2: show_msg(d1, "-> 2nd dec"); break;
|
|
case 3: show_msg(d1, "-> 3rd dec"); break;
|
|
case 4: show_msg(d1, "-> 4th dec"); break;
|
|
default: show_msg(d1, "-> more ..");
|
|
}
|
|
}
|
|
i++;
|
|
j++;
|
|
}
|
|
d1->display();
|
|
|
|
(void) arg;
|
|
}
|
|
|