#ifndef AD0X0_SPI_H
#define AD0X0_SPI_H

#include "stm32f103xb.h"
#include "stdint.h"
#include "../admisc/ad0x0_memman.h"
//#include "ad0x0_sfuncs.h"
#define AD0X0_SPI_EXT_COUNT 32

// ************************** I2C Configuration Variables **************************

/* definition of fast or default standard mode (bus speed up to 400 or 100 kHz) */
//#define FAST_I2C_MODE
#define AD0X0_SPI_FIFO_COUNT 16
    
//#define AD0X0_SPI_DBG
#ifndef AD0X0_LE_SWAP
#define AD0X0_LE_SWAP(X) X = ((uint16_t)X >> 8)|((uint16_t)X << 8)
#endif

#define AD0X0_DAMN_DBG
/*
очередь для SPI. Это почти копипаста с очереди I2C. Ну тут интересно, что кроме передачи нужно делать DC, команда\данные.
И RES - сброс. Как то надо протащить пины в виде параметров или еще как то. 
*/

//#undef AD0X0_I2C_DBG_CO
typedef enum{
//	ADQS_START_ADDR           = (uint8_t)0x1,
	ADQS_TX                   = (uint8_t)0x0,
	ADQS_TXRX_PBUF_DMA        = (uint8_t)0xB, 
	ADQS_TXRX_PBUF_DMA_EXT    = (uint8_t)0x5,
	ADQS_TX_PBUF							= (uint8_t)0x17, 
	ADQS_TX_PBUF_EXT          = (uint8_t)0xA,
	ADQS_TX_PBUF_DMA					= (uint8_t)0x1C, 
	ADQS_TX_PBUF_DMA_EXT      = (uint8_t)0x2,
	/*	ADQS_SET_RX_PBUF_H           = (uint8_t)0xC, //[15:8]
	ADQS_SET_RX_PBUF_L           = (uint8_t)0xD, //[7:0]
	ADQS_SET_RX_PBUF_HH           = (uint8_t)0xE, //[31:24] на стм8 хватало байта, но тут это не сканает
	ADQS_SET_RX_PBUF_HL           = (uint8_t)0xF, //[23:16] в общем пока делаю весь указатель (ad= (uint8_t)0x0 23082020)
	ADQS_SET_TX_PBUF_H           = (uint8_t)0x18, //[15:8]
	ADQS_SET_TX_PBUF_L           = (uint8_t)0x19, //[7:0]
	ADQS_SET_TX_PBUF_HH           = (uint8_t)0x1A, //[31:24] на стм8 хватало байта, но тут это не сканает
	ADQS_SET_TX_PBUF_HL           = (uint8_t)0x1B, //[23:16] в общем пока делаю весь указатель (ad= (uint8_t)0x0 23082020)	*/
	/*ADQS_SET_PFUNC_H           = (uint8_t)0x10, //[15:8]
	ADQS_SET_PFUNC_L           = (uint8_t)0x11, //[7:0]
	ADQS_SET_PFUNC_HH           = (uint8_t)0x12, //[31:24] на стм8 хватало байта, но тут это не сканает
	ADQS_SET_PFUNC_HL           = (uint8_t)0x13, //[23:16] после этого вызовется ф-я!!!!!!!*/
	ADQS_USE_EXT					    = (uint8_t)0x6, //а тут уже все меняется... эдакий шейдер очереди
//ADQS_LRB_MODIFY_APPLY_MASK    = (uint8_t)0x6, //прочитанный байт &= cbyte
	//ADQS_LRB_MODIFY_APPLY_OR      = (uint8_t)0x7, //прочитанный байт |= cbyte
	ADQS_ST7735_SET_DC=(uint8_t)0x14,
	ADQS_ST7735_SET_CS=(uint8_t)0x15,
	ADQS_SET_CS              = (uint8_t)0x4,	//инженеры стм32 обосрались с аппаратным NSS как тока могли... значит надо дергать ногами
	ADQS_ST7735_SET_RESET=(uint8_t)0x16,
	ADQS_DELAY_MS             = (uint8_t)0x9,
	ADQS_PROCESSED          = (uint8_t)0x40,//6й бит
	ADQS_EMPTY		          = (uint8_t)0x80 //7й бит
} ADQS_t;

