-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/embedded'
Showing
15 changed files
with
498 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
tools/venv/* | ||
|
||
.idea |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#include "edstream.h" | ||
#include "edstream_hal.h" | ||
|
||
#include <ssd1306.h> | ||
|
||
#define LOG_LOCAL_LEVEL ESP_LOG_ERROR | ||
#include "esp_log.h" | ||
|
||
void receiver(void *pvParameters) | ||
{ | ||
struct eds_hal_config eds_hal_conf = eds_hal_default(); | ||
eds_hal_init(&eds_hal_conf); | ||
|
||
ssd1306_128x64_i2c_init(); | ||
|
||
ssd1306_clearScreen(); | ||
|
||
uint8_t cmd[512]; | ||
int read; | ||
|
||
while(true) { | ||
vTaskDelay(1); | ||
read = eds_hal_recv(cmd, 512); | ||
if (read <= 0) continue; | ||
ESP_LOGD("RX", "Read bytes: %d", read); | ||
eds_decode_message(cmd, read); | ||
} | ||
|
||
vTaskDelete(NULL); | ||
} | ||
|
||
void app_main() | ||
{ | ||
xTaskCreate(receiver, "receiver", 8192, NULL, 0, NULL); // Yep, this is a huge amount of memory | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* EDStream HAL implementation | ||
* (c) 2021 - Project EDStream | ||
* | ||
* ESP32 I2C_0 and UART_0 | ||
*/ | ||
|
||
#include "edstream_hal.h" | ||
|
||
#define LOG_LOCAL_LEVEL ESP_LOG_NONE | ||
#include "esp_log.h" | ||
#include "ssd1306.h" | ||
#include "driver/uart.h" | ||
|
||
static struct eds_hal_config configuration; | ||
|
||
static uint8_t uart_num_mem; | ||
static QueueHandle_t queue_handle; | ||
|
||
void eds_hal_init(const struct eds_hal_config *config) { | ||
|
||
configuration = *config; | ||
|
||
// I2C | ||
ssd1306_platform_i2cConfig_t cfg = { | ||
.sda = config->i2c_pins.sda, | ||
.scl = config->i2c_pins.scl | ||
}; | ||
ssd1306_platform_i2cInit(config->i2c_num, 0, &cfg); | ||
|
||
// UART | ||
ESP_ERROR_CHECK(uart_param_config(config->uart_num, &(config->uart_conf))); | ||
ESP_ERROR_CHECK(uart_set_pin(config->uart_num, config->uart_pins.tx, config->uart_pins.rx, config->uart_pins.rts, config->uart_pins.cts)); | ||
ESP_ERROR_CHECK(uart_driver_install(config->uart_num, config->uart_buf_size, config->uart_buf_size, 10, &queue_handle, 0)); | ||
uart_num_mem = config->uart_num; | ||
} | ||
|
||
int eds_hal_send_byte(uint8_t x) { | ||
return eds_hal_send(&x, 1); | ||
} | ||
|
||
int eds_hal_send(const uint8_t *src, int n) { | ||
size_t res = uart_write_bytes(uart_num_mem, (const char*) src, n); | ||
uart_wait_tx_done(uart_num_mem, 100); // timeout of 100 ticks | ||
return res; | ||
} | ||
|
||
int eds_hal_recv(uint8_t *dst, int n) { | ||
return uart_read_bytes(UART_NUM_0, dst, n, 100 / portTICK_RATE_MS); | ||
} | ||
|
||
int eds_hal_display_show(const uint8_t *frame) { | ||
ssd1306_drawBuffer(0, 0, OLED_W, OLED_H, frame); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,57 @@ | ||
#ifndef __EDSTREAM_HAL | ||
#define __EDSTREAM_HAL | ||
|
||
#include "stdint.h" | ||
#include "stdbool.h" | ||
#include "driver/uart.h" | ||
|
||
#define OLED_W (128) | ||
#define OLED_H (64) | ||
#define UART_NUM (UART_NUM_0) // Connected to CP2102 | ||
#define UART_BUF_SIZE (2048) | ||
|
||
static struct _i2c_pins { | ||
uint8_t sda; | ||
uint8_t scl; | ||
}; | ||
|
||
static struct _uart_pins { | ||
int tx; // -1 is valid | ||
int rx; | ||
int rts; | ||
int cts; | ||
}; | ||
|
||
struct eds_hal_config { | ||
uint8_t i2c_num; | ||
uint8_t uart_num; | ||
struct _i2c_pins i2c_pins; | ||
struct _uart_pins uart_pins; | ||
uart_config_t uart_conf; | ||
uint16_t uart_buf_size; | ||
}; | ||
#define eds_hal_default() ((struct eds_hal_config){ .i2c_num=0, \ | ||
.i2c_pins = {.sda=21, .scl=22}, \ | ||
.uart_conf = {.baud_rate=115200, .data_bits=UART_DATA_8_BITS, .parity=UART_PARITY_DISABLE, \ | ||
.stop_bits=UART_STOP_BITS_1, .flow_ctrl=UART_HW_FLOWCTRL_DISABLE, .rx_flow_ctrl_thresh=122}, \ | ||
.uart_num = UART_NUM, \ | ||
.uart_pins = {.tx=UART_PIN_NO_CHANGE, .rx=UART_PIN_NO_CHANGE, .rts=18, .cts=19}, \ | ||
.uart_buf_size = UART_BUF_SIZE \ | ||
}) | ||
|
||
void eds_hal_init(const struct eds_hal_config *config); | ||
|
||
int eds_hal_send(uint8_t *src, int i); | ||
int eds_hal_send_byte(uint8_t x); | ||
int eds_hal_recv(uint8_t *dst, int i); | ||
int eds_hal_display_show(uint8_t *frame); | ||
|
||
/* | ||
* @return Number of sent bytes to UART | ||
*/ | ||
int eds_hal_send(const uint8_t *src, int n); | ||
|
||
/* | ||
* @return Number of read bytes from UART | ||
*/ | ||
int eds_hal_recv(uint8_t *dst, int n); | ||
int eds_hal_display_show(const uint8_t *frame); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
""" | ||
daemon.py | ||
MQTT bridge daemon for remote communication with edstream controller. | ||
""" | ||
|
||
__authors__ = "5H wild nerds" | ||
|
||
import argparse | ||
import logging | ||
import paho.mqtt.client as mqtt | ||
import serial | ||
from queue import Queue | ||
import threading | ||
from bitmap_over_uart import ProtocolHandler | ||
from io import BytesIO | ||
from PIL import Image | ||
|
||
class EdstreamMQTT(mqtt.Client): | ||
def __init__(self, frame_queue: Queue, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.frame_queue = frame_queue | ||
|
||
def on_connect(self, mqttc, obj, flags, rc): | ||
logging.info(f"Connected to broker with return code {rc}") | ||
self.subscribe("edstream") | ||
|
||
def on_disconnect(self, mqttc, userdata, rc): | ||
if rc != 0: | ||
logging.warning(f"Unexpected disconnection from server. Result code {rc}") | ||
else: | ||
logging.info("Disconnected from broker") | ||
|
||
def on_message(self, mqttc, userdata, message: mqtt.MQTTMessage): | ||
logging.debug(f"Received message from topic {message.topic}") | ||
self.frame_queue.put(message.payload) | ||
|
||
|
||
def main(port, broker_addr): | ||
with serial.Serial(port, baudrate=115200) as s: | ||
frame_queue = Queue() | ||
client = EdstreamMQTT(frame_queue, protocol=mqtt.MQTTv311) | ||
client.connect(broker_addr) | ||
phandler = ProtocolHandler(s) | ||
|
||
t = threading.Thread(target=client.loop_forever) | ||
t.start() | ||
|
||
s.flushInput() | ||
|
||
try: | ||
while True: | ||
frame = frame_queue.get() | ||
|
||
stdin_img_bytes = BytesIO(frame) | ||
img = Image.open(stdin_img_bytes) | ||
|
||
phandler.send_bitmap(img.tobytes()) | ||
|
||
phandler.start() | ||
|
||
except KeyboardInterrupt: | ||
pass | ||
|
||
client.disconnect() | ||
|
||
if __name__ == '__main__': | ||
logging.basicConfig(level=logging.DEBUG) | ||
|
||
parser = argparse.ArgumentParser() | ||
parser.add_argument('-p', '--port', help='Serial port name', type=str, default="/dev/cu.SLAB_USBtoUART") | ||
parser.add_argument('-b', '--broker', help='Broker address', type=str, default="mqtt.ssh.edu.it") | ||
|
||
args = parser.parse_args() | ||
|
||
main(args.port, args.broker) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
""" | ||
Tool for UART debugging. Waits for a string on stdin representing the hex | ||
dump of a bytes array. | ||
The tool only writes on the serial port stream, a monitor should read the debug | ||
response from the display controller (e.g. ESP32). | ||
""" | ||
|
||
__authors__ = "5H wild nerds" | ||
|
||
import serial | ||
import argparse | ||
import threading | ||
import logging | ||
|
||
def send_raw_byte(port: serial.Serial, hex_repr: str): | ||
x = bytes.fromhex(hex_repr) | ||
port.write(x) | ||
|
||
def speed_test(port: serial.Serial): | ||
port.write(bytes([0])) | ||
for x in range(256): | ||
port.write(x.to_bytes(1, 'little')) | ||
|
||
def main(port: str, speed: int, speedtest): | ||
with serial.Serial(port, speed) as s: | ||
if speedtest: | ||
speed_test(s) | ||
|
||
while True: | ||
payload = eval(input(">> ")) # 'ff'*256 (string*number of times) is allowed | ||
print(f">> {payload}") | ||
send_raw_byte(s, payload) | ||
|
||
if __name__ == '__main__': | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('-p', '--port', help='Serial port name', default="/dev/cu.SLAB_USBtoUART") | ||
parser.add_argument('-b', '--baudrate', help='Serial port baudrate', type=int, default=115200) | ||
parser.add_argument('-s', '--speedtest', help='Performs a speed test', default=False, action='store_true') | ||
parser.add_argument('-d', '--display', help='Print incoming bytes using a separate thread', default=False, action='store_true') | ||
|
||
args = parser.parse_args() | ||
main(args.port, args.baudrate, args.speedtest) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
""" | ||
rotate_pixel.py script | ||
Converts GLCD or standard horizontal bitmap images to SSD1306 format. | ||
Each byte represents a vertical pixel. Least significant bit is the first row, | ||
therefore a simple rotation of 90 degrees clockwise is needed which is a trivial | ||
operation to perform using Pillow. | ||
You can invoke this script in your shell pipeline, or use it as a standalone function. | ||
""" | ||
|
||
from PIL import Image | ||
import argparse | ||
import sys | ||
from io import BytesIO | ||
|
||
def GLCD_to_SSD1306(image: Image) -> Image: | ||
output = bytearray() | ||
|
||
for bn in range(8): #block number | ||
block: Image = image.crop((0, bn*8, 128, bn*8+8)) | ||
rblock: Image = block.rotate(-90, expand=True) | ||
output += rblock.tobytes() | ||
|
||
reassembled: Image = Image.frombytes('1', (64, 128), bytes(output)) | ||
return reassembled | ||
|
||
|
||
def main(use_stdin: bool, image: str): | ||
if use_stdin: | ||
stdin_img_bytes = BytesIO(sys.stdin.buffer.read()) | ||
img = Image.open(stdin_img_bytes) | ||
else: | ||
img = Image.open(image) | ||
|
||
reassembled: Image = GLCD_to_SSD1306(img) | ||
|
||
img_byte_array = BytesIO() | ||
reassembled.save(img_byte_array, format='bmp') | ||
stdout_img_bytes: bytes = img_byte_array.getvalue() | ||
sys.stdout.buffer.write(stdout_img_bytes) | ||
|
||
|
||
if __name__ == '__main__': | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('-n', '--nostdin', default=True, action='store_false') | ||
parser.add_argument('-i', '--image', default=None, required=False, type=str) | ||
|
||
args = parser.parse_args() | ||
|
||
main(args.nostdin, args.image) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters