#ifndef AFE4300V2_h
#define AFE4300V2_h

#include <stdint.h>
#include "driver/spi_master.h"
#include "driver/gpio.h"

#include "SPIExt.h"

namespace sts {
namespace driver
{
	struct AFE4300Setting
	{
		int mosi_pin;
		int miso_pin;
		int sclk_pin;
		int cs_pin;
		int clock_pin;
		int reset_pin;
		int ready_pin;
		int sclk_freq_hz;
		int clock_freq_hz;
	};
	/**
	 * @brief Device for reading analog values of weightcells
	 */
	class AFE4300V2
	{
	private:
		/* out */ gpio_num_t PIN_RESET;
		/* in  */ gpio_num_t PIN_DRDY;
		/* out */ gpio_num_t PIN_CLOCK;
		/* out */ gpio_num_t PIN_MOSI;
		/* in  */ gpio_num_t PIN_MISO;
		/* out */ gpio_num_t PIN_SCLK;
		/* ?   */ gpio_num_t PIN_CS;


		uint8_t gain_;
		int weightscale_;
		int weightoffset;

	public:
		AFE4300V2(AFE4300Setting setting);
		AFE4300V2(int reset, int rdy, int mosi, int miso, int sclk, int cs);

		void init() const;
		void resetAFE4300() const;
		void initWeightScale() const;
		void initBCM() const;

		int read() const;

		void setGain(uint8_t gain);

		void setWeightScale(int scale);
		int  getWeightScale() const;

		void setWeightOffset(int offset);
		int  getWeightOffset() const;

		void tare();

	private:
		SPI* m_spi;

		void writeRegister(unsigned char address, unsigned int data) const;
		int  readRegister(unsigned char address) const;
		void initClock() const;

		inline uint32_t IRAM_ATTR micros() const;
		void IRAM_ATTR delayMicroseconds(uint32_t us) const;

	};
} //end namespace driver
} //end namespace sts

#endif /* AFE4300_h */
