First test cases :)

custom
jacqueline 2 years ago
parent e389871d20
commit ff30b27f0d
  1. 2
      src/drivers/CMakeLists.txt
  2. 5
      src/drivers/display.cpp
  3. 37
      src/drivers/i2c.cpp
  4. 3
      src/drivers/include/i2c.hpp
  5. 10
      src/drivers/include/spi.hpp
  6. 48
      src/drivers/spi.cpp
  7. 2
      src/drivers/test/CMakeLists.txt
  8. 9
      src/drivers/test/test_example.cpp
  9. 74
      src/drivers/test/test_storage.cpp
  10. 76
      src/main/main.cpp

@ -1,6 +1,6 @@
idf_component_register( idf_component_register(
SRCS "dac.cpp" "gpio-expander.cpp" "battery.cpp" "storage.cpp" "i2c.cpp" 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" INCLUDE_DIRS "include"
REQUIRES "esp_adc_cal" "fatfs" "audio_pipeline" "audio_stream" "result" "lvgl") REQUIRES "esp_adc_cal" "fatfs" "audio_pipeline" "audio_stream" "result" "lvgl")
target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS}) target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS})

@ -222,9 +222,8 @@ void Display::SendTransaction(TransactionType type,
ServiceTransactions(); ServiceTransactions();
gpio_set_level(kCommandOrDataPin, type); gpio_set_level(kCommandOrDataPin, type);
gpio_->with([&](auto& gpio) { gpio_->with(
gpio.set_pin(GpioExpander::DISPLAY_CHIP_SELECT, 0); [&](auto& gpio) { gpio.set_pin(GpioExpander::DISPLAY_CHIP_SELECT, 0); });
});
{ {
// auto lock = gpio_->AcquireSpiBus(GpioExpander::DISPLAY); // auto lock = gpio_->AcquireSpiBus(GpioExpander::DISPLAY);
ESP_ERROR_CHECK(spi_device_polling_transmit(handle_, transaction)); ESP_ERROR_CHECK(spi_device_polling_transmit(handle_, transaction));

@ -3,11 +3,48 @@
#include "assert.h" #include "assert.h"
#include "driver/i2c.h" #include "driver/i2c.h"
#include "esp_err.h"
namespace drivers { 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); 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() { I2CTransaction::I2CTransaction() {
// Use a fixed size buffer to avoid many many tiny allocations. // Use a fixed size buffer to avoid many many tiny allocations.
buffer_ = (uint8_t*)calloc(sizeof(uint8_t), kCmdLinkSize); buffer_ = (uint8_t*)calloc(sizeof(uint8_t), kCmdLinkSize);

@ -7,6 +7,9 @@
namespace drivers { namespace drivers {
esp_err_t init_i2c(void);
esp_err_t deinit_i2c(void);
/* /*
* Convenience wrapper for performing an I2C transaction with a reasonable * Convenience wrapper for performing an I2C transaction with a reasonable
* preconfigured timeout, automatic management of a heap-based command buffer, * preconfigured timeout, automatic management of a heap-based command buffer,

@ -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

@ -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

@ -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)

@ -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 );
}

@ -0,0 +1,74 @@
#include <dirent.h>
#include <cstdio>
#include <fstream>
#include <iostream>
#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<SdStorage> 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

@ -7,9 +7,11 @@
#include "esp_freertos_hooks.h" #include "esp_freertos_hooks.h"
#include "freertos/portmacro.h" #include "freertos/portmacro.h"
#include "gpio-expander.hpp" #include "gpio-expander.hpp"
#include "i2c.hpp"
#include "misc/lv_color.h" #include "misc/lv_color.h"
#include "misc/lv_timer.h" #include "misc/lv_timer.h"
#include "playback.hpp" #include "playback.hpp"
#include "spi.hpp"
#include "storage.hpp" #include "storage.hpp"
#include <dirent.h> #include <dirent.h>
@ -33,68 +35,8 @@
#include "lvgl/lvgl.h" #include "lvgl/lvgl.h"
#include "widgets/lv_label.h" #include "widgets/lv_label.h"
#define I2C_SDA_IO (GPIO_NUM_2)
#define I2C_SCL_IO (GPIO_NUM_4)
#define I2C_CLOCK_HZ (400000)
#define SPI_SDI_IO (GPIO_NUM_19)
#define SPI_SDO_IO (GPIO_NUM_23)
#define SPI_SCLK_IO (GPIO_NUM_18)
#define SPI_QUADWP_IO (GPIO_NUM_22)
#define SPI_QUADHD_IO (GPIO_NUM_21)
static const char* TAG = "MAIN"; static const char* TAG = "MAIN";
esp_err_t init_i2c(void) {
i2c_port_t port = I2C_NUM_0;
i2c_config_t config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_SDA_IO,
.scl_io_num = I2C_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master =
{
.clk_speed = I2C_CLOCK_HZ,
},
// No requirements for the clock.
.clk_flags = 0,
};
ESP_ERROR_CHECK(i2c_param_config(port, &config));
ESP_ERROR_CHECK(i2c_driver_install(port, config.mode, 0, 0, 0));
// TODO: INT line
return ESP_OK;
}
esp_err_t init_spi(void) {
spi_bus_config_t config = {
.mosi_io_num = SPI_SDO_IO,
.miso_io_num = SPI_SDI_IO,
.sclk_io_num = SPI_SCLK_IO,
.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,
};
ESP_ERROR_CHECK(spi_bus_initialize(VSPI_HOST, &config, SPI_DMA_CH_AUTO));
return ESP_OK;
}
void IRAM_ATTR tick_hook(void) { void IRAM_ATTR tick_hook(void) {
lv_tick_inc(1); lv_tick_inc(1);
} }
@ -149,17 +91,13 @@ extern "C" void app_main(void) {
ESP_LOGI(TAG, "Initialising peripherals"); ESP_LOGI(TAG, "Initialising peripherals");
ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LOWMED)); ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LOWMED));
init_i2c(); ESP_ERROR_CHECK(drivers::init_i2c());
init_spi(); ESP_ERROR_CHECK(drivers::init_spi());
ESP_ERROR_CHECK(drivers::init_adc()); ESP_ERROR_CHECK(drivers::init_adc());
ESP_LOGI(TAG, "Init GPIOs"); ESP_LOGI(TAG, "Init GPIOs");
drivers::GpioExpander* expander = new drivers::GpioExpander(); drivers::GpioExpander* expander = new drivers::GpioExpander();
// for debugging usb ic
// expander.set_sd_mux(drivers::GpioExpander::USB);
/*
ESP_LOGI(TAG, "Init SD card"); ESP_LOGI(TAG, "Init SD card");
auto storage_res = drivers::SdStorage::create(expander); auto storage_res = drivers::SdStorage::create(expander);
if (storage_res.has_error()) { if (storage_res.has_error()) {
@ -184,15 +122,15 @@ extern "C" void app_main(void) {
} }
std::unique_ptr<drivers::DacAudioPlayback> playback = std::unique_ptr<drivers::DacAudioPlayback> playback =
std::move(playback_res.value()); std::move(playback_res.value());
*/
ESP_LOGI(TAG, "Everything looks good! Waiting a mo for debugger."); ESP_LOGI(TAG, "Everything looks good! Waiting a mo for debugger.");
vTaskDelay(pdMS_TO_TICKS(1500)); vTaskDelay(pdMS_TO_TICKS(1500));
LvglArgs* lvglArgs = (LvglArgs*)calloc(1, sizeof(LvglArgs)); LvglArgs* lvglArgs = (LvglArgs*)calloc(1, sizeof(LvglArgs));
lvglArgs->gpio_expander = expander; lvglArgs->gpio_expander = expander;
xTaskCreateStaticPinnedToCore(&lvgl_main, "LVGL", kLvglStackSize, (void*)lvglArgs, xTaskCreateStaticPinnedToCore(&lvgl_main, "LVGL", kLvglStackSize,
1, sLvglStack, &sLvglTaskBuffer, 1); (void*)lvglArgs, 1, sLvglStack,
&sLvglTaskBuffer, 1);
while (1) { while (1) {
// TODO: Find owners for everything so we can quit this task safely. // TODO: Find owners for everything so we can quit this task safely.

Loading…
Cancel
Save