Merge branch 'r2-bringup'

custom
jacqueline 2 years ago
commit 41993ea509
  1. 24
      src/drivers/display.cpp
  2. 18
      src/drivers/gpio_expander.cpp
  3. 102
      src/drivers/include/gpio_expander.hpp
  4. 8
      src/drivers/storage.cpp
  5. 8
      src/main/main.cpp

@ -21,8 +21,6 @@
#include "display_init.hpp"
static const char* kTag = "DISPLAY";
static const gpio_num_t kCommandOrDataPin = GPIO_NUM_21;
static const gpio_num_t kLedPin = GPIO_NUM_22;
static const uint8_t kDisplayWidth = 128;
static const uint8_t kDisplayHeight = 160;
@ -76,18 +74,9 @@ static void IRAM_ATTR post_cb(spi_transaction_t* transaction) {
auto Display::create(GpioExpander* expander,
const displays::InitialisationData& init_data)
-> cpp::result<std::unique_ptr<Display>, Error> {
// First, set up our GPIOs
gpio_config_t gpio_cfg = {
.pin_bit_mask = GPIO_SEL_22 | GPIO_SEL_21,
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&gpio_cfg);
gpio_set_level(kLedPin, 1);
gpio_set_level(kCommandOrDataPin, 0);
expander->with(
[&](auto& gpio) { gpio.set_pin(GpioExpander::DISPLAY_LED, 1); });
// Next, init the SPI device
spi_device_interface_config_t spi_cfg = {
@ -101,7 +90,7 @@ auto Display::create(GpioExpander* expander,
.cs_ena_posttrans = 0,
.clock_speed_hz = SPI_MASTER_FREQ_40M,
.input_delay_ns = 0,
.spics_io_num = -1, // TODO: change for R2
.spics_io_num = GPIO_NUM_22,
.flags = 0,
.queue_size = kTransactionQueueSize,
.pre_cb = NULL,
@ -223,14 +212,11 @@ void Display::SendTransaction(TransactionType type,
//
ServiceTransactions();
gpio_set_level(kCommandOrDataPin, type);
gpio_->with(
[&](auto& gpio) { gpio.set_pin(GpioExpander::DISPLAY_CHIP_SELECT, 0); });
{
// auto lock = gpio_->AcquireSpiBus(GpioExpander::DISPLAY);
[&](auto& gpio) { gpio.set_pin(GpioExpander::DISPLAY_DR, type); });
ESP_ERROR_CHECK(spi_device_polling_transmit(handle_, transaction));
}
free(transaction);
}

@ -54,10 +54,6 @@ esp_err_t GpioExpander::Read() {
return ret;
}
void GpioExpander::set_pin(ChipSelect cs, bool value) {
set_pin((Pin)cs, value);
}
void GpioExpander::set_pin(Pin pin, bool value) {
if (value) {
ports_ |= (1 << pin);
@ -70,18 +66,4 @@ bool GpioExpander::get_input(Pin pin) const {
return (inputs_ & (1 << pin)) > 0;
}
GpioExpander::SpiLock GpioExpander::AcquireSpiBus(ChipSelect cs) {
// TODO: also spi_device_acquire_bus?
return SpiLock(*this, cs);
}
GpioExpander::SpiLock::SpiLock(GpioExpander& gpio, ChipSelect cs)
: lock_(gpio.cs_mutex_), gpio_(gpio), cs_(cs) {
gpio_.with([&](auto& expander) { expander.set_pin(cs_, 0); });
}
GpioExpander::SpiLock::~SpiLock() {
gpio_.with([&](auto& expander) { expander.set_pin(cs_, 1); });
}
} // namespace drivers

@ -36,27 +36,27 @@ class GpioExpander {
// Port A:
// 0 - audio power enable
// 1 - usb interface power enable
// 1 - usb interface power enable (active low)
// 2 - display power enable
// 3 - sd card power enable
// 4 - charge power ok (active low)
// 3 - touchpad power enable
// 4 - sd card power enable
// 5 - sd mux switch
// 6 - sd chip select
// 7 - display chip select
// All power switches low, chip selects high, active-low charge power high
static const uint8_t kPortADefault = 0b11010001;
// 6 - LDO enable
// 7 - charge power ok (active low)
// All power switches low, sd mux pointing away from us, inputs high.
static const uint8_t kPortADefault = 0b10000010;
// Port B:
// 0 - 3.5mm jack detect (active low)
// 1 - dac soft mute switch
// 2 - GPIO
// 3 - GPIO
// 4 - GPIO
// 5 - GPIO
// 6 - GPIO
// 7 - GPIO
// DAC mute output low, everything else is active-low inputs.
static const uint8_t kPortBDefault = 0b11111111;
// 1 - unused
// 2 - volume up
// 3 - volume down
// 4 - lock switch
// 5 - touchpad interupt
// 6 - display DR
// 7 - display LED
// Inputs all high, all others low.
static const uint8_t kPortBDefault = 0b00111101;
/*
* Convenience mehod for packing the port a and b bytes into a single 16 bit
@ -102,33 +102,27 @@ class GpioExpander {
AUDIO_POWER_ENABLE = 0,
USB_INTERFACE_POWER_ENABLE = 1,
DISPLAY_POWER_ENABLE = 2,
SD_CARD_POWER_ENABLE = 3,
CHARGE_POWER_OK = 4, // Active-low input
TOUCHPAD_POWER_ENABLE = 3,
SD_CARD_POWER_ENABLE = 4,
SD_MUX_SWITCH = 5,
SD_CHIP_SELECT = 6,
DISPLAY_CHIP_SELECT = 7,
LDO_ENABLE = 6,
CHARGE_POWER_OK = 7, // Active-low input
// Port B
PHONE_DETECT = 8, // Active-high input
DAC_MUTE = 9,
GPIO_1 = 10,
GPIO_2 = 11,
GPIO_3 = 12,
GPIO_4 = 13,
GPIO_5 = 14,
GPIO_6 = 15,
};
/* Pins whose access should be guarded by `cs_lock`. */
enum ChipSelect {
SD_CARD = SD_CHIP_SELECT,
DISPLAY = DISPLAY_CHIP_SELECT,
//UNUSED = 9,
VOL_UP = 10,
VOL_DOWN = 11,
LOCK = 12,
TOUCHPAD_INT = 13,
DISPLAY_DR = 14,
DISPLAY_LED = 15,
};
/* Nicer value names for use with the SD_MUX_SWITCH pin. */
enum SdController {
SD_MUX_ESP = 0,
SD_MUX_USB = 1,
SD_MUX_ESP = 1,
SD_MUX_USB = 0,
};
/**
@ -145,7 +139,6 @@ class GpioExpander {
* is made.
*/
void set_pin(Pin pin, bool value);
void set_pin(ChipSelect cs, bool value);
/**
* Returns the input status of each of the ports. The first byte is port a,
@ -159,49 +152,12 @@ class GpioExpander {
*/
bool get_input(Pin pin) const;
/* Returns the mutex that must be held whilst pulling a CS pin low. */
std::mutex& cs_mutex() { return cs_mutex_; }
/*
* Helper class containing an active `cs_mutex` lock. When an instance of
* this class is destroyed (usually by falling out of scope), the associated
* CS pin will be driven high before the lock is released.
*/
class SpiLock {
public:
SpiLock(GpioExpander& gpio, ChipSelect cs);
~SpiLock();
SpiLock(const SpiLock&) = delete;
private:
std::scoped_lock<std::mutex> lock_;
GpioExpander& gpio_;
ChipSelect cs_;
};
/*
* Pulls the given CS pin low to signal that we are about to communicate
* with a particular device, after acquiring a lock on `cs_mutex`. The
* recommended way to safely interact with devices on the SPI bus is to have
* a self-contained block like so:
*
* ```
* {
* auto lock = AcquireSpiBus(WHATEVER);
* // Do some cool things here.
* }
* ```
*/
SpiLock AcquireSpiBus(ChipSelect cs);
// Not copyable or movable. There should usually only ever be once instance
// of this class, and that instance will likely have a static lifetime.
GpioExpander(const GpioExpander&) = delete;
GpioExpander& operator=(const GpioExpander&) = delete;
private:
std::mutex cs_mutex_;
std::atomic<uint16_t> ports_;
std::atomic<uint16_t> inputs_;
};

@ -51,8 +51,8 @@ static esp_err_t do_transaction(sdspi_dev_handle_t handle,
auto SdStorage::create(GpioExpander* gpio)
-> cpp::result<std::unique_ptr<SdStorage>, Error> {
// Acquiring the bus will also flush the mux switch change.
gpio->set_pin(GpioExpander::SD_MUX_SWITCH, GpioExpander::SD_MUX_ESP);
gpio->Write();
sdspi_dev_handle_t handle;
std::unique_ptr<sdmmc_host_t> host;
@ -64,8 +64,7 @@ auto SdStorage::create(GpioExpander* gpio)
sdspi_device_config_t config = {
.host_id = VSPI_HOST,
// CS handled manually bc it's on the GPIO expander
.gpio_cs = GPIO_NUM_2,
.gpio_cs = GPIO_NUM_21,
.gpio_cd = SDSPI_SLOT_NO_CD,
.gpio_wp = SDSPI_SLOT_NO_WP,
.gpio_int = GPIO_NUM_NC,
@ -87,7 +86,6 @@ auto SdStorage::create(GpioExpander* gpio)
host->slot = handle;
callback::bootstrap = do_transaction;
auto lock = gpio->AcquireSpiBus(GpioExpander::SD_CARD);
// Will return ESP_ERR_INVALID_RESPONSE if there is no card
esp_err_t err = sdmmc_card_init(host.get(), card.get());
if (err != ESP_OK) {
@ -142,7 +140,7 @@ SdStorage::~SdStorage() {
auto SdStorage::HandleTransaction(sdspi_dev_handle_t handle,
sdmmc_command_t* cmdinfo) -> esp_err_t {
auto lock = gpio_->AcquireSpiBus(GpioExpander::SD_CARD);
// TODO: not needed anymore?
return do_transaction_(handle, cmdinfo);
}

@ -101,6 +101,14 @@ extern "C" void app_main(void) {
ESP_LOGI(TAG, "Init GPIOs");
drivers::GpioExpander* expander = new drivers::GpioExpander();
ESP_LOGI(TAG, "Enable power rails for development");
expander->with(
[&](auto& gpio) {
gpio.set_pin(drivers::GpioExpander::AUDIO_POWER_ENABLE, 1);
gpio.set_pin(drivers::GpioExpander::SD_CARD_POWER_ENABLE, 1);
gpio.set_pin(drivers::GpioExpander::SD_MUX_SWITCH, drivers::GpioExpander::SD_MUX_ESP);
});
ESP_LOGI(TAG, "Init SD card");
auto storage_res = drivers::SdStorage::create(expander);
if (storage_res.has_error()) {

Loading…
Cancel
Save