Support feather board, move to broken out source

This commit is contained in:
Justin C. Miller
2025-02-15 14:27:26 -08:00
parent 7a0cfebf52
commit 3a8fa7d08f
18 changed files with 411 additions and 105 deletions

163
src/edmfd/main.cc Normal file
View File

@@ -0,0 +1,163 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/i2c.h"
#include "tusb_config.h"
#include "bsp/board_api.h"
#include "tusb.h"
#include "logging/log.hh"
#include "blink.hh"
#include "hid.hh"
#include "mcp23017.hh"
extern "C" {
// TinyUSB callbacks
void tud_mount_cb();
void tud_unmount_cb();
void tud_suspend_cb(bool);
void tud_resume_cb();
}
// I2C reserves some addresses for special purposes. We exclude these from the scan.
// These are any addresses of the form 000 0xxx or 111 1xxx
bool reserved_addr(uint8_t addr) {
return (addr & 0x78) == 0 || (addr & 0x78) == 0x78;
}
void setup_i2c()
{
i2c_init(i2c_default, 100 * 1000);
gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C);
gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN);
gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
// Make the I2C pins available to picotool
bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C));
}
int write_mcp(uint8_t addr, uint8_t reg, uint8_t value, const char *regname)
{
uint8_t txdata[2] = { reg, value };
int ret = i2c_write_blocking(i2c_default, addr, txdata, 2, false);
if (ret)
printf("Error %02x writing %02x to %02x:%s", ret, value, addr, regname);
else
printf("Wrote %02x to %02x:%s", value, addr, regname);
return ret;
}
void setup_mcp()
{
// A7 is button, B0 is LED
static constexpr uint8_t addr = 0x20;
if (write_mcp(addr, 0x00, 0xff, "IODIRA")) return;
if (write_mcp(addr, 0x10, 0x00, "IODIRB")) return;
if (write_mcp(addr, 0x02, 0xff, "GPINTENA")) return;
if (write_mcp(addr, 0x06, 0xff, "GPPUA")) return;
}
void i2c_scan()
{
printf("\nI2C Bus Scan\n");
printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");
for (int addr = 0; addr < (1 << 7); ++addr) {
if (addr % 16 == 0) {
printf("%02x ", addr);
}
// Perform a 1-byte dummy read from the probe address. If a slave
// acknowledges this address, the function returns the number of bytes
// transferred. If the address byte is ignored, the function returns
// -1.
// Skip over any reserved addresses.
int ret;
uint8_t rxdata;
if (reserved_addr(addr))
ret = PICO_ERROR_GENERIC;
else
ret = i2c_read_blocking(i2c_default, addr, &rxdata, 1, false);
printf(ret < 0 ? "." : "@");
printf(addr % 16 == 15 ? "\n" : " ");
}
printf("Done.\n");
}
int main(void)
{
setup_default_uart();
stdio_init_all();
puts("\n");
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
board_init();
log::info("board initialized");
tud_init(BOARD_TUD_RHPORT);
if (board_init_after_tusb)
board_init_after_tusb();
log::info("tinyusb initialized");
setup_i2c();
log::info("i2c initialized");
using mcp23017::reg;
mcp23017::gpios gpios {0x20};
uint8_t iocon = 0xba;
gpios.read(reg::iocona, &iocon);
gpios.read(reg::iodira, &iocon);
/*
gpios.write(reg::iodira, 0xff);
gpios.write(reg::gpintena, 0xff);
gpios.write(reg::gppua, 0xff);
*/
while (1) {
uint32_t time = board_millis();
tud_task(); // tinyusb device task
blink::task(time);
hid::task(time);
}
}
//--------------------------------------------------------------------+
// Device callbacks
//--------------------------------------------------------------------+
// Invoked when device is mounted
void tud_mount_cb() {
blink::set_pattern(blink::pattern::mounted);
}
// Invoked when device is unmounted
void tud_umount_cb() {
blink::set_pattern(blink::pattern::not_mounted);
}
// Invoked when usb bus is suspended
// argumen : if host allow us to perform remote wakeup
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
void tud_suspend_cb(bool) {
blink::set_pattern(blink::pattern::suspended);
}
// Invoked when usb bus is resumed
void tud_resume_cb() {
blink::pattern pat = tud_mounted() ? blink::pattern::mounted : blink::pattern::not_mounted;
blink::set_pattern(pat);
}