From ff30b27f0d042972b4777c43dbdfccb7641be0f2 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Wed, 9 Nov 2022 13:33:50 +1100 Subject: First test cases :) --- src/drivers/CMakeLists.txt | 2 +- src/drivers/display.cpp | 5 ++- src/drivers/i2c.cpp | 37 ++++++++++++++++++++ src/drivers/include/i2c.hpp | 3 ++ src/drivers/include/spi.hpp | 10 ++++++ src/drivers/spi.cpp | 48 +++++++++++++++++++++++++ src/drivers/test/CMakeLists.txt | 2 +- src/drivers/test/test_example.cpp | 9 ----- src/drivers/test/test_storage.cpp | 74 +++++++++++++++++++++++++++++++++++++++ 9 files changed, 176 insertions(+), 14 deletions(-) create mode 100644 src/drivers/include/spi.hpp create mode 100644 src/drivers/spi.cpp delete mode 100644 src/drivers/test/test_example.cpp create mode 100644 src/drivers/test/test_storage.cpp (limited to 'src/drivers') diff --git a/src/drivers/CMakeLists.txt b/src/drivers/CMakeLists.txt index f57fbc2e..3b3c4a65 100644 --- a/src/drivers/CMakeLists.txt +++ b/src/drivers/CMakeLists.txt @@ -1,6 +1,6 @@ idf_component_register( SRCS "dac.cpp" "gpio-expander.cpp" "battery.cpp" "storage.cpp" "i2c.cpp" - "playback.cpp" "display.cpp" "display-init.cpp" + "playback.cpp" "display.cpp" "display-init.cpp" "spi.cpp" INCLUDE_DIRS "include" REQUIRES "esp_adc_cal" "fatfs" "audio_pipeline" "audio_stream" "result" "lvgl") target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS}) diff --git a/src/drivers/display.cpp b/src/drivers/display.cpp index 68bf41f5..dd9005cb 100644 --- a/src/drivers/display.cpp +++ b/src/drivers/display.cpp @@ -222,9 +222,8 @@ void Display::SendTransaction(TransactionType type, ServiceTransactions(); gpio_set_level(kCommandOrDataPin, type); - gpio_->with([&](auto& gpio) { - gpio.set_pin(GpioExpander::DISPLAY_CHIP_SELECT, 0); - }); + gpio_->with( + [&](auto& gpio) { gpio.set_pin(GpioExpander::DISPLAY_CHIP_SELECT, 0); }); { // auto lock = gpio_->AcquireSpiBus(GpioExpander::DISPLAY); ESP_ERROR_CHECK(spi_device_polling_transmit(handle_, transaction)); diff --git a/src/drivers/i2c.cpp b/src/drivers/i2c.cpp index d3378df6..0c195a25 100644 --- a/src/drivers/i2c.cpp +++ b/src/drivers/i2c.cpp @@ -3,11 +3,48 @@ #include "assert.h" #include "driver/i2c.h" +#include "esp_err.h" namespace drivers { +static const i2c_port_t kI2CPort = I2C_NUM_0; +static const gpio_num_t kI2CSdaPin = GPIO_NUM_2; +static const gpio_num_t kI2CSclPin = GPIO_NUM_4; +static const uint32_t kI2CClkSpeed = 400'000; + static constexpr int kCmdLinkSize = I2C_LINK_RECOMMENDED_SIZE(12); +esp_err_t init_i2c(void) { + i2c_config_t config = { + .mode = I2C_MODE_MASTER, + .sda_io_num = kI2CSdaPin, + .scl_io_num = kI2CSclPin, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master = + { + .clk_speed = kI2CClkSpeed, + }, + // No requirements for the clock. + .clk_flags = 0, + }; + + if (esp_err_t err = i2c_param_config(kI2CPort, &config)) { + return err; + } + if (esp_err_t err = i2c_driver_install(kI2CPort, config.mode, 0, 0, 0)) { + return err; + } + + // TODO: INT line + + return ESP_OK; +} + +esp_err_t deinit_i2c(void) { + return i2c_driver_delete(kI2CPort); +} + I2CTransaction::I2CTransaction() { // Use a fixed size buffer to avoid many many tiny allocations. buffer_ = (uint8_t*)calloc(sizeof(uint8_t), kCmdLinkSize); diff --git a/src/drivers/include/i2c.hpp b/src/drivers/include/i2c.hpp index a4c71767..3704509d 100644 --- a/src/drivers/include/i2c.hpp +++ b/src/drivers/include/i2c.hpp @@ -7,6 +7,9 @@ namespace drivers { +esp_err_t init_i2c(void); +esp_err_t deinit_i2c(void); + /* * Convenience wrapper for performing an I2C transaction with a reasonable * preconfigured timeout, automatic management of a heap-based command buffer, diff --git a/src/drivers/include/spi.hpp b/src/drivers/include/spi.hpp new file mode 100644 index 00000000..e58656a2 --- /dev/null +++ b/src/drivers/include/spi.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "esp_err.h" + +namespace drivers { + +esp_err_t init_spi(void); +esp_err_t deinit_spi(void); + +} // namespace drivers diff --git a/src/drivers/spi.cpp b/src/drivers/spi.cpp new file mode 100644 index 00000000..66c78e8a --- /dev/null +++ b/src/drivers/spi.cpp @@ -0,0 +1,48 @@ +#include "spi.hpp" + +#include "driver/sdspi_host.h" +#include "driver/spi_common.h" +#include "driver/spi_master.h" +#include "esp_err.h" +#include "hal/spi_types.h" + +namespace drivers { + +static const spi_host_device_t kSpiHost = VSPI_HOST; +static const gpio_num_t kSpiSdoPin = GPIO_NUM_23; +static const gpio_num_t kSpiSdiPin = GPIO_NUM_19; +static const gpio_num_t kSpiSclkPin = GPIO_NUM_18; + +esp_err_t init_spi(void) { + spi_bus_config_t config = { + .mosi_io_num = kSpiSdoPin, + .miso_io_num = kSpiSdiPin, + .sclk_io_num = kSpiSclkPin, + .quadwp_io_num = -1, // SPI_QUADWP_IO, + .quadhd_io_num = -1, // SPI_QUADHD_IO, + + // Unused + .data4_io_num = -1, + .data5_io_num = -1, + .data6_io_num = -1, + .data7_io_num = -1, + + // Use the DMA default size. The display requires larger buffers, but it + // manages its down use of DMA-capable memory. + .max_transfer_sz = 128 * 16 * 2, // TODO: hmm + .flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_IOMUX_PINS, + .intr_flags = 0, + }; + + if (esp_err_t err = spi_bus_initialize(kSpiHost, &config, SPI_DMA_CH_AUTO)) { + return err; + } + + return ESP_OK; +} + +esp_err_t deinit_spi(void) { + return spi_bus_free(kSpiHost); +} + +} // namespace drivers diff --git a/src/drivers/test/CMakeLists.txt b/src/drivers/test/CMakeLists.txt index f6690c4d..83904339 100644 --- a/src/drivers/test/CMakeLists.txt +++ b/src/drivers/test/CMakeLists.txt @@ -1 +1 @@ -idf_component_register(SRC_DIRS "." INCLUDE_DIRS "." REQUIRES catch2 cmock drivers) +idf_component_register(SRCS "test_storage.cpp" INCLUDE_DIRS "." REQUIRES catch2 cmock drivers) diff --git a/src/drivers/test/test_example.cpp b/src/drivers/test/test_example.cpp deleted file mode 100644 index ef90cf8f..00000000 --- a/src/drivers/test/test_example.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "catch2/catch.hpp" - -TEST_CASE("Example test case", "[cooltag]") { - REQUIRE ( 1 == 1 ); -} - -TEST_CASE("test that doesn't run", "[cooltag][!mayfail]") { - REQUIRE ( 0 == 1 ); -} diff --git a/src/drivers/test/test_storage.cpp b/src/drivers/test/test_storage.cpp new file mode 100644 index 00000000..178ec815 --- /dev/null +++ b/src/drivers/test/test_storage.cpp @@ -0,0 +1,74 @@ +#include +#include +#include +#include + +#include "gpio-expander.hpp" +#include "storage.hpp" +#include "i2c.hpp" +#include "spi.hpp" + +#include "catch2/catch.hpp" + +namespace drivers { + +static const std::string kTestFilename = "test"; +static const std::string kTestFilePath = + std::string(kStoragePath) + "/" + kTestFilename; + +TEST_CASE("sd card storage", "[integration]") { + REQUIRE( drivers::init_i2c() == ESP_OK ); + REQUIRE( drivers::init_spi() == ESP_OK ); + GpioExpander expander; + + { + std::unique_ptr result = SdStorage::create(&expander).value(); + + SECTION("write to a file") { + + { + std::ofstream test_file; + test_file.open(kTestFilePath.c_str()); + test_file << "hello here is some test"; + test_file.close(); + } + + SECTION("read from a file") { + std::ifstream test_file; + test_file.open(kTestFilePath.c_str()); + + std::string line; + REQUIRE(std::getline(test_file, line)); + REQUIRE(line == "hello here is some test"); + + test_file.close(); + } + + SECTION("list files") { + DIR* dir; + struct dirent* ent; + + dir = opendir(kStoragePath); + REQUIRE(dir != nullptr); + + bool found_test_file = false; + while (ent = readdir(dir)) { + if (ent->d_name == kTestFilename) { + found_test_file = true; + } + } + closedir(dir); + + REQUIRE(found_test_file); + + } + + REQUIRE(remove(kTestFilePath.c_str()) == 0); + } + } + + REQUIRE( drivers::deinit_i2c() == ESP_OK ); + REQUIRE( drivers::deinit_spi() == ESP_OK ); +} + +} // namespace drivers -- cgit v1.2.3