From 8106cdd481a025f62f7345f14c0a3ffdddfd2bd4 Mon Sep 17 00:00:00 2001 From: "Ettore L. Pane" <ettore.pane4@gmail.com> Date: Sun, 22 Oct 2023 17:59:50 +0200 Subject: [PATCH] Commit buggato (test di creazione driver) --- .vscode/c_cpp_properties.json | 5 +- CMakeLists.txt | 5 +- cmake/boardcore.cmake | 6 + src/shared/drivers/ettore/SPIDriver.cpp | 114 ++++++++++++++++++ src/shared/drivers/ettore/SPIDriver.h | 30 +++++ src/shared/sensors/LIS3DSH-ettore/LIS3DSH.cpp | 46 +++++++ src/shared/sensors/LIS3DSH-ettore/LIS3DSH.h | 81 +++++++++++++ src/tests/sensors/test-ettore.cpp | 36 ++++++ src/tests/sensors/test-lis3dsh.cpp | 5 +- src/tests/test-serial.cpp | 10 +- 10 files changed, 327 insertions(+), 11 deletions(-) create mode 100644 src/shared/drivers/ettore/SPIDriver.cpp create mode 100644 src/shared/drivers/ettore/SPIDriver.h create mode 100644 src/shared/sensors/LIS3DSH-ettore/LIS3DSH.cpp create mode 100644 src/shared/sensors/LIS3DSH-ettore/LIS3DSH.h create mode 100644 src/tests/sensors/test-ettore.cpp diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 895903d93..54a6c9482 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -428,9 +428,10 @@ "${defaultIncludePaths}", "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/common", "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM7_stm32f7/stm32f769ni_discovery" + "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM7_stm32f7/stm32f769ni_discovery", + "${workspaceFolder}/src/shared/sensors/LIS3DSH" ] } ], "version": 4 -} +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index aaba63944..aeff2d1c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,9 @@ project(SkywardBoardcore) # Entrypoints # #-----------------------------------------------------------------------------# +add_executable(test-ettore src/tests/sensors/test-ettore.cpp) +sbs_target(test-ettore stm32f407vg_stm32f4discovery) + add_executable(bmx160-calibration-v2 src/entrypoints/bmx160-calibration-entry.cpp) sbs_target(bmx160-calibration-v2 stm32f429zi_skyward_death_stack_x) @@ -106,7 +109,7 @@ add_executable(test-sensormanager src/tests/test-sensormanager.cpp) sbs_target(test-sensormanager stm32f429zi_skyward_death_stack_x) add_executable(test-serial src/tests/test-serial.cpp) -sbs_target(test-serial stm32f756zg_nucleo) +sbs_target(test-serial stm32f407vg_stm32f4discovery) add_executable(test-taskscheduler src/tests/scheduler/test-taskscheduler.cpp) sbs_target(test-taskscheduler stm32f407vg_stm32f4discovery) diff --git a/cmake/boardcore.cmake b/cmake/boardcore.cmake index 49c749382..e04b56c93 100644 --- a/cmake/boardcore.cmake +++ b/cmake/boardcore.cmake @@ -27,6 +27,12 @@ foreach(OPT_BOARD ${BOARDS}) set(BOARDCORE_LIBRARY boardcore-${OPT_BOARD}) add_library(${BOARDCORE_LIBRARY} STATIC EXCLUDE_FROM_ALL + # Ettore + ${SBS_BASE}/src/shared/sensors/LIS3DSH-ettore/LIS3DSH.cpp + ${SBS_BASE}/src/shared/drivers/ettore/SPIDriver.cpp + + + # Actuators ${SBS_BASE}/src/shared/actuators/HBridge/HBridge.cpp ${SBS_BASE}/src/shared/actuators/Servo/Servo.cpp diff --git a/src/shared/drivers/ettore/SPIDriver.cpp b/src/shared/drivers/ettore/SPIDriver.cpp new file mode 100644 index 000000000..b153ae5a2 --- /dev/null +++ b/src/shared/drivers/ettore/SPIDriver.cpp @@ -0,0 +1,114 @@ +#include "SPIDriver.h" +#include <utils/Debug.h> + + +namespace Boardcore { + +SpiDriver::SpiDriver(){ + +} + +void SpiDriver::config() +{ + // CS has to be configured as output and put to high state. This because the + // chip select, by design, is active low: when the master wants to communicate + // with a slave, it has to pull the corresponding CS line to low + cs::mode(miosix::Mode::OUTPUT); + cs::high(); + + // SCK, MISO and MOSI GPIOs have to be configured in alternate mode. In this + // mode they are controlled by the internal SPI peripheral and not by the + // GPIO control registers + sck::mode(miosix::Mode::ALTERNATE); + miso::mode(miosix::Mode::ALTERNATE); + mosi::mode(miosix::Mode::ALTERNATE); + + // STM32F4 chips have many peripherals connected to the same pins. The selection + // of which peripheral is connected to the GPIO pins is done through this + // function. + // To have a list of all the peripherals and their corresponding alternate + // function number, see device's datasheet in the section "Alternate function + // mapping". + // For the STM32F407VG the SPI1 is on alternate function number 5 + sck::alternateFunction(5); + miso::alternateFunction(5); + mosi::alternateFunction(5); + + TRACE("[SpiDriver] GPIOs configured \n"); + + { + // Disable interrupts + miosix::FastInterruptDisableLock dLock; + // Now enable the SPI peripheral by setting to 1 the corresponding bit into + // the clock gating register. This gives clock to peripheral's hardware + // allowing to read and write hardware. This operation must be done before + // accessing any of the peripheral's registers, otherwise reading and/or + // writing to them will have no effect. + RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; + RCC_SYNC(); + } + + // Once clock has been enabled, configure the SPI peripheral writing to its + // registers. + // For detailed informations, see the reference manual for the STM32F407xx + // family at page 857 and following + SPI1->CR1 = SPI_CR1_SSM // Software slave management enabled, CS line + // is controlled by software and not by the peripheral + + | SPI_CR1_SSI // Internal slave select, see above + + | SPI_CR1_MSTR // Peripheral is an SPI master + + | SPI_CR1_BR_2 // Division factor for SPI clock generation. + // SPI1 is connected to APB2 bus, which is clocked + // at 84MHz. Setting to 1 the third bit of division + // factor we obtain an SCK frequency of 84MHz / 32 = 2.625MHz + + | SPI_CR1_SPE; // Finally enable the peripheral + + TRACE("[SpiDriver] SPI1 configured \n"); +} + +uint8_t SpiDriver::sendRecv(uint8_t data) +{ + SPI1->DR = data; + waitBusy(); + return SPI1->DR; +} + +void SpiDriver::waitBusy() +{ + // Wait until the RX Not Empty flag in peripheral's status + // register (SPI1->SR) is set. This signals that the data transfer + // is completed and the data received from the slave device is + // into data register (SPI1->DR) + while((SPI1->SR & SPI_SR_RXNE) == 0) + { + } +} + +void SpiDriver::write(uint8_t addr, uint8_t value) +{ + cs::low(); + + sendRecv(addr); + sendRecv(value); + + cs::high(); + miosix::delayUs(10); // wait 10 microseconds +} + +uint8_t SpiDriver::read(uint8_t addr) +{ + cs::low(); + sendRecv(0x80 | addr); // <--deeper + uint8_t data = sendRecv(0x00); + + cs::high(); + miosix::delayUs(10); // wait 10 microseconds + printf("returning\n"); + + return data; +} + +} // namespace Boardcore \ No newline at end of file diff --git a/src/shared/drivers/ettore/SPIDriver.h b/src/shared/drivers/ettore/SPIDriver.h new file mode 100644 index 000000000..6fbba0077 --- /dev/null +++ b/src/shared/drivers/ettore/SPIDriver.h @@ -0,0 +1,30 @@ +#include <miosix.h> + +namespace Boardcore { + + typedef miosix::Gpio<GPIOA_BASE, 5> sck; + typedef miosix::Gpio<GPIOA_BASE, 6> miso; + typedef miosix::Gpio<GPIOA_BASE, 7> mosi; + + typedef miosix::Gpio<GPIOE_BASE, 3> cs; + + class SpiDriver + { + public: + + SpiDriver(); + + void config(); + + uint8_t read(uint8_t addr); + + void write(uint8_t addr, uint8_t value); + + private: + + uint8_t sendRecv(uint8_t data); + + void waitBusy(); + }; + +} // namespace BoardCore diff --git a/src/shared/sensors/LIS3DSH-ettore/LIS3DSH.cpp b/src/shared/sensors/LIS3DSH-ettore/LIS3DSH.cpp new file mode 100644 index 000000000..d4b3f6411 --- /dev/null +++ b/src/shared/sensors/LIS3DSH-ettore/LIS3DSH.cpp @@ -0,0 +1,46 @@ +#include "LIS3DSH.h" + +namespace Boardcore { + +LIS3DSHettore::LIS3DSHettore(uint8_t odr, uint8_t bdu) + : odr(odr), bdu(bdu) +{ +} + +bool LIS3DSHettore::checkWhoAmI() +{ + uint8_t who_am_i = spi_driver.read(WHO_AM_I_REG); // <-- we need to go deeper + + if (who_am_i == WHO_AM_I_VALUE) + { + + return true; + } + + return false; +} + +bool LIS3DSHettore::init() +{ + if (!checkWhoAmI()) // wrong who_am_i value + { + printf("init not okay"); + return false; + } + // set the output data rate and the BDU in CTRL_REG4 + uint8_t ctrl_reg4_value = (odr << 4) | (bdu << 3); + spi_driver.write(CTRL_REG4, ctrl_reg4_value); + return true; // correctly initialized +} + +int8_t LIS3DSHettore::getTemperature() +{ + // the temperature is given as a 8-bits integer (in 2-complement) + // 1 LSB/deg - 8-bit resolution + // also, reading zero means 25 °C, so add the temperature reference + return spi_driver.read(OUT_T) + TEMPERATURE_REF; +} + +} + + diff --git a/src/shared/sensors/LIS3DSH-ettore/LIS3DSH.h b/src/shared/sensors/LIS3DSH-ettore/LIS3DSH.h new file mode 100644 index 000000000..f13d5f688 --- /dev/null +++ b/src/shared/sensors/LIS3DSH-ettore/LIS3DSH.h @@ -0,0 +1,81 @@ + + +#pragma once + +#include "drivers/ettore/SPIDriver.h" + +namespace Boardcore +{ + +class LIS3DSHettore +{ + +public: + LIS3DSHettore(uint8_t odr, uint8_t bdu); + + bool init(); + + bool checkWhoAmI(); + + int8_t getTemperature(); + + enum OutputDataRate : uint8_t + { + ODR_POWER_DOWN = 0, // default value + ODR_3_125_HZ = 1, + ODR_6_25_HZ = 2, + ODR_12_5_HZ = 3, + ODR_25_HZ = 4, + ODR_50_HZ = 5, + ODR_100_HZ = 6, + ODR_400_HZ = 7, + ODR_800_HZ = 8, + ODR_1600_HZ = 9 + }; + + enum BlockDataUpdate : uint8_t + { + CONTINUOUS_UPDATE_MODE = 0, + UPDATE_AFTER_READ_MODE = 1 // values updated only when MSB and LSB are read + }; + + enum Registers : uint8_t + { + WHO_AM_I_REG = 0x0F, + CTRL_REG4 = 0x20, // control register to set ODR and BDU + OUT_T = 0x0C // temperature output register + }; + + +private: + + SpiDriver spi_driver; + uint8_t odr; + uint8_t bdu; + + const uint8_t WHO_AM_I_VALUE = 63; + const uint8_t TEMPERATURE_REF = 25; +}; + +} // namespace Boardcore + +enum OutputDataRate : uint8_t +{ + ODR_POWER_DOWN = 0, // default value + ODR_3_125_HZ = 1, + ODR_6_25_HZ = 2, + ODR_12_5_HZ = 3, + ODR_25_HZ = 4, + ODR_50_HZ = 5, + ODR_100_HZ = 6, + ODR_400_HZ = 7, + ODR_800_HZ = 8, + ODR_1600_HZ = 9 +}; + +enum BlockDataUpdate : uint8_t +{ + CONTINUOUS_UPDATE_MODE = 0, + UPDATE_AFTER_READ_MODE = 1 // values updated only when MSB and LSB are read +}; + diff --git a/src/tests/sensors/test-ettore.cpp b/src/tests/sensors/test-ettore.cpp new file mode 100644 index 000000000..c156c9b79 --- /dev/null +++ b/src/tests/sensors/test-ettore.cpp @@ -0,0 +1,36 @@ +#include <miosix.h> +#include <utils/Debug.h> +#include "sensors/LIS3DSH-ettore/LIS3DSH.h" + +using namespace miosix; +using namespace Boardcore; + +int main() +{ + LIS3DSHettore driver(LIS3DSHettore::OutputDataRate::ODR_100_HZ, + LIS3DSHettore::BlockDataUpdate::UPDATE_AFTER_READ_MODE); + + + printf("Ciao\n"); + if (driver.init()) + { + while (true) + { + TRACE("Temp : %d °C \n", driver.getTemperature()); + printf("Ciao\n"); + + + Thread::sleep(2000); + } + } else { + while (true) + { + TRACE("error \n"); + printf("Ciao\n"); + + Thread::sleep(2000); + } + } + + return 0; +} diff --git a/src/tests/sensors/test-lis3dsh.cpp b/src/tests/sensors/test-lis3dsh.cpp index 7588e9cca..4d64fedd0 100644 --- a/src/tests/sensors/test-lis3dsh.cpp +++ b/src/tests/sensors/test-lis3dsh.cpp @@ -38,6 +38,8 @@ GpioPin cs(GPIOE_BASE, 3); int main() { + Thread::sleep(500); + spiSck.mode(miosix::Mode::ALTERNATE); spiSck.alternateFunction(5); spiMiso.mode(miosix::Mode::ALTERNATE); @@ -53,6 +55,7 @@ int main() LIS3DSHData data; + // sensor not initialized, should give the error sensor.sample(); if (sensor.getLastError() != SensorErrors::NOT_INIT) @@ -85,7 +88,7 @@ int main() Thread::sleep(500); // sample some data from the sensor - for (int i = 0; i < 5; i++) + for (int i = 0; i < 5000; i++) { // sensor intitialized, should return error if no new data exist sensor.sample(); diff --git a/src/tests/test-serial.cpp b/src/tests/test-serial.cpp index b1d27f597..91c558163 100644 --- a/src/tests/test-serial.cpp +++ b/src/tests/test-serial.cpp @@ -26,13 +26,9 @@ using namespace miosix; int main() { - while (true) - { - ledOn(); - printf("Serial is working!\n"); - Thread::sleep(1000); - ledOff(); - Thread::sleep(1000); + while (true) { + printf("Helo this is my test!\n"); + Thread::sleep(500); } return 0; -- GitLab