-
Notifications
You must be signed in to change notification settings - Fork 1k
Fix SPI CS pin trouble #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
variants/DISCO_F100RB/variant.h
Outdated
@@ -133,7 +133,7 @@ enum { | |||
|
|||
//SPI definitions | |||
//define 16 channels. As many channel as digital IOs | |||
#define SPI_CHANNELS_NUM 16 | |||
#define SPI_CHANNELS_NUM PEND |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pleaser use NUM_DIGITAL_PINS instead of PEND for all
Amend the commit to avoid twice commit for this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! ;)
Thanks @fprwi6labs Arduino_Core_STM32/libraries/SPI/SPI.h Line 163 in 0692177
I think, we need to study more before merge. |
@fprwi6labs can you please describe the original root cause of the bug and how this is fixed here ? For now please find my 2 cents as I just discussed it with @fpistm |
Firstly, the bug is caused by this code: So when you use a CS pin higher than SPI_CHANNELS_NUM you are out. Secondly, when you look at the avr code, the CS pin is saved only one time when you call the function begin(). So I think it is not to the SPI library to save a list of CS pin but to the user if he has several devices on the same SPI bus. Finally, spiSettings saved the SPI settings but it is 'idiot' to save multiple settings for the same instance. You should call beginTransaction() to set the SPI before to send data. I exposed my project to @fpistm to rework the SPI library. I will propose to you soon the code. |
One more note: I just add a look to SPI.cpp and SPI.h files and the _pin is used as an index to the spiSettings[] table, so the _pin is directly used as an channel index. To be able to use any pin as CS, the table index must be separated from the _pin ... so a deeper change is needed |
I found out indeed
Yes. I agree this is due to SPI implementation which uses _pin as the index of settings.
I agree the user will store and use the CS pin, which is used as a reference to a device.
I don't think this is 'idiot'. You can have several devices on the SPI bus, on different CS pins, that have different settings. And you don't want to re-define the settings before each transfer, so the SPI library do the job of applying the right settting. This is efficient: If it's the same device as before, you keep the setting, and only when device changes you re-apply the corresponding setting. I'm not saying that you must store the _pin, but you'd need to find a way to map the table index to a given _pin ... |
I agree but when I read the documentation of the Arduino SPI I understand that the user should follow the following sequence:
The native Arduino SPI library is simpler than our. But I can try to save several settings. |
Signed-off-by: fpr <[email protected]>
Signed-off-by: fpr <[email protected]>
libraries/SPI/src/SPI.h
Outdated
int16_t _CSpin; | ||
spi_t _spi; | ||
|
||
uint8_t getIdx(uint8_t _pin) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merge getIdx and addIdx and use a second arg to define if a new idx could be added with a default value (no add by default)
This will avoid to loop twice if there is no idx for pin then call addIdx.
libraries/SPI/src/SPI.cpp
Outdated
spiSettings[_pin].bOrder = settings.bOrder; | ||
if(spiSettings[_pin].bOrder == MSBFIRST) { | ||
spiSettings[_pin].msb = MSBFIRST; | ||
idx = getIdx(_pin); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment in SPI.h for getIdx and AddIdx to avoid loop twice
libraries/SPI/src/SPI.h
Outdated
@@ -97,45 +97,59 @@ class SPISettings { | |||
friend class SPIClass; | |||
}; | |||
|
|||
|
|||
typedef struct { | |||
int16_t pinCS; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not add the pinCS in the SPISettings class?
libraries/SPI/src/SPI.h
Outdated
#define SPI_TRANSFER_TIMEOUT 5000 | ||
|
||
// Defines the number of settings saved per SPI instance. Must be < 254. | ||
#ifndef NB_SPI_SETTINGS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add in the comment, it could be redefined in the variant.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this new solution - this looks good. I added a few comments or questions but I'm happy with the change overall that keeps the "dynamic" settings management
libraries/SPI/src/SPI.cpp
Outdated
if(idx == NB_SPI_SETTINGS) { | ||
idx = addPin(_pin); | ||
if(idx == NB_SPI_SETTINGS) | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this case here is not clear - is this an error ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this is an error because there is no more place available for a new CS pin.
libraries/SPI/src/SPI.cpp
Outdated
UNUSED(_pin); | ||
end(); | ||
if(_pin > NUM_DIGITAL_PINS) | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also an error because _pin must be a defined pin (presents in digitalPin[]).
libraries/SPI/src/SPI.cpp
Outdated
* The transfer function can reconfigure the SPI instance if the CS pin is | ||
* different from the previous one. | ||
* If the _mode is set to SPI_CONTINUE, keep the spi instance alive. That means | ||
* the CS pin is not reset. Becareful in case you use several CS pin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good comment thx. 1 typo: Becareful => Be careful
libraries/SPI/src/SPI.h
Outdated
|
||
// Defines a default timeout delay in seconds for the SPI transfer | ||
#define SPI_TRANSFER_TIMEOUT 5000 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems not related to CS related change and should be in a different commit.
The timeout was hardcoded to 10000 before and now is defined as 5000.
Is it really 5000 seconds ?? Do we consider that timeout can be fixed, whatever the number of bytes and frequency ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not 5000 seconds but 5000 milliseconds. I took advantage of the fix to standardize the timeout value.
This timeout doesn't change whatever the number of bytes or frequency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment above the definition is
// Defines a default timeout delay in seconds for the SPI transfer
so you need to change that ...
How many bytes does it allow to send @ slowest supported frequency ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless I am mistaken, we can send 78kbytes at slowest frequency = 125000.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok that sounds like a reasonable number. Even 1 sec might be enough then (~15kBytes) ... as I don't know the max supported length ...
#define BOARD_SPI_OWN_SS SPI_CHANNELS_NUM | ||
|
||
#define SS BOARD_SPI_DEFAULT_SS | ||
#define SS 43 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not related to this commit, but was is 43 ? can't we use a pin name like e.g. D10 or PB13 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
43 == D43
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See PR #83 for more information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that D43 is same as 43 and same as PX_y ...but D43 or 43 cannot be read anywhere on my board schematics or on the board itself, so I would prefer to use a commonly used names (either D0/D16 A0/A5 or PX_y ....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree that on VLdisco there is no Arduino connector and so using Dx is not well appropriate while all PXn names are on the board silkscreen print. But it's not the subject of this PR. Currently, variant.h using the same naming (Dx). Probably a new PR could be done to update all variants which do not have Arduino connector or those one using a pin number > 15.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, that's why I started my comment with "Not related to this commit" ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR ok. Waiting comment correction raised by @LMESTM before merge.
Signed-off-by: fpr <[email protected]>
I fixed a bug inside SPI library caused by the use of a CS pin other than Arduino digital pins.
Now, all pins can be used like a CS pin for the SPI.