Add i2c update function with some stop bit shenanigans
This commit is contained in:
parent
5c963b0592
commit
c8d1093faa
|
@ -3,7 +3,9 @@
|
|||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
#include <functional>
|
||||
#include <array>
|
||||
#include <span>
|
||||
|
||||
namespace Framebuffer {
|
||||
class FramebufferListener {
|
||||
|
@ -26,20 +28,29 @@ namespace Framebuffer {
|
|||
static constexpr size_t ROWS = (FB_HEIGHT/ROW_HEIGHT);
|
||||
static constexpr size_t SIZE = FB_WIDTH * ROWS;
|
||||
std::array<uint8_t, SIZE> m_buffer;
|
||||
FramebufferListener &m_listener;
|
||||
std::function<void(std::span<uint8_t>)> m_listener_update;
|
||||
|
||||
void update_listener() {
|
||||
m_listener.update(0, 0, m_buffer.data(), m_buffer.size());
|
||||
m_listener_update(m_buffer);
|
||||
}
|
||||
|
||||
public:
|
||||
Framebuffer(FramebufferListener &listener)
|
||||
: m_listener(listener) {
|
||||
Framebuffer(std::function<void(std::span<uint8_t>)> f)
|
||||
: m_listener_update(f) {
|
||||
}
|
||||
|
||||
void fill(uint8_t val) { FrameBufferBase::fill(m_buffer.data(), m_buffer.size(), val); }
|
||||
void putc(size_t x, size_t y, char c) { FrameBufferBase::putc(m_buffer.data(), ROW_HEIGHT, m_buffer.size(), x, y, c); }
|
||||
void puts(size_t x, size_t y, const char *s) { FrameBufferBase::putc(m_buffer.data(), ROW_HEIGHT, m_buffer.size(), x, y, s); }
|
||||
void fill(uint8_t val) {
|
||||
FrameBufferBase::fill(m_buffer.data(), m_buffer.size(), val);
|
||||
update_listener();
|
||||
}
|
||||
void putc(size_t x, size_t y, char c) {
|
||||
FrameBufferBase::putc(m_buffer.data(), ROW_HEIGHT, m_buffer.size(), x, y, c);
|
||||
update_listener();
|
||||
}
|
||||
void puts(size_t x, size_t y, const char *s) {
|
||||
FrameBufferBase::putc(m_buffer.data(), ROW_HEIGHT, m_buffer.size(), x, y, s);
|
||||
update_listener();
|
||||
}
|
||||
uint8_t *data() { return m_buffer.data(); }
|
||||
size_t size() { return m_buffer.size(); }
|
||||
};
|
||||
|
|
21
src/main.cc
21
src/main.cc
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "hardware/gpio.h"
|
||||
#include "hardware/i2c.h"
|
||||
#include "hardware/regs/i2c.h"
|
||||
#include "pico/time.h"
|
||||
#include "pico/types.h"
|
||||
|
||||
|
@ -16,7 +17,6 @@
|
|||
|
||||
static bool failure = false;
|
||||
|
||||
|
||||
static uint8_t encoder_pos = 0;
|
||||
|
||||
void irq_callback(uint gpio, uint32_t events) {
|
||||
|
@ -90,7 +90,7 @@ static void write_cmd(uint8_t cmd) {
|
|||
}
|
||||
|
||||
ssd1306::ssd1306()
|
||||
: m_frame_buffer(*this) {
|
||||
: m_frame_buffer(std::bind(&ssd1306::update, this, std::placeholders::_1)) {
|
||||
write_cmd(SET_DISP | 0x00); // Off
|
||||
|
||||
write_cmd(SET_MUX_RATIO); // The height
|
||||
|
@ -157,10 +157,21 @@ void ssd1306::flush() {
|
|||
}
|
||||
}
|
||||
|
||||
void ssd1306::update(size_t x, size_t y, uint8_t *data, size_t len) {
|
||||
set_coordinates(x, 128, y, 7);
|
||||
void ssd1306::update(std::span<uint8_t> data) {
|
||||
set_coordinates(0, 128, 0, 7);
|
||||
write_cmd(SET_MEM_ADDR);
|
||||
write_cmd(0x00); // Horizontal
|
||||
|
||||
// TODO: Something with nostop and then spitting raw bytes? might work...
|
||||
uint8_t write = 0x40;
|
||||
i2c_write_blocking(i2c0, ADDR, &write, 1, true);
|
||||
i2c_write_raw_blocking(i2c0, data.data(), data.size()-1);
|
||||
|
||||
while (!i2c_get_write_available(i2c0)) tight_loop_contents();
|
||||
|
||||
// Write a stop bit with the final byte
|
||||
i2c_get_hw(i2c0)->data_cmd = 1 << I2C_IC_DATA_CMD_STOP_LSB | data.data()[data.size()-1];
|
||||
|
||||
// https://github.com/raspberrypi/pico-sdk/issues/812#issuecomment-1983833379
|
||||
// Wait for the stop bit to clock out
|
||||
while (!(i2c0->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_STOP_DET_BITS)) tight_loop_contents();
|
||||
}
|
||||
|
|
|
@ -35,6 +35,6 @@ public:
|
|||
void flush();
|
||||
void set_coordinates(uint8_t start_x, uint8_t end_x, uint8_t start_y, uint8_t end_y);
|
||||
|
||||
void update(size_t x, size_t y, uint8_t *data, size_t len);
|
||||
void update(std::span<uint8_t> data);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue