... | ... | @@ -29,19 +29,18 @@ Consider that the GPIOs associated to the SPI bus (`SPI1` in this example) can v |
|
|
```cpp
|
|
|
#include <miosix.h>
|
|
|
|
|
|
using namespace Boardcore;
|
|
|
using namespace miosix;
|
|
|
namespace Boardcore {
|
|
|
|
|
|
typedef Gpio<GPIOA_BASE, 5> sck;
|
|
|
typedef Gpio<GPIOA_BASE, 6> miso;
|
|
|
typedef Gpio<GPIOA_BASE, 7> mosi;
|
|
|
typedef miosix::Gpio<GPIOA_BASE, 5> sck;
|
|
|
typedef miosix::Gpio<GPIOA_BASE, 6> miso;
|
|
|
typedef miosix::Gpio<GPIOA_BASE, 7> mosi;
|
|
|
```
|
|
|
|
|
|
Moreover we need to specify a **chip-select** (or _slave-select_) pin: when set to the low logic level it indicates the beginning of the communication. If you have multiple slaves you will need one chip-select pin for each of them.
|
|
|
In this example we consider the scenario in which we have a single slave, so a single chip-select pin is required:
|
|
|
|
|
|
```cpp
|
|
|
typedef Gpio<GPIOE_BASE, 3> cs;
|
|
|
typedef miosix::Gpio<GPIOE_BASE, 3> cs;
|
|
|
```
|
|
|
|
|
|
Then we define the methods that we will be implemented in the `cpp` file:
|
... | ... | @@ -71,6 +70,8 @@ private: |
|
|
|
|
|
void waitBusy();
|
|
|
};
|
|
|
|
|
|
} // namespace BoardCore
|
|
|
```
|
|
|
|
|
|
## Cpp file
|
... | ... | @@ -78,11 +79,15 @@ private: |
|
|
Import the header file and specify the namespaces:
|
|
|
|
|
|
```cpp
|
|
|
#include "SpiDriver.h”
|
|
|
#include "SpiDriver.h"
|
|
|
#include <utils/Debug.h>
|
|
|
|
|
|
using namespace Boardcore;
|
|
|
using namespace miosix;
|
|
|
|
|
|
namespace Boardcore {
|
|
|
|
|
|
SpiDriver::SpiDriver(){
|
|
|
|
|
|
}
|
|
|
```
|
|
|
|
|
|
#### SPI Configuration
|
... | ... | @@ -93,15 +98,15 @@ 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(Mode::OUTPUT);
|
|
|
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(Mode::ALTERNATE);
|
|
|
miso::mode(Mode::ALTERNATE);
|
|
|
mosi::mode(Mode::ALTERNATE);
|
|
|
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
|
... | ... | @@ -118,7 +123,7 @@ void SpiDriver::config() |
|
|
|
|
|
{
|
|
|
// Disable interrupts
|
|
|
FastInterruptDisableLock dLock;
|
|
|
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
|
... | ... | @@ -148,6 +153,7 @@ void SpiDriver::config() |
|
|
|
|
|
TRACE("[SpiDriver] SPI1 configured \n");
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
#### Send and receive data
|
... | ... | @@ -197,7 +203,7 @@ void SpiDriver::write(uint8_t addr, uint8_t value) |
|
|
sendRecv(value);
|
|
|
|
|
|
cs::high();
|
|
|
usleep(10); // wait 10 microseconds
|
|
|
miosix::delayUs(10); // wait 10 microseconds
|
|
|
}
|
|
|
```
|
|
|
|
... | ... | @@ -222,10 +228,12 @@ uint8_t SpiDriver::read(uint8_t addr) |
|
|
uint8_t data = sendRecv(0x00);
|
|
|
|
|
|
cs::high();
|
|
|
usleep(10); // wait 10 microseconds
|
|
|
miosix::delayUs(10); // wait 10 microseconds
|
|
|
|
|
|
return data;
|
|
|
}
|
|
|
|
|
|
} // namespace Boardcore
|
|
|
```
|
|
|
|
|
|
## What's next?
|
... | ... | |