mirror of
https://github.com/usatiuk/cardboy.git
synced 2025-10-28 15:17:48 +01:00
less crap spi
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
|
||||
#ifndef CB_DISP_TOOLS_HPP
|
||||
#define CB_DISP_TOOLS_HPP
|
||||
#include <display.hpp>
|
||||
|
||||
#include <display.hpp>
|
||||
|
||||
class DispTools {
|
||||
public:
|
||||
@@ -14,34 +14,28 @@ public:
|
||||
void clear() {
|
||||
for (int y = 0; y < DISP_HEIGHT; y++) {
|
||||
for (int x = 0; x < DISP_WIDTH; x++) {
|
||||
disp_frame[y][x] = 1;
|
||||
SMD::get().set_pixel(x, y, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
bool get_pixel(int x, int y) {
|
||||
// if (x < 0 || x >= DISP_WIDTH || y < 0 || y >= DISP_HEIGHT)
|
||||
// assert(false);
|
||||
return disp_frame[y][x];
|
||||
return true;
|
||||
// return disp_frame[y][x];
|
||||
}
|
||||
void reset_pixel(int x, int y) {
|
||||
// if (x < 0 || x >= DISP_WIDTH || y < 0 || y >= DISP_HEIGHT)
|
||||
// assert(false);
|
||||
|
||||
disp_frame[y][x] = true;
|
||||
SMD::get().set_pixel(x, y, false);
|
||||
}
|
||||
void set_pixel(int x, int y) {
|
||||
// if (x < 0 || x >= DISP_WIDTH || y < 0 || y >= DISP_HEIGHT)
|
||||
// assert(false);
|
||||
//
|
||||
disp_frame[y][x] = false;
|
||||
SMD::get().set_pixel(x, y, true);
|
||||
}
|
||||
void draw_rectangle(int x1, int y1, int x2, int y2);
|
||||
void draw_line(int x1, int y1, int x2, int y2);
|
||||
void draw_circle(int x, int y, int r);
|
||||
void draw_to_display();
|
||||
|
||||
private:
|
||||
SMD::disp_frame_t disp_frame;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -17,12 +17,28 @@
|
||||
|
||||
class SMD {
|
||||
public:
|
||||
using disp_line_t = std::bitset<400>;
|
||||
using disp_frame_t = std::array<disp_line_t, 240>;
|
||||
static constexpr size_t kLineBytes = DISP_WIDTH / 8;
|
||||
static constexpr size_t kLineMultiSingle = (kLineBytes + 2);
|
||||
static constexpr size_t kLineDataBytes = kLineMultiSingle * DISP_HEIGHT + 2;
|
||||
|
||||
static DMA_ATTR uint8_t dma_buf[SMD::kLineDataBytes];
|
||||
|
||||
static SMD& get();
|
||||
void clear();
|
||||
void draw(const disp_frame_t& frame);
|
||||
void draw();
|
||||
|
||||
void set_pixel(int x, int y, bool value) {
|
||||
assert(x >= 0 && x < DISP_WIDTH && y >= 0 && y < DISP_HEIGHT);
|
||||
|
||||
unsigned lineIdx = 2 + kLineMultiSingle * y + (x / 8);
|
||||
unsigned bitIdx = 1 << (7 - (x % 8)) % 8;
|
||||
|
||||
if (value) {
|
||||
dma_buf[lineIdx] &= ~bitIdx;
|
||||
} else {
|
||||
dma_buf[lineIdx] |= bitIdx;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SMD();
|
||||
@@ -34,14 +50,8 @@ private:
|
||||
.queue_size = 3,
|
||||
// .pre_cb = lcd_spi_pre_transfer_callback, //Specify pre-transfer callback to handle D/C line
|
||||
};
|
||||
static constexpr size_t kLineBytes = DISP_WIDTH / 8;
|
||||
spi_device_handle_t _spi;
|
||||
bool _vcom = false;
|
||||
|
||||
static constexpr size_t kLineData = (kLineBytes + 4);
|
||||
std::array<uint8_t, kLineData> buf{};
|
||||
|
||||
std::array<uint8_t, kLineBytes> prep_line(const SMD::disp_line_t& line);
|
||||
spi_device_handle_t _spi;
|
||||
bool _vcom = false;
|
||||
};
|
||||
|
||||
class SMDSurface : public Surface<SMDSurface, BwPixel>, public StandardEventQueue<SMDSurface> {
|
||||
|
||||
@@ -13,53 +13,4 @@ DispTools& DispTools::get() {
|
||||
return disp_tools;
|
||||
}
|
||||
|
||||
void DispTools::draw_rectangle(int x1, int y1, int x2, int y2) {
|
||||
int dy = y2 - y1;
|
||||
while (std::abs(dy) > 0) {
|
||||
draw_line(x1, y1 + dy, x2, y1 + dy);
|
||||
dy += (dy > 0) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
void DispTools::draw_line(int x1, int y1, int x2, int y2) {
|
||||
int dx = x2 - x1;
|
||||
int dy = y2 - y1;
|
||||
int a = 0, b = 0, diff = 0;
|
||||
|
||||
if (dx == 0) {
|
||||
while (dy != 0) {
|
||||
set_pixel(x1, y1 + dy);
|
||||
dy += (dy > 0) ? -1 : 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (dy == 0) {
|
||||
while (dx != 0) {
|
||||
set_pixel(x1 + dx, y1);
|
||||
dx += (dx > 0) ? -1 : 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while (std::abs(a) <= std::abs(dx) && std::abs(b) <= std::abs(dy)) {
|
||||
set_pixel(x1 + a, y1 + b);
|
||||
if (diff < 0) {
|
||||
a += (dx > 0) ? 1 : -1;
|
||||
diff += std::abs(dy);
|
||||
} else {
|
||||
b += (dy > 0) ? 1 : -1;
|
||||
diff -= std::abs(dx);
|
||||
}
|
||||
}
|
||||
}
|
||||
void DispTools::draw_circle(int x, int y, int r) {
|
||||
if (r > 181)
|
||||
return;
|
||||
int dy = -r;
|
||||
while (dy <= r) {
|
||||
int dx = static_cast<int>(std::sqrt(r * r - dy * dy));
|
||||
draw_line(x - dx, y + dy, x + dx, y + dy);
|
||||
dy++;
|
||||
}
|
||||
}
|
||||
void DispTools::draw_to_display() { SMD::get().draw(disp_frame); }
|
||||
void DispTools::draw_to_display() { SMD::get().draw(); }
|
||||
|
||||
@@ -11,21 +11,12 @@
|
||||
|
||||
#include "disp_tools.hpp"
|
||||
|
||||
DMA_ATTR uint8_t SMD::dma_buf[SMD::kLineDataBytes]{};
|
||||
|
||||
// This solution is attributed to Rich Schroeppel in the Programming Hacks section
|
||||
// TODO: Why does the device flag not work?
|
||||
unsigned char reverse_bits3(unsigned char b) { return (b * 0x0202020202ULL & 0x010884422010ULL) % 0x3ff; }
|
||||
|
||||
std::array<uint8_t, SMD::kLineBytes> SMD::prep_line(const SMD::disp_line_t& line) {
|
||||
std::array<uint8_t, kLineBytes> data{};
|
||||
for (int i = 0; i < DISP_WIDTH; i++) {
|
||||
data[i / 8] = data[i / 8] | (line[i] << (i % 8));
|
||||
}
|
||||
for (int i = 0; i < kLineBytes; i++) {
|
||||
data[i] = reverse_bits3(data[i]);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
SMD& SMD::get() {
|
||||
static SMD smd;
|
||||
return smd;
|
||||
@@ -38,6 +29,12 @@ SMD::SMD() {
|
||||
ESP_ERROR_CHECK(gpio_set_direction(SPI_DISP_DISP, GPIO_MODE_OUTPUT));
|
||||
ESP_ERROR_CHECK(gpio_set_level(SPI_DISP_DISP, 1));
|
||||
ESP_ERROR_CHECK(gpio_hold_en(SPI_DISP_DISP));
|
||||
|
||||
for (uint8_t i = 0; i < DISP_HEIGHT; i++) {
|
||||
dma_buf[kLineMultiSingle * i + 1] = reverse_bits3(i + 1);
|
||||
dma_buf[2 + kLineMultiSingle * i + kLineBytes] = 0;
|
||||
}
|
||||
dma_buf[kLineDataBytes - 1] = 0;
|
||||
}
|
||||
|
||||
void SMD::clear() {
|
||||
@@ -50,25 +47,15 @@ void SMD::clear() {
|
||||
ESP_ERROR_CHECK(spi_device_transmit(_spi, &t));
|
||||
}
|
||||
|
||||
void SMD::draw(const disp_frame_t& frame) {
|
||||
void SMD::draw() {
|
||||
_vcom = !_vcom;
|
||||
for (uint8_t i = 0; i < DISP_HEIGHT; i++) {
|
||||
spi_transaction_t t{};
|
||||
spi_transaction_t t{};
|
||||
|
||||
t.tx_buffer = buf.data();
|
||||
t.length = buf.size() * 8;
|
||||
t.tx_buffer = dma_buf;
|
||||
t.length = SMD::kLineDataBytes * 8;
|
||||
dma_buf[0] = 0b10000000 | (_vcom << 6);
|
||||
|
||||
buf[0] = 0b10000000 | (_vcom << 6);
|
||||
buf[1] = reverse_bits3(i + 1);
|
||||
|
||||
auto prepared = prep_line(frame.at(i));
|
||||
memcpy(buf.data() + 2, prepared.data(), kLineBytes);
|
||||
|
||||
buf[2 + kLineBytes] = 0;
|
||||
buf[2 + kLineBytes + 1] = 0;
|
||||
|
||||
ESP_ERROR_CHECK(spi_device_transmit(_spi, &t));
|
||||
}
|
||||
ESP_ERROR_CHECK(spi_device_transmit(_spi, &t));
|
||||
}
|
||||
|
||||
void SMDSurface::draw_pixel_impl(unsigned x, unsigned y, const BwPixel& pixel) {
|
||||
|
||||
@@ -45,7 +45,7 @@ FbTty tty;
|
||||
extern "C" void app_main() {
|
||||
esp_pm_config_t pm_config = {
|
||||
.max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, .min_freq_mhz = 16, .light_sleep_enable = true};
|
||||
ESP_ERROR_CHECK(esp_pm_configure(&pm_config));
|
||||
// ESP_ERROR_CHECK(esp_pm_configure(&pm_config));
|
||||
printf("Hello world!\n");
|
||||
// TODO: Where to put that?
|
||||
ESP_ERROR_CHECK(esp_sleep_enable_gpio_wakeup());
|
||||
@@ -64,8 +64,8 @@ extern "C" void app_main() {
|
||||
SMD::get();
|
||||
SMD::get().clear();
|
||||
DispTools::get().clear();
|
||||
DispTools::get().draw_line(0, 0, 399, 239);
|
||||
DispTools::get().draw_circle(100, 100, 20);
|
||||
// DispTools::get().draw_line(0, 0, 399, 239);
|
||||
// DispTools::get().draw_circle(100, 100, 20);
|
||||
DispTools::get().draw_to_display();
|
||||
tty.putstr("Hello\nworld!");
|
||||
DispTools::get().draw_to_display();
|
||||
|
||||
Reference in New Issue
Block a user