Skip to content

File spiMultislave.h

File List > external-docs > libDaisy > src > per > spiMultislave.h

Go to the documentation of this file

Source Code

#pragma once
#ifndef DSY_SPI_MULTISLAVE_H
#define DSY_SPI_MULTISLAVE_H

#include "daisy_core.h"
#include "spi.h"
#include "gpio.h"

namespace daisy
{
class MultiSlaveSpiHandle
{
  public:
    static constexpr size_t max_num_devices_ = 4;
    struct Config
    {
        struct
        {
            Pin sclk; 
            Pin miso; 
            Pin mosi; 
            Pin nss[max_num_devices_];
        } pin_config;

        SpiHandle::Config::Peripheral    periph;
        SpiHandle::Config::Direction     direction;
        unsigned long                    datasize;
        SpiHandle::Config::ClockPolarity clock_polarity;
        SpiHandle::Config::ClockPhase    clock_phase;
        SpiHandle::Config::BaudPrescaler baud_prescaler;
        size_t                           num_devices;
    };

    MultiSlaveSpiHandle() {}
    MultiSlaveSpiHandle(const MultiSlaveSpiHandle& other) = delete;

    SpiHandle::Result Init(const Config& config);

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

    SpiHandle::Result BlockingTransmit(size_t   device_index,
                                       uint8_t* buff,
                                       size_t   size,
                                       uint32_t timeout = 100);

    SpiHandle::Result BlockingReceive(size_t   device_index,
                                      uint8_t* buff,
                                      uint16_t size,
                                      uint32_t timeout = 100);

    SpiHandle::Result BlockingTransmitAndReceive(size_t   device_index,
                                                 uint8_t* tx_buff,
                                                 uint8_t* rx_buff,
                                                 size_t   size,
                                                 uint32_t timeout = 100);

    SpiHandle::Result
    DmaTransmit(size_t                              device_index,
                uint8_t*                            buff,
                size_t                              size,
                SpiHandle::StartCallbackFunctionPtr start_callback,
                SpiHandle::EndCallbackFunctionPtr   end_callback,
                void*                               callback_context);

    SpiHandle::Result
    DmaReceive(size_t                              device_index,
               uint8_t*                            buff,
               size_t                              size,
               SpiHandle::StartCallbackFunctionPtr start_callback,
               SpiHandle::EndCallbackFunctionPtr   end_callback,
               void*                               callback_context);

    SpiHandle::Result
    DmaTransmitAndReceive(size_t                              device_index,
                          uint8_t*                            tx_buff,
                          uint8_t*                            rx_buff,
                          size_t                              size,
                          SpiHandle::StartCallbackFunctionPtr start_callback,
                          SpiHandle::EndCallbackFunctionPtr   end_callback,
                          void*                               callback_context);

    int CheckError();

  private:
    MultiSlaveSpiHandle& operator=(const MultiSlaveSpiHandle&)
    {
        return *this;
    };

    void        EnableDevice(size_t device_index);
    void        DisableDevice(size_t device_index);
    static void DmaStartCallback(void* context);
    static void DmaEndCallback(void* context, SpiHandle::Result result);

    Config    config_;
    SpiHandle spiHandle_;
    GPIO      nss_pins[max_num_devices_];

    struct DmaTransfer
    {
        int8_t                              device_index;
        SpiHandle::StartCallbackFunctionPtr start_callback;
        SpiHandle::EndCallbackFunctionPtr   end_callback;
        void*                               callback_context;

        void Invalidate() { device_index = -1; }
        bool IsValid() const { return device_index >= 0; }
    } current_dma_transfer_;
};

} // namespace daisy

#endif // ifndef DSY_SPI_MULTISLAVE_H