122 lines
3.0 KiB
Plaintext
122 lines
3.0 KiB
Plaintext
|
// display.c
|
||
|
|
||
|
/*
|
||
|
* Copyright (c) 2014-2017 Cesanta Software Limited
|
||
|
* All rights reserved
|
||
|
*/
|
||
|
|
||
|
#include <Arduino.h>
|
||
|
#include <Adafruit_SSD1306.h>
|
||
|
|
||
|
#include "common/cs_dbg.h"
|
||
|
#include "fw/src/mgos_app.h"
|
||
|
#include "fw/src/mgos_timers.h"
|
||
|
|
||
|
Adafruit_SSD1306 *d1 = nullptr, *d2 = nullptr;
|
||
|
|
||
|
static void timer_cb(void *arg);
|
||
|
|
||
|
void setup(void) {
|
||
|
// I2C
|
||
|
d1 = new Adafruit_SSD1306(4 /* RST GPIO */, Adafruit_SSD1306::RES_128_64);
|
||
|
|
||
|
if (d1 != nullptr) {
|
||
|
d1->begin(SSD1306_SWITCHCAPVCC, 0x3D, true /* reset */);
|
||
|
d1->display();
|
||
|
}
|
||
|
|
||
|
// SPI.
|
||
|
// On ESP8266 SPI and I2C cannot be enabled at the same time by default
|
||
|
// because their pins overlap.
|
||
|
// You will need to disable I2C and enable SPI:
|
||
|
// mos config-set i2c.enable=false spi.enable=true
|
||
|
d2 = new Adafruit_SSD1306(21 /* DC */, 5 /* RST */, 17 /* CS */,
|
||
|
Adafruit_SSD1306::RES_128_32);
|
||
|
|
||
|
if (d2 != nullptr) {
|
||
|
d2->begin(SSD1306_SWITCHCAPVCC, 0 /* unused */, true /* reset */);
|
||
|
d2->display();
|
||
|
}
|
||
|
|
||
|
mgos_set_timer(1000 /* ms */, true /* repeat */, timer_cb, NULL);
|
||
|
}
|
||
|
|
||
|
static void show_num(Adafruit_SSD1306 *d, const char *s, int i) {
|
||
|
d->clearDisplay();
|
||
|
d->setTextSize(2);
|
||
|
d->setTextColor(WHITE);
|
||
|
d->setCursor(d->width() / 4, d->height() / 4);
|
||
|
d->printf("%s%d", s, i);
|
||
|
d->display();
|
||
|
}
|
||
|
|
||
|
static void timer_cb(void *arg) {
|
||
|
static int i = 0, j = 0;
|
||
|
if (d1 != nullptr) show_num(d1, "i = ", i);
|
||
|
if (d2 != nullptr) show_num(d2, "j = ", j);
|
||
|
LOG(LL_INFO, ("i = %d, j = %d", i, j));
|
||
|
i++;
|
||
|
j++;
|
||
|
(void) arg;
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
void loop(void) {
|
||
|
/* For now, do not use delay() inside loop, use timers instead. */
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#if 0
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#include "common/cs_dbg.h"
|
||
|
#include "fw/src/mgos_app.h"
|
||
|
#include "fw/src/mgos_i2c.h"
|
||
|
#include "fw/src/mgos_mongoose.h"
|
||
|
#include "fw/src/mgos_utils.h"
|
||
|
|
||
|
static struct mgos_i2c *uOLED_i2c;
|
||
|
|
||
|
static uint8_t from_hex(const char *s) {
|
||
|
#define HEXTOI(x) (x >= '0' && x <= '9' ? x - '0' : x - 'W')
|
||
|
int a = tolower(*(const unsigned char *) s);
|
||
|
int b = tolower(*(const unsigned char *) (s + 1));
|
||
|
return (HEXTOI(a) << 4) | HEXTOI(b);
|
||
|
}
|
||
|
|
||
|
enum mgos_app_init_result uOLED_i2cSetup() {
|
||
|
struct sys_config_i2c *cfg;
|
||
|
|
||
|
uOLED_i2c = mgos_i2c_create(const struct sys_config_i2c *cfg);
|
||
|
return MGOS_APP_INIT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
void uOLED_send_hexstring(struct mg_str *s) {
|
||
|
bool ret = false;
|
||
|
LOG(LL_INFO, ("Got: [%.*s]", (int) s->len, s->p));
|
||
|
if (s->len >= 2) {
|
||
|
int j = 0;
|
||
|
// struct mgos_i2c *i2c = mgos_i2c_get_global();
|
||
|
for (size_t i = 0; i < s->len; i += 2, j++) {
|
||
|
((uint8_t *) s->p)[j] = from_hex(s->p + i);
|
||
|
}
|
||
|
ret = mgos_i2c_write(uOLED_i2c, s->p[0], s->p + 1, j, true /* stop */);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** \brief Write a byte over I2C
|
||
|
Write a byte to I2C device _address_. The DC byte determines whether
|
||
|
the data being sent is a command or display data. Use either I2C_COMMAND
|
||
|
or I2C_DATA in that parameter. The data byte can be any 8-bit value.
|
||
|
**/
|
||
|
void uOLED_i2cWrite(byte address, byte dc, byte data)
|
||
|
{
|
||
|
Wire.beginTransmission(address);
|
||
|
Wire.write(dc); // If data dc = 0, if command dc = 0x40
|
||
|
Wire.write(data);
|
||
|
Wire.endTransmission();
|
||
|
}
|
||
|
|
||
|
#endif
|