/*
 * Copyright (C) 2020-2021 Aloysius Indrayanto
 *
 * This file is part of the eCxx library, see LICENSE file for the license details.
 */


#ifndef INCLUDE_ECXX_PLATFORM_SPECIFIC_SPI_H
#error "this file cannot be included directly"
#endif
#undef INCLUDE_ECXX_PLATFORM_SPECIFIC_SPI_H


#ifndef ECXX_PLATFORM_DUMMY_SPI_H
#define ECXX_PLATFORM_DUMMY_SPI_H


namespace eCxx {


//
// A simple dummy SPI wrapper
//
// WARNING : All functions derived from BasicOutputWriter<T> that accept parameters with data types
//           'PGMCharPointer' and 'PGMCharPointerFar' expect the pointers to come from program
//           memory exclusively!
//
// NOTE    : Whenever possible, use the versions that accept near program pointers because those that
//           accept the far program pointers may have more overhead and restrictions.
//
class SPI : public BasicOutputWriter<SPI> {
    public:
        using SPIMode  = eCxx::SPIMode;
        using DataMode = eCxx::SPIDataMode;

        static constexpr decltype(eCxx::DefaultSPIFrequency) DefaultSPIFrequency = eCxx::DefaultSPIFrequency;

    public:
        inline ~SPI() = default;

    public:
        void begin(SPIMode mode = SPIMode::Master);
        void end();

        void beginTransaction(uint32_t frequency = DefaultSPIFrequency, BitOrder bitOrder = BitOrder::MSBFirst, DataMode dataMode = DataMode::Mode0);
        void endTransaction();

        bool transfer(uint8_t& recv, uint8_t send) const;
        bool transfer(uint8_t* rxtx, uint8_t len) const;

        inline bool write(uint8_t value) const;

        // WARNING : Non-transactional SPI-master mode only!
        void ntmBegin(uint32_t frequency = DefaultSPIFrequency, BitOrder bitOrder = BitOrder::MSBFirst, DataMode dataMode = DataMode::Mode0) const;

        void ntmSelectSlave() const;
        void ntmDeselectSlave() const;

        uint8_t ntmRead(uint8_t dummy) const;
        uint8_t ntmReadX00() const;
        uint8_t ntmReadXFF() const;
        void ntmWrite(uint8_t value) const;

    private:
        inline SPI() = default;
};


} // namespace eCxx


#endif
