Skip to content

File sr_4021.h

File List > dev > sr_4021.h

Go to the documentation of this file

Source Code

#pragma once
#ifndef DEV_SR_4021_H
#define DEV_SR_4021_H
#include "per/gpio.h"
#include "sys/system.h"

namespace daisy
{
template <size_t num_daisychained = 1, size_t num_parallel = 1>
class ShiftRegister4021
{
  public:
    struct Config
    {
        Pin clk;   
        Pin latch; 
        Pin data[num_parallel]; 
        uint32_t delay_ticks = 10;
    };

    ShiftRegister4021() {}
    ~ShiftRegister4021() {}

    void Init(const Config& cfg)
    {
        config_ = cfg;
        // Init GPIO
        clk_.Init(cfg.clk, GPIO::Mode::OUTPUT);
        latch_.Init(cfg.latch, GPIO::Mode::OUTPUT);
        for(size_t i = 0; i < num_parallel; i++)
        {
            data_[i].Init(cfg.data[i], GPIO::Mode::INPUT);
        }
        // Init States
        for(size_t i = 0; i < kTotalStates; i++)
        {
            states_[i] = false;
        }
    }

    void Update()
    {
        uint32_t del_ticks = config_.delay_ticks;
        clk_.Write(false);
        latch_.Write(true);
        System::DelayTicks(del_ticks);
        latch_.Write(false);
        uint32_t idx;
        for(size_t i = 0; i < 8 * num_daisychained; i++)
        {
            clk_.Write(false);
            System::DelayTicks(del_ticks);
            for(size_t j = 0; j < num_parallel; j++)
            {
                idx = (8 * num_daisychained - 1) - i;
                idx += (8 * num_daisychained * j);
                states_[idx] = data_[j].Read();
            }
            clk_.Write(true);
            System::DelayTicks(del_ticks);
        }
    }

    inline bool State(int index) const { return states_[index]; }

    inline const Config& GetConfig() const { return config_; }

  private:
    static constexpr int kTotalStates = 8 * num_daisychained * num_parallel;
    Config               config_;
    bool                 states_[kTotalStates];
    GPIO                 clk_;
    GPIO                 latch_;
    GPIO                 data_[num_parallel];
};

} // namespace daisy

#endif