#define AD0X0_SPI_DBG
/*#define AD_DBG_S1_Pin GPIO_PIN_1
#define AD_DBG_S1_GPIO_Port GPIOA
#define AD_DBG_S2_Pin GPIO_PIN_2
#define AD_DBG_S2_GPIO_Port GPIOA
#define AD_DC_Pin GPIO_PIN_3
#define AD_DC_GPIO_Port GPIOA
#define AD_RES_Pin GPIO_PIN_0
#define AD_RES_GPIO_Port GPIOB*/
//хитрая связка, но так удобнее связать кубе эмикс с нашими исходниками

//#define SPI2_NSS_Port SPI2_NSS_GPIO_Port
//#define SPI2_NSS_Pin SPI2_NSS_Pin
#ifdef AD0X0_SPI_DBG
	#define ADS1_HIGH  AD_DBG_S1_GPIO_Port->ODR |= AD_DBG_S1_Pin;
#else
	#define ADS1_HIGH ;
#endif
#ifdef AD0X0_SPI_DBG
#define ADS1_LOW  	AD_DBG_S1_GPIO_Port->ODR &= ~AD_DBG_S1_Pin;;//
#else
	#define ADS1_LOW ;
#endif
#ifdef AD0X0_SPI_DBG
#define ADS2_HIGH AD_DBG_S2_GPIO_Port->ODR |= AD_DBG_S2_Pin;
#else
	#define ADS2_HIGH ;
#endif
#ifdef AD0X0_SPI_DBG
#define ADS2_LOW  AD_DBG_S2_GPIO_Port->ODR &= ~AD_DBG_S2_Pin;//
#else
	#define ADS2_LOW ;
#endif

// ************************* Function Declaration ***************************
__packed struct ad0x0_spi_cmd_s{	
/*	//u8 processed=ctypex & 0x40;//b 0100 0000
	//u8 dropped=ctypex & 0x80;//b 1000 0000*/
  ADQS_t       ctype;//
  uint8_t       cbyte;
	//uint8_t				cext;//ссылка на ...нахер (перенес в отдельную команду)
  __packed struct ad0x0_spi_cmd_s *pnext;
};

/*__packed struct ad0x0_spi_cmd_ext_s{	
	uint8_t				cext;//ссылка на 
};*/

typedef struct {	
/*	//u8 processed=ctypex & 0x40;//b 0100 0000
	//u8 dropped=ctypex & 0x80;//b 1000 0000*/
	SPI_TypeDef *spix;
	volatile uint8_t *rx_pbuf,*tx_pbuf,pbuf_counter;//установочные
	volatile uint8_t *rx_pbuf_cur,*tx_pbuf_cur,pbuf_counter_cur;//текущие
	volatile void (*pfunc)(void);
	void (*perrfunc)(void);
	uint8_t err_ovrflow;
	volatile uint8_t insint;
	volatile uint32_t last_hwi_process_tick;
}ad0x0_spi_desc_s;
/* USER CODE BEGIN PFP */
//это надо в main.c копипастить
/*void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi){
	if(hspi->Instance==(SPI_TypeDef*)SPI1_BASE){
		ad0x0_spi1_dma();
	}else{ad0x0_spi2_dma();}
}
//это надо в main.c копипастить
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi){
	if(hspi->Instance==(SPI_TypeDef*)SPI1_BASE){
		ad0x0_spi1_dma();
	}else{ad0x0_spi2_dma();}	
}
//это надо в main.c копипастить
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi){
	if(hspi->Instance==(SPI_TypeDef*)SPI1_BASE){
		ad0x0_spi1_dma_err();
	}else{ad0x0_spi2_dma_err();}
}*/
/* USER CODE END PFP */
//это туда где хендлеры прерываний
/*void SPI2_IRQHandler(void)
{
   USER CODE BEGIN SPI2_IRQn 0 
	ad0x0_spi2_irq();
   USER CODE END SPI2_IRQn 0 
   USER CODE BEGIN SPI2_IRQn 1 

   USER CODE END SPI2_IRQn 1 
}*/
//это туда где крутится задача 
/*ad0x0_spi1_xqRecieveHandler();
*/
#endif 
