mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
[cxx]: simple spi master class
* spi cxx unit test (CATCH-based, on host) * added portmacro.h to driver mocking * added simple testing app to write/read SPI, using an MPU9250
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component")
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(simple_spi_rw_example)
|
||||
@@ -0,0 +1,68 @@
|
||||
# Example: C++ SPI sensor read for MCU9250 inertial/giroscope sensor
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates usage of C++ SPI classes in ESP-IDF to read the `WHO_AM_I` register of the sensor.
|
||||
|
||||
In this example, the `sdkconfig.defaults` file sets the `CONFIG_COMPILER_CXX_EXCEPTIONS` option.
|
||||
This enables both compile time support (`-fexceptions` compiler flag) and run-time support for C++ exception handling.
|
||||
This is necessary for the C++ SPI API.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware Required
|
||||
|
||||
An MCU9250 sensor and any commonly available ESP32 development board.
|
||||
|
||||
### Configure the project
|
||||
|
||||
```
|
||||
idf.py menuconfig
|
||||
```
|
||||
|
||||
### Build and Flash
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(Replace PORT with the name of the serial port.)
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
If the sensor is read correctly:
|
||||
|
||||
```
|
||||
...
|
||||
I (0) cpu_start: Starting scheduler on APP CPU.
|
||||
Result of WHO_AM_I register: 0x71
|
||||
I (437) gpio: GPIO[23]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (447) gpio: GPIO[25]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (457) gpio: GPIO[26]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (467) gpio: GPIO[27]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||
|
||||
Done
|
||||
```
|
||||
|
||||
If there's an error with the SPI peripheral:
|
||||
```
|
||||
...
|
||||
I (0) cpu_start: Starting scheduler on APP CPU.
|
||||
E (434) spi: spicommon_bus_initialize_io(429): mosi not valid
|
||||
Coulnd't read SPI!
|
||||
```
|
||||
|
||||
If the SPI pins are not connected properly, the resulting read may just return 0, this error can not be detected:
|
||||
```
|
||||
...
|
||||
I (0) cpu_start: Starting scheduler on APP CPU.
|
||||
Result of WHO_AM_I register: 0x00
|
||||
I (437) gpio: GPIO[23]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (447) gpio: GPIO[25]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (457) gpio: GPIO[26]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (467) gpio: GPIO[27]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "simple_spi_rw_example.cpp"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES experimental_cpp_component)
|
||||
@@ -0,0 +1,4 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0
|
||||
*
|
||||
* MPU9250 SPI Sensor C++ Example
|
||||
*
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "spi_host_cxx.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace idf;
|
||||
|
||||
static const GPIONum NSS(23);
|
||||
static const uint8_t READ_FLAG = 0x80;
|
||||
static const uint8_t MPU9250_WHO_AM_I_REG_ADDR = 0x75;
|
||||
|
||||
extern "C" void app_main(void)
|
||||
{
|
||||
try {
|
||||
|
||||
SPIMaster master(SPINum(2),
|
||||
MOSI(25),
|
||||
MISO(26),
|
||||
SCLK(27));
|
||||
|
||||
shared_ptr<SPIDevice> spi_dev = master.create_dev(CS(NSS.get_num()), Frequency::MHz(1));
|
||||
|
||||
vector<uint8_t> write_data = {MPU9250_WHO_AM_I_REG_ADDR | READ_FLAG, 0x00};
|
||||
vector<uint8_t> result = spi_dev->transfer(write_data).get();
|
||||
|
||||
cout << "Result of WHO_AM_I register: 0x";
|
||||
printf("%02X", result[1]);
|
||||
cout << endl;
|
||||
|
||||
this_thread::sleep_for(std::chrono::seconds(2));
|
||||
|
||||
} catch (const SPIException &e) {
|
||||
cout << "Coulnd't read SPI!" << endl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Enable C++ exceptions and set emergency pool size for exception objects
|
||||
CONFIG_COMPILER_CXX_EXCEPTIONS=y
|
||||
CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=1024
|
||||
Reference in New Issue
Block a user