Open FFBoard
Open source force feedback firmware
SPI.h
Go to the documentation of this file.
1/*
2 * SPI.h
3 *
4 * Created on: 27.12.2020
5 * Author: willson556
6 */
7
8#ifndef SPI_H_
9#define SPI_H_
10
11#include <GPIOPin.h>
12#include <vector>
13#include "cppmain.h"
14
15#include "SpiHandler.h"
16#include "semaphore.hpp"
17
18struct SPIConfig {
20 :cs{cs}, cspol{cspol}{
21 peripheral.Mode = SPI_MODE_MASTER;
22 peripheral.Direction = SPI_DIRECTION_2LINES;
23 peripheral.DataSize = SPI_DATASIZE_8BIT;
24 peripheral.CLKPolarity = SPI_POLARITY_LOW;
25 peripheral.CLKPhase = SPI_PHASE_1EDGE;
26 peripheral.NSS = SPI_NSS_SOFT;
27 peripheral.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
28 peripheral.FirstBit = SPI_FIRSTBIT_MSB;
29 peripheral.TIMode = SPI_TIMODE_DISABLE;
30 peripheral.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
31 peripheral.CRCPolynomial = 10;
32 }
33
35
37 bool cspol;
38 SPI_InitTypeDef peripheral;
39};
40
41class SPIDevice;
42
43class SPIPort: public SpiHandler {
44public:
45 SPIPort(SPI_HandleTypeDef &hspi,const std::vector<OutputPin>& csPins,uint32_t baseclk,bool allowReconfigure = true);
46
47 void takeSemaphore(); // Call before accessing this port
48 void giveSemaphore(); // Call when finished using this port
49
50 void configurePort(SPI_InitTypeDef* config); // Reconfigures the spi port
51
52 std::vector<OutputPin>& getCsPins();
53 OutputPin* getCsPin(uint16_t idx);
54 std::vector<OutputPin>& getFreeCsPins(); // Returns a vector of cs pins assigned to this port that are not reserved
55 bool reserveCsPin(OutputPin pin); // Signals that this pin is now in use
56 bool freeCsPin(OutputPin pin); // Signals that this cs pin is not used anymore. Call this in the destructor
57 bool isPinFree(OutputPin pin); // Returns if a pin is assigned to this port and not in use
58
59 void transmit_DMA(const uint8_t* buf,uint16_t size,SPIDevice* device);
60 void transmitReceive_DMA(const uint8_t* txbuf,uint8_t* rxbuf,uint16_t size,SPIDevice* device);
61 void receive_DMA(uint8_t* buf,uint16_t size,SPIDevice* device);
62 void transmit_IT(const uint8_t* buf,uint16_t size,SPIDevice* device);
63 void transmitReceive_IT(const uint8_t* txbuf,uint8_t* rxbuf,uint16_t size,SPIDevice* device);
64 void receive_IT(uint8_t* buf,uint16_t size,SPIDevice* device);
65 void transmit(const uint8_t* buf,uint16_t size,SPIDevice* device,uint16_t timeout);
66 void receive(uint8_t* buf,uint16_t size,SPIDevice* device,int16_t timeout);
67 void transmitReceive(const uint8_t* txbuf,uint8_t* rxbuf,uint16_t size,SPIDevice* device,uint16_t timeout);
68
69 void SpiTxCplt(SPI_HandleTypeDef *hspi) override;
70 void SpiRxCplt(SPI_HandleTypeDef *hspi) override;
71 void SpiTxRxCplt(SPI_HandleTypeDef *hspi) override;
72 void SpiError(SPI_HandleTypeDef *hspi) override;
73
74 bool isTaken(); // Returns true if semaphore was taken by another task
75
76 void takeExclusive(bool exclusive);
77 bool hasFreePins();
78
79 uint32_t getBaseClk();
80 std::pair<uint32_t,float> getClosestPrescaler(float clock);
81
82 SPI_HandleTypeDef* getPortHandle();
83
84private:
85 void beginTransfer(SPIConfig* config);
86 void endTransfer(SPIConfig* config);
87
88 SPI_HandleTypeDef &hspi;
90 std::vector<OutputPin> csPins; // cs pins and bool true if pin is reserved
91 std::vector<OutputPin> freePins;
92
94 bool allowReconfigure = false; // Allow reconfiguration at runtime. Can reduce performance a lot
95 volatile bool isTakenFlag = false;
96 bool takenExclusive = false;
97 uint32_t baseclk;
98};
99
101public:
102 SPIDevice(SPIPort& port,OutputPin csPin);
104 virtual ~SPIDevice();
105
106// virtual const SPIConfig& getConfig(SPIPort& port);
107 void assertChipSelect();
108 void clearChipSelect();
109
110 virtual bool updateCSPin(OutputPin& csPin);
111
112 virtual void spiTxCompleted(SPIPort* port) { }
113 virtual void spiRxCompleted(SPIPort* port) { }
114 virtual void spiTxRxCompleted(SPIPort* port) { }
115 virtual void spiRequestError(SPIPort* port) { }
116
117 virtual void beginSpiTransfer(SPIPort* port);
118 virtual void endSpiTransfer(SPIPort* port);
119
120 virtual SPIConfig* getSpiConfig(){return &this->spiConfig;}
121
122protected:
123 virtual void setSpiConfig(SPIConfig config){spiConfig = config;}
126};
127
128#endif
Definition: SPI.h:100
virtual bool updateCSPin(OutputPin &csPin)
Definition: SPI.cpp:340
SPIPort & spiPort
Definition: SPI.h:124
virtual void beginSpiTransfer(SPIPort *port)
Definition: SPI.cpp:359
SPIDevice(SPIPort &port, OutputPin csPin)
Definition: SPI.cpp:332
virtual ~SPIDevice()
Definition: SPI.cpp:336
void assertChipSelect()
Definition: SPI.cpp:373
virtual void spiTxCompleted(SPIPort *port)
Definition: SPI.h:112
virtual SPIConfig * getSpiConfig()
Definition: SPI.h:120
void clearChipSelect()
Definition: SPI.cpp:377
virtual void endSpiTransfer(SPIPort *port)
Definition: SPI.cpp:368
SPIConfig spiConfig
Definition: SPI.h:125
virtual void setSpiConfig(SPIConfig config)
Definition: SPI.h:123
virtual void spiRequestError(SPIPort *port)
Definition: SPI.h:115
virtual void spiRxCompleted(SPIPort *port)
Definition: SPI.h:113
virtual void spiTxRxCompleted(SPIPort *port)
Definition: SPI.h:114
Definition: SPI.h:43
void beginTransfer(SPIConfig *config)
void transmitReceive(const uint8_t *txbuf, uint8_t *rxbuf, uint16_t size, SPIDevice *device, uint16_t timeout)
Definition: SPI.cpp:176
void transmit_IT(const uint8_t *buf, uint16_t size, SPIDevice *device)
Definition: SPI.cpp:128
std::vector< OutputPin > & getCsPins()
Definition: SPI.cpp:61
bool hasFreePins()
Definition: SPI.cpp:220
SPIDevice * current_device
Definition: SPI.h:89
SPI_HandleTypeDef & hspi
Definition: SPI.h:88
bool isPinFree(OutputPin pin)
Definition: SPI.cpp:51
void takeExclusive(bool exclusive)
Definition: SPI.cpp:216
void takeSemaphore()
Definition: SPI.cpp:186
bool reserveCsPin(OutputPin pin)
Definition: SPI.cpp:25
std::pair< uint32_t, float > getClosestPrescaler(float clock)
Definition: SPI.cpp:291
uint32_t getBaseClk()
Definition: SPI.cpp:227
std::vector< OutputPin > & getFreeCsPins()
Definition: SPI.cpp:55
std::vector< OutputPin > freePins
Definition: SPI.h:91
SPI_HandleTypeDef * getPortHandle()
Definition: SPI.cpp:80
void receive(uint8_t *buf, uint16_t size, SPIDevice *device, int16_t timeout)
Definition: SPI.cpp:167
void transmitReceive_DMA(const uint8_t *txbuf, uint8_t *rxbuf, uint16_t size, SPIDevice *device)
Definition: SPI.cpp:103
void SpiError(SPI_HandleTypeDef *hspi) override
Definition: SPI.cpp:273
void SpiTxCplt(SPI_HandleTypeDef *hspi) override
Definition: SPI.cpp:232
void transmit(const uint8_t *buf, uint16_t size, SPIDevice *device, uint16_t timeout)
Definition: SPI.cpp:158
void receive_DMA(uint8_t *buf, uint16_t size, SPIDevice *device)
Definition: SPI.cpp:117
bool isTaken()
Definition: SPI.cpp:212
void transmitReceive_IT(const uint8_t *txbuf, uint8_t *rxbuf, uint16_t size, SPIDevice *device)
Definition: SPI.cpp:138
bool takenExclusive
Definition: SPI.h:96
void transmit_DMA(const uint8_t *buf, uint16_t size, SPIDevice *device)
Definition: SPI.cpp:89
void endTransfer(SPIConfig *config)
OutputPin * getCsPin(uint16_t idx)
Definition: SPI.cpp:65
std::vector< OutputPin > csPins
Definition: SPI.h:90
void SpiTxRxCplt(SPI_HandleTypeDef *hspi) override
Definition: SPI.cpp:259
void configurePort(SPI_InitTypeDef *config)
Definition: SPI.cpp:72
void giveSemaphore()
Definition: SPI.cpp:199
void receive_IT(uint8_t *buf, uint16_t size, SPIDevice *device)
Definition: SPI.cpp:148
bool freeCsPin(OutputPin pin)
Definition: SPI.cpp:37
volatile bool isTakenFlag
Definition: SPI.h:95
bool allowReconfigure
Definition: SPI.h:94
void SpiRxCplt(SPI_HandleTypeDef *hspi) override
Definition: SPI.cpp:246
cpp_freertos::BinarySemaphore semaphore
Definition: SPI.h:93
SPIPort(SPI_HandleTypeDef &hspi, const std::vector< OutputPin > &csPins, uint32_t baseclk, bool allowReconfigure=true)
Definition: SPI.cpp:14
uint32_t baseclk
Definition: SPI.h:97
Definition: SPI.h:18
SPI_InitTypeDef peripheral
Definition: SPI.h:38
OutputPin cs
Definition: SPI.h:34
bool cspol
CSPOL=true === active low.
Definition: SPI.h:37
SPIConfig(OutputPin cs, bool cspol=true)
Definition: SPI.h:19