Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

shiftIn and shiftOut do not work with SPI_MODE 3 and 4

Aperta
#94 4 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
42/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Ferma
Stack tecnologico
cpp
Ambito
embedded-iot

Direzione di ricerca

Inizia in wiring_shift.c e confronta shiftIn() e shiftOut() con la gestione delle modalità SPI da parte della SPI library. Riproduci il comportamento segnalato di 74HC165 nelle modalità di clock interessate, quindi verifica che il comportamento standard di shift rimanga corretto per le modalità e gli ordini dei bit esistenti. Il lavoro è completato quando le funzioni software gestiscono le modalità segnalate senza perdere né aggiungere bit.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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!

// ===============================================================================================================================
// 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
//
Lingua principale
C++
Stelle
306
Fork
150
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Non abbiamo ancora controllato i file di configurazione di questo progetto. Parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di arduino/ArduinoCore-API

Tutte le issue di arduino/ArduinoCore-API

Issue simili

Altre issue su C++

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.