Skip to content

Commit 6cbb1b4

Browse files
committed
Fix issue #109, SPI needs to read register SPI_USER(SPI_NO) instead of using the value SPI_USER(SPI_NO) as base value for SPI_USER in SPI::transfer and SPI::transfer32
1 parent fc50665 commit 6cbb1b4

File tree

4 files changed

+35
-12
lines changed

4 files changed

+35
-12
lines changed

sming/sming/core/SPI.cpp

+13-6
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ void SPIClass::beginTransaction(SPISettings mySettings) {
8888
#ifdef SPI_DEBUG
8989
debugf("SPIhw::beginTransaction(SPISettings mySettings)");
9090
#endif
91+
92+
// store SPI user register
93+
_userReg = READ_PERI_REG(SPI_USER(SPI_NO));
94+
9195
// check if we need to change settings
9296
if (this->_SPISettings == mySettings)
9397
return;
@@ -108,6 +112,10 @@ void SPIClass::endTransaction() {
108112
#ifdef SPI_DEBUG
109113
debugf("SPIhw::endTransaction()");
110114
#endif
115+
116+
// restore SPI user register
117+
WRITE_PERI_REG(SPI_USER(SPI_NO), _userReg);
118+
_userReg = 0;
111119
};
112120

113121
/* @defgroup SPI hardware implementation
@@ -125,7 +133,7 @@ void SPIClass::endTransaction() {
125133
uint32 SPIClass::transfer32(uint32 data, uint8 bits)
126134
{
127135
// restore inital SPI_USER register
128-
uint32_t regvalue = _SPISettings._user_regvalue;
136+
uint32_t regvalue = READ_PERI_REG(SPI_USER(SPI_NO));
129137

130138
while(READ_PERI_REG(SPI_CMD(SPI_NO))&SPI_USR);
131139

@@ -193,7 +201,7 @@ void SPIClass::transfer(uint8 *buffer, size_t numberBytes) {
193201
num_bits = bufLenght * 8;
194202

195203
// restore inital SPI_USER register
196-
uint32_t regvalue = _SPISettings._user_regvalue;
204+
uint32_t regvalue = READ_PERI_REG(SPI_USER(SPI_NO));
197205

198206
while(READ_PERI_REG(SPI_CMD(SPI_NO))&SPI_USR);
199207

@@ -242,9 +250,9 @@ void SPIClass::prepare(SPISettings mySettings) {
242250
debugf("SPIClass::prepare(SPISettings mySettings)");
243251
mySettings.print("mySettings");
244252
#endif
245-
253+
246254
// check if we need to change settings
247-
if (_init & _SPISettings == mySettings)
255+
if (_init && _SPISettings == mySettings)
248256
return;
249257

250258
// setup clock
@@ -261,7 +269,6 @@ void SPIClass::prepare(SPISettings mySettings) {
261269
#endif
262270

263271
_SPISettings = mySettings;
264-
mySettings._user_regvalue = SPI_USER(SPI_NO);
265272
_init = true;
266273
};
267274

@@ -441,7 +448,7 @@ void SPIClass::setFrequency(int freq) {
441448
int _CPU_freq = system_get_cpu_freq() * 10000000UL;
442449

443450
// dont run code if there are no changes
444-
if (_init & freq == _SPISettings._speed) return;
451+
if (_init && freq == _SPISettings._speed) return;
445452

446453
// run full speed -> do not use any dividers
447454
if (freq == _CPU_freq) {

sming/sming/core/SPI.h

+22-3
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,24 @@ class SPIClass: public SPIBase {
106106
virtual unsigned short transfer16(unsigned short val) {
107107
return transfer32((uint32)val, 16);
108108
};
109+
110+
/** @brief transfer32()
111+
* @param short to send
112+
* @retval short received
113+
*
114+
* calls private method transfer32(byte) to send/recv one uint32_t
115+
* input/output casted to rightdta type
116+
*
117+
* SPI transfer is based on a simultaneous send and receive:
118+
* the received data is returned in receivedVal (or receivedVal16).
119+
*
120+
* receivedVal = SPI.transfer(val) : single byte
121+
* receivedVal32 = SPI.transfer32(val32) : single uint32_t
122+
*/
123+
virtual uint32_t transfer32(uint32_t val) {
124+
return transfer32((uint32_t) val, 32);
125+
};
126+
109127

110128
/** @brief transfer(uint8 *buffer, size_t numberBytes)
111129
* @param buffer in/out
@@ -168,9 +186,10 @@ class SPIClass: public SPIBase {
168186
uint32_t getFrequency(int freq, int &pre, int clk);
169187
void setFrequency(int freq);
170188

171-
SPISettings _SPISettings;
172-
uint8 _isTX = false;
173-
uint8 _init = false;
189+
SPISettings _SPISettings;
190+
uint8 _isTX = false;
191+
uint8 _init = false;
192+
uint32_t _userReg = 0;
174193

175194
};
176195

sming/sming/core/SPISettings.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ SPISettings::SPISettings() {
2121
_speed = 4000000;
2222
_byteOrder = MSBFIRST;
2323
_dataMode = SPI_MODE0;
24-
_user_regvalue = 0;
2524
}
2625

2726
/*
@@ -38,7 +37,6 @@ SPISettings::SPISettings(int speed, uint8 byteOrder, uint8 dataMode) {
3837
_speed = speed;
3938
_byteOrder = byteOrder;
4039
_dataMode = dataMode;
41-
_user_regvalue = 0;
4240
}
4341

4442

sming/sming/core/SPISettings.h

-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ class SPISettings {
6767
int _speed;
6868
uint8 _byteOrder;
6969
uint8 _dataMode;
70-
uint32_t _user_regvalue;
7170

7271
// overload operator to check wheter the settings are equal
7372
bool operator==(const SPISettings &other) const;

0 commit comments

Comments
 (0)