#ifndef _SPICH_HPP_
#define _SPICH_HPP_

#include "pin.hpp"
#include "spi.hpp"

// spi channel has a hardware spi object and a pin object for the chipselect. 

template <typename DerivedPin,
          typename DerivedSPI>
struct SPICH
{
    SPICH(Pin<DerivedPin>& csPin,
            SPI<DerivedSPI>& spi) :
        chipSelect(csPin),
        spiHwCH(spi) 
    {

    }

    uint8_t read_write_u8(const uint8_t& data)
    {
        uint8_t temp;

        // spiHwCH.takeMutex();
        chipSelect.write(false);
        
        temp = spiHwCH.trx_u8(data);

        chipSelect.write(true);
        // spiHwCH.releaseMutex();
        return temp;
    }

    void readArray(const uint8_t& address,
                   uint8_t* buffer,
                   const uint8_t& len)
    {
        // spiHwCH.takeMutex();
        chipSelect.write(false);

        spiHwCH.tx(address);

        for(uint8_t i = 0; i < len;i++) {
            buffer[i] = spiHwCH.rx();
        };

        chipSelect.write(true);
        // spiHwCH.releaseMutex();
    }


    void writeArray(const uint8_t& address,
                    const uint8_t* buffer,
                    const uint8_t& len)
    {
        chipSelect.write(false);

        spiHwCH.tx(address);

        for(uint8_t i = 0; i < len; i++) {
            spiHwCH.tx(buffer[i]);
        };

        chipSelect.write(true);
    }

    private:

    // hardware resources
    Pin<DerivedPin>& chipSelect;
    SPI<DerivedSPI>& spiHwCH;
};

#endif // _SPICH_HPP_
