mirror of
https://github.com/justinian/edmfd_firmware.git
synced 2025-12-09 16:24:31 -08:00
Support feather board, move to broken out source
This commit is contained in:
163
src/edmfd/main.cc
Normal file
163
src/edmfd/main.cc
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user