arduino / arduino/ArduinoCore-API

shiftIn and shiftOut do not work with SPI_MODE 3 and 4

Ouverte
#94 4 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
Langage dominant
C++
Étoiles
306
Forks
150
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

The solution described here might well fix several other problems in this thread where bits go missing or additional bits appear...
I was trying to use the standard Arduino shiftIn and shiftOut to operate a 74HC165 shift register. I found that it always clocked one too many bits, and therefore shifted all the bits to the left, losing the top one. This did not happen when I used hardware SPI (the SPI library).
I therefore took a close look at the source code for shiftIn and shiftOut in (wiring_shift.c) and soon spotted the problem: shiftIn and shiftOut assume a clock polarity of 0. _**They will therefore only work with SPI_MODE0 and 1.**_

This can be fixed by inverting the clock signal if the SPI_MODE is 3 or 4. I give my solution below. The functions require the SPI mode as an additional parameter, using the Arduino standard definitions SPI_MODE0 etc.
While I was at it, I gained a little speed by taking the test for MSBFIRST or LSBFIRST outside the bit loop and by declaring the method ‘inline’.
I have tested NEWshiftIn with the 74HC165 shift register (SPI_MODE3) and it works fine. I have not tested NEWshiftOut yet as I do not have a MOD3 or 4 device output to test it with. I have also not tested the timings to see if there is a real improvement, as I do not have access to the necessary equipment at the moment. I will be happy to hear from anyone who does any of these tests.
Happy shifting in SPI_MODES 3 and 4!
```cpp
// ===============================================================================================================================
// New version of shiftIn() and shiftOut with the clock polarity bug removed
// Requires SPI_MODE as a parameter
// Also speeded up by taking the bit direction test out of the loop
// Andrew W Symons 9-Aug-2018
//
// SHIFT IN
//
inline uint8_t NEWshiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t spiMode )
{
uint8_t value = 0;
uint8_t i;

uint8_t clock_polarity = spiMode >> 1 ;
switch ( bitOrder )
{
case LSBFIRST:
{
for (i = 0; i < 8; ++i)
{
digitalWrite(clockPin, HIGH ^ clock_polarity );
value |= digitalRead(dataPin) << i;
digitalWrite(clockPin, LOW ^ clock_polarity );
} ;
} ;
break ;

case MSBFIRST:
{
for (i = 0; i < 8; ++i)
{
digitalWrite(clockPin, HIGH ^ clock_polarity );
value |= digitalRead(dataPin) << (7 - i);
digitalWrite(clockPin, LOW ^ clock_polarity );
} ;
} ;
break ;
} ;
return value;
} ;
//
// ===============================================================================================================================
// SHIFT OUT
//
inline void NEWshiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val, uint8_t spiMode )
{
uint8_t i;
uint8_t clock_polarity = spiMode >> 1 ;
switch ( bitOrder )
{
case LSBFIRST:
{
digitalWrite(dataPin, !!(val & (1 << i)));
digitalWrite(clockPin, HIGH ^ clock_polarity );
digitalWrite(clockPin, LOW ^ clock_polarity );
} ;
break ;

case MSBFIRST:
{
digitalWrite(dataPin, !!(val & (1 << (7 - i))));
digitalWrite(clockPin, HIGH ^ clock_polarity );
digitalWrite(clockPin, LOW ^ clock_polarity );
} ;
break ;
} ;
} ;
//
// ===============================================================================================================================
// END OF FILE
//
```

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Piste de recherche

Commencez dans wiring_shift.c et comparez shiftIn() et shiftOut() avec la gestion des modes SPI de la SPI library. Reproduisez le comportement signalé de 74HC165 dans les modes d’horloge concernés, puis vérifiez que le comportement standard de décalage reste correct pour les modes et les ordres de bits existants. Le travail est considéré comme terminé lorsque les fonctions logicielles gèrent les modes signalés sans bits manquants ni ajoutés.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
cpp
Domaine
embedded-iot
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
42/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.