#ifndef BIWAK_SPI_HPP
#define BIWAK_SPI_HPP
//----------------------------------------------------------------------------
///
/// \brief  SPI
///
///         See implementation files for further information.
//
/// \date   20150121
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


//---Includes-----------------------------------------------------------------


//---Own------------------------------

#include <biwak/biwak.h>
#include <biwak/gpio.hpp>


//---Forward declarations-----------------------------------------------------


#if defined (MCU_PLATFORM_STM32)
   // #define SPI_HANDLE_TYPE    SPI_HandleTypeDef
   #include <HALWrapper/stm32_dma.h>       // SPI wants that
   #include <HALWrapper/stm32_spi.h>
#else
   #define SPI_HandleTypeDef    void
#endif


//---Defines------------------------------------------------------------------


//---Declaration--------------------------------------------------------------


#if defined (MCU_PLATFORM_STM32)

enum ESpiMode: uint32_t
{
   eSpiMode187Khz = SPI_BAUDRATEPRESCALER_256,
   eSpiMode375Khz = SPI_BAUDRATEPRESCALER_128,
   eSpiMode750Khz = SPI_BAUDRATEPRESCALER_64,
   eSpiMode1500Khz= SPI_BAUDRATEPRESCALER_32,
   eSpiMode3Mhz   = SPI_BAUDRATEPRESCALER_16,
   eSpiMode6Mhz   = SPI_BAUDRATEPRESCALER_8,
   eSpiMode12Mhz  = SPI_BAUDRATEPRESCALER_4,
   eSpiMode24Mhz  = SPI_BAUDRATEPRESCALER_2,
   eSpiModeLast=eSpiMode24Mhz
};

#else

enum ESpiMode: uint32_t
{
   eSpiMode1500Khz,
   eSpiMode3Mhz,
   eSpiMode6Mhz,
   eSpiMode12Mhz,
   eSpiMode24Mhz,
};

#endif


struct SSpiConfig;
//enum HAL_StatusTypeDef {ss,sa};

class CSpi
{

   private:
      const SSpiConfig &configData;
      SPI_HandleTypeDef* m_pHandler;
      int m_bytesPerData = 1;

      int m_status;

   public:

      CSpi(const SSpiConfig &configData, ESpiMode eSpiMode);
      void setMode(ESpiMode eSpiMode);
      ESpiMode getMode();
      bool isSlowerOrEqual( ESpiMode mode );
      void init();
      ~CSpi();

      SPI_HandleTypeDef* getHandler()
      {
         return(m_pHandler);
      }

      void convertEndianess(uint32_t &value, int count);
      uint32_t writeReadData(uint32_t value, int count);
      int writeReadData(const uint8_t* out, uint8_t* in, int count);

      int writeData(uint32_t value, int count = 1);
      int writeData(const uint8_t* data, int count = 1);

      uint32_t readData( int count = 1 );
      uint32_t readData(uint8_t *data, int count);
      
      void setDataSize(int size);

      void error();
};


//---fin----------------------------------------------------------------------
#endif // ? ! BIWAK_SPI_HPP
