Skip to content

File spi.h

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

Go to the documentation of this file

Source Code

#pragma once
#ifndef DSY_SPI_H
#define DSY_SPI_H

#include "daisy_core.h"

#if !UNIT_TEST
#include "util/hal_map.h"
#endif

/* TODO:
- Add documentation
- Add IT
*/

namespace daisy
{
class SpiHandle
{
  public:
    struct Config
    {
        enum class Peripheral
        {
            SPI_1,
            SPI_2,
            SPI_3,
            SPI_4,
            SPI_5,
            SPI_6,
        };

        enum class Mode
        {
            MASTER,
            SLAVE,
        };

        enum class Direction
        {
            TWO_LINES,
            TWO_LINES_TX_ONLY,
            TWO_LINES_RX_ONLY,
            ONE_LINE,
        };

        enum class ClockPolarity
        {
            LOW,
            HIGH,
        };

        enum class ClockPhase
        {
            ONE_EDGE,
            TWO_EDGE,
        };

        enum class NSS
        {
            SOFT,
            HARD_INPUT,
            HARD_OUTPUT,
        };

        enum class BaudPrescaler
        {
            PS_2,
            PS_4,
            PS_8,
            PS_16,
            PS_32,
            PS_64,
            PS_128,
            PS_256,
        };

        struct
        {
            Pin sclk; 
            Pin miso; 
            Pin mosi; 
            Pin nss;  
        } pin_config;

        Config()
        {
            // user must specify periph, mode, direction, nss, and pin_config
            datasize       = 8;
            clock_polarity = ClockPolarity::LOW;
            clock_phase    = ClockPhase::ONE_EDGE;
            baud_prescaler = BaudPrescaler::PS_8;
        }

        Peripheral    periph;
        Mode          mode;
        Direction     direction;
        unsigned long datasize;
        ClockPolarity clock_polarity;
        ClockPhase    clock_phase;
        NSS           nss;
        BaudPrescaler baud_prescaler;
    };

    SpiHandle() : pimpl_(nullptr) {}
    SpiHandle(const SpiHandle& other) = default;
    SpiHandle& operator=(const SpiHandle& other) = default;

    enum class Result
    {
        OK, 
        ERR 
    };

    enum class DmaDirection
    {
        RX,    
        TX,    
        RX_TX, 
    };

    Result Init(const Config& config);

    const Config& GetConfig() const;

    typedef void (*StartCallbackFunctionPtr)(void* context);
    typedef void (*EndCallbackFunctionPtr)(void* context, Result result);


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

    Result BlockingReceive(uint8_t* buffer, uint16_t size, uint32_t timeout);

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

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

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

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

    int CheckError();

    class Impl; 
  private:
    Impl* pimpl_;
};

extern "C"
{
    void dsy_spi_global_init();
};

} // namespace daisy

#endif