223 lines
5.2 KiB
C++

#include "cardslot.h"
#include "display.h"
#include "flash.h"
#include "icons.h"
#include "pixelstream.h"
#include <pico/binary_info.h>
#include <pico/stdlib.h>
#include <tusb.h>
using namespace lib;
namespace
{
bi_decl(bi_program_feature_group(0x1111, 0, "Display Pinout"));
bi_decl(bi_ptr_int32(0x1111, 0, DISPLAY_SCK, 2));
bi_decl(bi_ptr_int32(0x1111, 0, DISPLAY_TX, 3));
bi_decl(bi_ptr_int32(0x1111, 0, DISPLAY_CS, 5));
bi_decl(bi_ptr_int32(0x1111, 0, DISPLAY_DC, 6));
bi_decl(bi_program_feature_group(0x1111, 1, "Flash Pinout"));
bi_decl(bi_ptr_int32(0x1111, 1, FLASH_SCK, 26));
bi_decl(bi_ptr_int32(0x1111, 1, FLASH_TX, 27));
bi_decl(bi_ptr_int32(0x1111, 1, FLASH_RX, 28));
bi_decl(bi_ptr_int32(0x1111, 1, FLASH_CS, 29));
bi_decl(bi_program_feature_group(0x1111, 2, "Buttons"));
bi_decl(bi_ptr_int32(0x1111, 2, BUTTON_LEFT, 20));
bi_decl(bi_ptr_int32(0x1111, 2, BUTTON_MIDDLE, 0));
bi_decl(bi_ptr_int32(0x1111, 2, BUTTON_RIGHT, 8));
Display display(DISPLAY_SCK, DISPLAY_TX, DISPLAY_CS, DISPLAY_DC, 120000000);
Flash flash(FLASH_SCK, FLASH_TX, FLASH_RX, FLASH_CS, 70000000);
enum class RX
{
WAITING,
GETTING_NAME,
GETTING_IMAGE
};
struct
{
struct
{
uint8_t buffer[32];
uint8_t size;
uint8_t written;
} name;
struct
{
size_t written = 0;
uint16_t page_index = 0;
} image;
RX state = RX::WAITING;
int32_t card_index = 0;
} rx;
}
int main()
{
gpio_set_function(BUTTON_LEFT, GPIO_FUNC_SIO);
gpio_set_function(BUTTON_MIDDLE, GPIO_FUNC_SIO);
gpio_set_function(BUTTON_RIGHT, GPIO_FUNC_SIO);
gpio_set_dir(BUTTON_LEFT, GPIO_IN);
gpio_set_dir(BUTTON_MIDDLE, GPIO_IN);
gpio_set_dir(BUTTON_RIGHT, GPIO_IN);
gpio_pull_up(BUTTON_LEFT);
gpio_pull_up(BUTTON_MIDDLE);
gpio_pull_up(BUTTON_RIGHT);
tusb_rhport_init_t dev_init
= { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO };
tud_init(0);
uint16_t card_index = 0;
absolute_time_t last_press = get_absolute_time();
const auto& pixel_fn = [](void* pixels, uint8_t data)
{ static_cast<PixelStream*>(pixels)->write(data); };
{
auto pixels = display.pixels();
CardSlot(flash, 0).each_pixel(flash, pixel_fn, &pixels);
}
while (true)
{
absolute_time_t current = get_absolute_time();
if (!gpio_get(BUTTON_LEFT)
&& absolute_time_diff_us(last_press, current) > 1000 * 10)
{
do
{
card_index -= 1;
if (card_index >= CardSlot::MAX_CARDS)
{
card_index = CardSlot::MAX_CARDS - 1;
}
} while (!CardSlot(flash, card_index).is_used());
auto pixels = display.pixels();
CardSlot(flash, card_index).each_pixel(flash, pixel_fn, &pixels);
last_press = current;
}
if (!gpio_get(BUTTON_RIGHT)
&& absolute_time_diff_us(last_press, current) > 1000 * 10)
{
do
{
card_index += 1;
if (card_index >= CardSlot::MAX_CARDS)
{
card_index = 0;
}
} while (!CardSlot(flash, card_index).is_used());
auto pixels = display.pixels();
CardSlot(flash, card_index).each_pixel(flash, pixel_fn, &pixels);
last_press = current;
}
tud_task();
}
}
void tud_vendor_rx_cb(uint8_t itf, const uint8_t* buffer, uint16_t bufsize)
{
for (size_t read = 0; read < bufsize;)
{
if (rx.state == RX::WAITING)
{
// special command to mark all as unused
if (buffer[0] == 0x42)
{
for (int i = 0; i < CardSlot::MAX_CARDS; i++)
{
CardSlot slot(flash, i);
slot.mark_unused(flash);
}
return;
}
rx.state = RX::GETTING_NAME;
rx.card_index = CardSlot::get_unused(flash);
rx.name.size = buffer[0] > 32 ? 32 : buffer[0];
rx.name.written = 0;
read += 1;
}
else if (rx.state == RX::GETTING_NAME)
{
size_t copy_size = bufsize - read < rx.name.size - rx.name.written
? bufsize - read
: rx.name.size - rx.name.written;
memcpy(rx.name.buffer + rx.name.written, buffer + read, copy_size);
read += copy_size;
rx.name.written += copy_size;
if (rx.name.written == rx.name.size)
{
rx.state = RX::GETTING_IMAGE;
rx.image.written = 0;
rx.image.page_index
= CardSlot(flash, rx.card_index).get_image_start_page_index();
if (rx.card_index >= 0)
{
CardSlot slot(flash, rx.card_index);
slot.erase(flash);
slot.set_name(rx.name.buffer, rx.name.size);
slot.save_data(flash);
}
}
}
else
{
size_t copy_size = bufsize - read < Flash::Page::SIZE - rx.image.written
? bufsize - read
: Flash::Page::SIZE - rx.image.written;
memcpy(flash.page() + rx.image.written, buffer + read, copy_size);
read += copy_size;
rx.image.written += copy_size;
if (rx.image.written == 256)
{
if (rx.card_index >= 0)
{
flash.write_page(rx.image.page_index);
}
rx.image.page_index += 1;
rx.image.written = 0;
if (rx.image.page_index
- CardSlot(flash, rx.card_index).get_image_start_page_index()
== CardSlot::IMAGE_PAGE_COUNT)
{
rx.state = RX::WAITING;
}
}
}
}
}