-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSPImaster.cpp
More file actions
216 lines (179 loc) · 5.6 KB
/
SPImaster.cpp
File metadata and controls
216 lines (179 loc) · 5.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*
* SPImaster.cpp
*
* Created on: Nov 17, 2024
* Author: admin
*/
#include "SPImaster.h"
#ifdef HAL_SPI_MODULE_ENABLED
#include "SPIreset.h"
#include <algorithm>
void SPImaster::init(const Init& settings, const u16 distance)
{
if(settings.hspi == nullptr || settings.rx_ptr == nullptr || settings.tx_ptr == nullptr || distance == 0 ||
settings.rx_size == 0 || settings.tx_size == 0) {
return;
}
// SPI -----------------------
m_hspi = settings.hspi;
// total buffers size calculation
const reg max_size = m_size = std::max(settings.rx_size, settings.tx_size) /* plus salt */ + sizeof(u32) /* plus hash */ + sizeof(u32);
// hash
{
hash = max_size ^ (settings.tx_size * settings.rx_size);
hash_pos = max_size - sizeof(u32);
}
// rx buffer -----------------------------
{
m_rxBuffer.init(distance, max_size);
m_rxPtr = settings.rx_ptr;
m_rxSize = settings.rx_size;
}
// tx buffer -----------------------------
{
if(m_txBuffer.init(distance, max_size)) {
// write hash to table ------------------------------------------
m_txBuffer.initializeBuff([this](void* buffer, reg size) {
if(size < (0 /* plus salt */ + sizeof(u32) /* plus hash */ + sizeof(u32))) {
return;
}
u8* const buffer_u8 = static_cast<u8*>(buffer);
u32* const ptr = reinterpret_cast<u32*>(buffer_u8 + hash_pos);
*ptr = hash;
});
// --------------------------------------------------------------
}
m_txPtr = settings.tx_ptr;
m_txSize = settings.tx_size;
}
// reinit spi with CRC polynomial
{
SPI_ENGINE_RESET(settings.hspi);
// MAIN PARAMETERS -------------------------
#ifdef SPI_MODE_MASTER
settings.hspi->Init.Mode = SPI_MODE_MASTER;
#endif /* SPI_MODE_MASTER */
#ifdef SPI_DIRECTION_2LINES
settings.hspi->Init.Direction = SPI_DIRECTION_2LINES;
#endif /* SPI_DIRECTION_2LINES */
#ifdef SPI_DATASIZE_8BIT
settings.hspi->Init.DataSize = SPI_DATASIZE_8BIT;
#endif /* SPI_DATASIZE_8BIT */
#ifdef SPI_POLARITY_LOW
settings.hspi->Init.CLKPolarity = SPI_POLARITY_LOW;
#endif /* SPI_POLARITY_LOW */
#ifdef SPI_PHASE_2EDGE
settings.hspi->Init.CLKPhase = SPI_PHASE_2EDGE;
#endif /* SPI_PHASE_2EDGE */
#ifdef SPI_NSS_HARD_OUTPUT
settings.hspi->Init.NSS = SPI_NSS_HARD_OUTPUT;
#endif /* SPI_NSS_HARD_OUTPUT */
#ifdef SPI_FIRSTBIT_MSB
settings.hspi->Init.FirstBit = SPI_FIRSTBIT_MSB;
#endif /* SPI_FIRSTBIT_MSB */
#ifdef SPI_TIMODE_DISABLE
settings.hspi->Init.TIMode = SPI_TIMODE_DISABLE;
#endif /* SPI_TIMODE_DISABLE */
#ifdef SPI_NSS_PULSE_DISABLE
settings.hspi->Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
#endif /* SPI_NSS_PULSE_DISABLE */
#ifdef SPI_NSS_POLARITY_LOW
settings.hspi->Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
#endif /* SPI_NSS_POLARITY_LOW */
#ifdef SPI_MASTER_KEEP_IO_STATE_ENABLE
settings.hspi->Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE;
#endif /* SPI_MASTER_KEEP_IO_STATE_ENABLE */
// CRC PARAMETERS --------------------------
#ifdef SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN
settings.hspi->Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
settings.hspi->Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
#endif /* SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN */
settings.hspi->Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE;
settings.hspi->Init.CRCPolynomial = 0x8005; // CRC-16-ANSI polynomial
settings.hspi->Init.CRCLength = SPI_CRC_LENGTH_16BIT;
HAL_SPI_Init(settings.hspi);
}
}
void SPImaster::loop(const u32 time)
{
// rx loop
if(m_rxBuffer.readIsExist()) {
m_rxBuffer.read(m_rxPtr, m_rxSize);
m_ping = time - m_lastTxTime;
m_lastTxTime = time;
m_isOnline = true;
} else if((time - m_lastTxTime) > NoLinkTime) {
m_ping = 0xFFFFFFFF;
m_lastTxTime = time;
m_isOnline = false;
}
// tx loop
m_txBuffer.write(m_txPtr, m_txSize);
// check tx status
if(!isTxStarted) {
updateBuffers();
}
}
bool SPImaster::saltedLoop(const u32 time)
{
bool isSalted = false;
#define STATE_TX 0
#define STATE_RX 1
switch(state) {
case STATE_TX: {
// salt logic --------------------------------------------------------------
++salt; // add salt
u8* const wrPtr = static_cast<u8*>(m_txBuffer.getWriteBuffer());
u32* const pSaltTx = reinterpret_cast<u32*>(wrPtr + m_txSize);
*pSaltTx = salt; // write salt to tx
//--------------------------------------------------------------------------
m_txBuffer.write(m_txPtr, m_txSize);
m_lastTxTime = time;
state = STATE_RX;
break;}
case STATE_RX: {
// rx loop
if(m_rxBuffer.readIsExist()) {
// salt logic --------------------------------------------------------------
const u8* const rdPtr = static_cast<u8*>(m_rxBuffer.getReadBuffer());
const u32* const pSaltRx = reinterpret_cast<const u32*>(rdPtr + m_rxSize);
isSalted = (*pSaltRx == salt); // check total salt
//--------------------------------------------------------------------------
if(isSalted) {
m_rxBuffer.read(m_rxPtr, m_rxSize);
m_ping = time - m_lastTxTime;
m_isOnline = true;
state = STATE_TX;
}
}
if(!isSalted && (time - m_lastTxTime) > NoLinkTime) {
++m_errors;
m_ping = 0xFFFFFFFF;
m_isOnline = false;
state = STATE_TX;
}
break;}
default: { state = STATE_TX; break; }
}
#undef STATE_TX
#undef STATE_RX
// check tx status
if(!isTxStarted) {
updateBuffers();
}
return isSalted;
}
void SPImaster::onError()
{
++m_errors;
{
// reset DMA
HAL_SPI_DMAStop(m_hspi);
// Reset SPI for clear internal fifo
SPI_ENGINE_RESET(m_hspi);
// init after reset
HAL_SPI_Init(m_hspi);
}
updateBuffers();
}
#endif /* HAL_SPI_MODULE_ENABLED */