diff --git a/CMakeLists.txt b/CMakeLists.txt index 586693c1..4bcae43d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.8) set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) include($ENV{ADF_PATH}/CMakeLists.txt) include($ENV{IDF_PATH}/tools/cmake/project.cmake) diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index d8e98ac6..085f5683 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,2 +1,2 @@ -idf_component_register(SRCS "gay-ipod-fw.cpp" "gpio-expander.cpp" "battery.cpp" +idf_component_register(SRCS "gay-ipod-fw.cpp" "gpio-expander.cpp" "battery.cpp" "storage.cpp" INCLUDE_DIRS ".") diff --git a/main/gay-ipod-fw.cpp b/main/gay-ipod-fw.cpp index 5f16ddc7..a01a99b1 100644 --- a/main/gay-ipod-fw.cpp +++ b/main/gay-ipod-fw.cpp @@ -1,17 +1,20 @@ #include +#include "battery.h" #include "driver/adc.h" #include "driver/gpio.h" #include "driver/i2c.h" +#include "driver/sdspi_host.h" #include "driver/spi_common.h" #include "driver/spi_master.h" #include "esp_adc_cal.h" +#include "esp_intr_alloc.h" #include "esp_log.h" #include "gpio-expander.h" -#include "battery.h" #include "hal/adc_types.h" #include "hal/gpio_types.h" #include "hal/spi_types.h" +#include "storage.h" #define I2C_SDA_IO (GPIO_NUM_0) #define I2C_SCL_IO (GPIO_NUM_4) @@ -69,24 +72,22 @@ esp_err_t init_spi(void) { // Use the DMA default size. .max_transfer_sz = 0, - // TODO: check flags - .flags = 0, + .flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_IOMUX_PINS, .intr_flags = 0, }; ESP_ERROR_CHECK(spi_bus_initialize(VSPI_HOST, &config, SPI_DMA_CH_AUTO)); - // TODO: CS lines - // TODO: add devices to the bus (sd card and display) - return ESP_OK; } extern "C" void app_main(void) { ESP_LOGI(TAG, "Initialising peripherals"); + + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LOWMED)); init_i2c(); - //init_spi(); + init_spi(); ESP_LOGI(TAG, "Setting default GPIO state"); gay_ipod::GpioExpander expander; @@ -99,14 +100,18 @@ extern "C" void app_main(void) ESP_LOGI(TAG, "Init ADC"); ESP_ERROR_CHECK(gay_ipod::init_adc()); + ESP_LOGI(TAG, "Everything looks good! Waiting a mo for debugger."); + vTaskDelay(pdMS_TO_TICKS(2500)); + + ESP_LOGI(TAG, "Trying to init SD card"); + gay_ipod::SdStorage storage(&expander); - while (1) { - uint32_t battery = gay_ipod::read_battery_voltage(); - expander.Read(); + ESP_ERROR_CHECK(storage.Acquire()); - ESP_LOGI(TAG, "millivolts: %d, wall power? %d", battery, expander.charge_power_ok()); + ESP_LOGI(TAG, "Looks okay? Trying to deinit now."); + vTaskDelay(pdMS_TO_TICKS(1000)); + ESP_ERROR_CHECK(storage.Release()); - vTaskDelay(pdMS_TO_TICKS(1000)); - ESP_ERROR_CHECK(expander.Write()); - } + ESP_LOGI(TAG, "Hooray!"); + vTaskDelay(pdMS_TO_TICKS(1000)); } diff --git a/main/storage.cpp b/main/storage.cpp new file mode 100644 index 00000000..b1d5aa6c --- /dev/null +++ b/main/storage.cpp @@ -0,0 +1,72 @@ +#include "storage.h" + +#include "esp_check.h" +#include "driver/sdspi_host.h" +#include "esp_err.h" +#include "gpio-expander.h" +#include "hal/gpio_types.h" +#include "hal/spi_types.h" +#include "sdmmc_cmd.h" + +namespace gay_ipod { + +SdStorage::SdStorage(GpioExpander *gpio) { + this->gpio_ = gpio; +} + +SdStorage::~SdStorage() { + ESP_ERROR_CHECK(sdspi_host_deinit()); +} + +esp_err_t SdStorage::Acquire(void) { + // First switch to this device, and pull CS. + gpio_->set_sd_mux(GpioExpander::ESP); + gpio_->set_sd_cs(false); + gpio_->Write(); + + // Now we can init the driver and set up the SD card into SPI mode. + sdspi_host_init(); + + 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_cd = SDSPI_SLOT_NO_CD, + .gpio_wp = SDSPI_SLOT_NO_WP, + .gpio_int = GPIO_NUM_NC, + }; + esp_err_t ret = sdspi_host_init_device(&config, &handle_); + if (ret != ESP_OK) { + gpio_->set_sd_cs(true); + gpio_->Write(); + return ret; + } + + host_ = sdmmc_host_t SDSPI_HOST_DEFAULT(); + host_.slot = handle_; + // Will return ESP_ERR_INVALID_RESPONSE if there is no card + // TODO: use our own error code + ret = sdmmc_card_init(&host_, &card_); + + // We're done chatting for now. + gpio_->set_sd_cs(true); + gpio_->Write(); + + return ret; +} + +esp_err_t SdStorage::Release(void) { + gpio_->set_sd_cs(false); + gpio_->Write(); + + sdspi_host_remove_device(this->handle_); + sdspi_host_deinit(); + + gpio_->set_sd_mux(GpioExpander::USB); + gpio_->set_sd_cs(true); + gpio_->Write(); + + return ESP_OK; +} + +} // namespace gay_ipod diff --git a/main/storage.h b/main/storage.h new file mode 100644 index 00000000..79267b0b --- /dev/null +++ b/main/storage.h @@ -0,0 +1,34 @@ +#ifndef STORAGE_H +#define STORAGE_H + +#include "driver/sdmmc_types.h" +#include "driver/sdspi_host.h" +#include "esp_err.h" +#include "gpio-expander.h" + +namespace gay_ipod { + +class SdStorage { + public: + SdStorage(GpioExpander *gpio); + ~SdStorage(); + + esp_err_t Acquire(void); + esp_err_t Release(void); + + // Not copyable or movable. + // TODO: maybe this could be movable? + SdStorage(const SdStorage&) = delete; + SdStorage& operator=(const SdStorage&) = delete; + + private: + GpioExpander *gpio_; + + sdspi_dev_handle_t handle_; + sdmmc_host_t host_; + sdmmc_card_t card_; +}; + +} // namespace gay_ipod + +#endif