#include "main.h"
#include "ad0x0_i2c2.h"
#include "ad0x0_i2c_ext.h"

//#include "stm8s_delay.h"

#define I2CX                ((I2C_TypeDef *)I2C2_BASE)
//#undef  AD0X0_I2C2_DBG
//#define	  AD0X0_I2C2_DBG
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//ВАЖНО!!! если включить, то процессинг коллбэков передачи\приема будет работать
//через очередь фриртоса (возникнут 50-80 мкс задержки через каждые 5-10 команд
//(в видео рассказано должно быть))
//#define	  AD0X0_USE_I2C2_PROCESS_THROUGH_XQUEUE
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/*новая политика партии: включаем тока те ивенты, которые нужны для конкретных команд*/

__weak	void ad0x0_i2c2_err_cb(void);
//void    ad0x0_i2c2_process(void);
void    ad0x0_i2c2_err(void);
void    ad0x0_i2c2_err2(char *_str);
void    ad0x0_i2c2_pop(void);
/*2do:
Разобраться что вызывается из прерывания
ad0x0_i2c2_push - вызывать только из задач. В колбэках незя

*/
static ad0x0_i2c_desc_s i2c_desc;

struct ad0x0_i2c_cmd_s ad0x0_i2c2_fifo[AD0X0_FIFO_COUNT];
volatile struct ad0x0_i2c_cmd_s *ad0x0_i2c2_pcurhwi=0,*ad0x0_i2c2_pcurswi=0;
volatile uint32_t ad0x0_i2c2_wait_cycles=0,ad0x0_i2c2_wait_cycles_push=0;
uint8_t (*ad0x0_i2c2_pfunc)(void);
//extern xSemaphoreHandle xSemI2C2_01;
volatile xQueueHandle	xqi2c2_01=NULL;

void	ad0x0_i2c2_restart(void);
xQueueHandle	get_xqueue_i2c2(void){return xqi2c2_01;}
	
void ad0x0_i2c2_xqRecieveHandler(void){
	struct ad0x0_i2c_cmd_s *p=NULL;
	//Если в очереди нихера то выходим!!!!!!!!!!!!!!!!!!!!!!!!!
	if(xQueueReceive(xqi2c2_01,&p,0) != pdPASS)return;
	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	uint8_t ctype=p->ctype & 0x3f;
	switch(ctype){    
		case ADQ_DELAY_MS:
			osDelay(p->cbyte);
			ad0x0_i2c2_next(false);
		break;
		#ifdef AD0X0_USE_I2C2_PROCESS_THROUGH_XQUEUE
		case ADQ_HAL_ADDR_TX_BUF_SEQ_FIRST_EXT:
		case ADQ_HAL_ADDR_TX_BUF_STOP_EXT:
			if(!(ad0x0_i2c2_pcurhwi->cbyte & 0x80)){
							ad0x0_i2c_ext_post_process(&i2c_desc,ad0x0_i2c2_pcurhwi->cbyte);
							ad0x0_i2c2_pcurhwi->cbyte|=0x80;
			}
			ad0x0_i2c2_pop();
			if(!(ad0x0_i2c2_pcurhwi->ctype & ADQ_EMPTY)){//(очередь не пустая)
				ad0x0_i2c2_process(false);
			}
		break;
			#endif
		default:
			ad0x0_err();
	}
}

static void set_events(uint16_t _ev){
	//строка ниже, попробую перевести ее: "выключаем биты, которые надо выставить, кроме тех, которые должны остаться"
//	I2CX->CR2 &= (~(I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN)) | _ev;
//	I2CX->CR2 |= _ev | I2C_CR2_ITERREN;
}

/*эта тема не отлаживалась, ПРОВЕРИТЬ!!!!!!*/
static portFORCE_INLINE void xqSendProcess(uint8_t _from_isr){
	char str[10];
	static portBASE_TYPE xHigherPriorityTaskWoken;
	__enable_irq();
	if(_from_isr){		
		xHigherPriorityTaskWoken=false;
		BaseType_t res=xQueueSendFromISR(xqi2c2_01,(void*)&ad0x0_i2c2_pcurhwi,&xHigherPriorityTaskWoken);
		if(res==pdTRUE){
			__asm("nop");
			//portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
		}else
		if(res==errQUEUE_FULL){
			sprintf(str,"%d",(int)res);
			ad0x0_i2c2_err2(str);
		}
		if( xHigherPriorityTaskWoken )
		{
				/* Actual macro used here is port specific. */
				portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
		}
	}else{
		BaseType_t res=xQueueSend(xqi2c2_01,(void*)&ad0x0_i2c2_pcurhwi,100);
		if(res==pdTRUE){
			__asm("nop");
			//taskYIELD();
		}else
		if(res==errQUEUE_FULL){
			sprintf(str,"%d",(int)res);
			ad0x0_i2c2_err2(str);
		}
	}
}

void    ad0x0_i2c2_push(ADQ_t _ctype,uint8_t _cbyte){//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	#ifdef ADDBG4_HIGH
  ADDBG4_HIGH;
	#endif

	while(!(ad0x0_i2c2_pcurswi->ctype & ADQ_EMPTY)){
		osDelay(1);
	}
	
	if(ad0x0_i2c2_pcurswi->ctype & ADQ_EMPTY){
		__disable_irq();
    ad0x0_i2c2_pcurswi->ctype=_ctype;
    ad0x0_i2c2_pcurswi->cbyte=_cbyte;
    ad0x0_i2c2_pcurswi=ad0x0_i2c2_pcurswi->pnext;
		if((!(ad0x0_i2c2_pcurhwi->ctype & ADQ_PROCESSED)) ){
			ad0x0_i2c2_process(false);
		}
		__enable_irq();
		//xqSendProcess();
		//ADQ_I2C_EV_ENABLE;		
  }else ad0x0_err();
  //ADQ_I2C_EV_ENABLE;  
  #ifdef ADDBG4_HIGH
  ADDBG4_LOW;
  #endif
}

void    ad0x0_i2c2_pop(void){//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  if(!(ad0x0_i2c2_pcurhwi->ctype & ADQ_PROCESSED)){
    //попытка выкинуть необработанный элемент
    ad0x0_i2c2_err();
  }
	int was_masked=__disable_irq();
	switch(ad0x0_i2c2_pcurhwi->ctype & 0x3f){
    case ADQ_HAL_ADDR_TX_BUF_SEQ_FIRST_EXT:
		case ADQ_HAL_ADDR_RX_BUF_SEQ_LAST_EXT:
		case ADQ_HAL_ADDR_RX_BUF_SEQ_FIRST_EXT:
		case ADQ_HAL_ADDR_TX_BUF_STOP_EXT:
		case ADQ_USE_EXT:
			
			if(!(ad0x0_i2c2_pcurhwi->cbyte & 0x80))
			{
				ad0x0_i2c_ext_release(ad0x0_i2c2_pcurhwi->cbyte);
				ad0x0_i2c2_pcurhwi->cbyte|=0x80;
			}			
		break;
		case ADQ_DELAY_MS:
		break;
	}		
  ad0x0_i2c2_pcurhwi->ctype|=0x80;//метим как выкинутую
  ad0x0_i2c2_pcurhwi=ad0x0_i2c2_pcurhwi->pnext;
	if(!was_masked)__enable_irq();
}

void    ad0x0_i2c2_pop_all(void){//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	int was_masked=__disable_irq();
  while(  !(ad0x0_i2c2_pcurhwi->ctype & ADQ_EMPTY) ){
		switch(ad0x0_i2c2_pcurhwi->ctype & 0x3f){
    case ADQ_HAL_ADDR_TX_BUF_SEQ_FIRST_EXT:
		case ADQ_HAL_ADDR_RX_BUF_SEQ_LAST_EXT:
		case ADQ_HAL_ADDR_RX_BUF_SEQ_FIRST_EXT:
		case ADQ_HAL_ADDR_TX_BUF_STOP_EXT:
		case ADQ_USE_EXT:
			
			if(!(ad0x0_i2c2_pcurhwi->cbyte & 0x80))
			{
				ad0x0_i2c_ext_release(ad0x0_i2c2_pcurhwi->cbyte);
				ad0x0_i2c2_pcurhwi->cbyte|=0x80;
			}			
		break;
		case ADQ_DELAY_MS:
		break;
	}		
		ad0x0_i2c2_pcurhwi->ctype|=ADQ_EMPTY;//метим как выкинутую
		ad0x0_i2c2_pcurhwi=ad0x0_i2c2_pcurhwi->pnext;
	}
	if(ad0x0_i2c_ext_get_count()){
		ad0x0_i2c_ext_get_count();
		ad0x0_err();
	}
	if(!was_masked)__enable_irq();
}

void    ad0x0_i2c2_next(uint8_t _from_isr){
	ad0x0_i2c2_pop();
	if(!(ad0x0_i2c2_pcurhwi->ctype & (ADQ_EMPTY|ADQS_PROCESSED))){//(очередь не пустая)
			ad0x0_i2c2_process(_from_isr);
	}	
}

void    ad0x0_i2c2_process(uint8_t _from_isr){
	int was_masked=__disable_irq();
	if(ad0x0_i2c2_pcurhwi->ctype & (ADQ_EMPTY|ADQS_PROCESSED)){//(очередь не пустая)
		//ad0x0_err();
		__enable_irq();
		return;
	}
//тут мы шото меняем какие то флаги, а затем ждем прерывания для текущей команды
#ifdef AD0X0_I2C2_DBG
  ADDBG2_HIGH;
#endif
  //если тип не впишится в свитч, то комнда либо отброшена, либо обработана ранее
  switch(ad0x0_i2c2_pcurhwi->ctype){

    case ADQ_HAL_ADDR_TX_BUF_SEQ_FIRST_EXT:
				if(!(ad0x0_i2c2_pcurhwi->cbyte & 0x80))ad0x0_i2c_ext_pre_process(&i2c_desc,ad0x0_i2c2_pcurhwi->cbyte);
				i2c_desc.last_hal_err=HAL_I2C_Master_Seq_Transmit_IT(i2c_desc.phi2c, i2c_desc.addr_w, i2c_desc.tx_pbuf, i2c_desc.pbuf_counter,I2C_FIRST_FRAME);				
				if(HAL_OK != i2c_desc.last_hal_err){
					i2c_desc.last_hal_state=HAL_I2C_GetState(i2c_desc.phi2c);
				}
        ad0x0_i2c2_pcurhwi->ctype|=ADQ_PROCESSED;//метим как обработанную                				
				__enable_irq();
    break;
		case ADQ_HAL_ADDR_RX_BUF_SEQ_LAST_EXT:
				if(!(ad0x0_i2c2_pcurhwi->cbyte & 0x80)){
					ad0x0_i2c_ext_pre_process(&i2c_desc,ad0x0_i2c2_pcurhwi->cbyte);
				}				
				i2c_desc.last_hal_err=HAL_I2C_Master_Seq_Receive_IT(i2c_desc.phi2c, i2c_desc.addr_r, i2c_desc.rx_pbuf, i2c_desc.pbuf_counter,I2C_LAST_FRAME);
				//i2c_desc.last_hal_err=HAL_I2C_Master_Receive_IT(i2c_desc.phi2c, i2c_desc.addr_r, i2c_desc.rx_pbuf, i2c_desc.pbuf_counter);
				if(HAL_OK != i2c_desc.last_hal_err){
					i2c_desc.last_hal_state=HAL_I2C_GetState(i2c_desc.phi2c);
				}
        ad0x0_i2c2_pcurhwi->ctype|=ADQ_PROCESSED;//метим как обработанную                				
				__enable_irq();
    break;
		case ADQ_HAL_ADDR_TX_BUF_STOP_EXT:
				if(!(ad0x0_i2c2_pcurhwi->cbyte & 0x80)){
					ad0x0_i2c_ext_pre_process(&i2c_desc,ad0x0_i2c2_pcurhwi->cbyte);
				}				
				i2c_desc.last_hal_err=HAL_I2C_Master_Transmit_IT(i2c_desc.phi2c, i2c_desc.addr_w, i2c_desc.tx_pbuf, i2c_desc.pbuf_counter);
				if(HAL_OK != i2c_desc.last_hal_err){
					i2c_desc.last_hal_state=HAL_I2C_GetState(i2c_desc.phi2c);
				}
        ad0x0_i2c2_pcurhwi->ctype|=ADQ_PROCESSED;//метим как обработанную                				
				__enable_irq();
    break;

    case ADQ_DELAY_MS:
				//set_events(0);
				//HAL_Delay(ad0x0_i2c2_pcurhwi->cbyte);
        ad0x0_i2c2_pcurhwi->ctype|=ADQ_PROCESSED;//метим как обработанную
				__enable_irq();
				#ifdef INC_FREERTOS_H
				//osDelay(ad0x0_i2c2_pcurhwi->cbyte);
		//задача, в которую это придет, затормозится на скока надо и вызовет поп и процесс
				xqSendProcess(_from_isr);
				#else
				ad0x0_timman_add(ad0x0_spi1_pcurhwi->cbyte,ad0x0_spi1_next);
				#endif
    break;    

		case ADQ_USE_EXT:
			if(ad0x0_i2c2_pcurhwi->ctype & ADQ_PROCESSED){__enable_irq();ad0x0_i2c2_err();}
			else{
        ad0x0_i2c2_pcurhwi->ctype|=ADQ_PROCESSED;//метим как обработанную
				__enable_irq();
				uint8_t cb=ad0x0_i2c2_pcurhwi->cbyte;
				ad0x0_i2c2_pcurhwi->cbyte|=0x80;
				ad0x0_i2c_ext_pre_process(&i2c_desc,cb);
				ad0x0_i2c_ext_post_process(&i2c_desc,cb);
				ad0x0_i2c2_pop();
				if(!(ad0x0_i2c2_pcurhwi->ctype & (ADQ_EMPTY|ADQS_PROCESSED))){//(очередь не пустая)
					ad0x0_i2c2_process(_from_isr);
				}
				//xqSendProcess();
			}
				//__enable_irq();				
    break;
  default:
      ad0x0_i2c2_err();
	//__ASM("nop");
  }
	i2c_desc.last_hwi_process_tick=HAL_GetTick();
	//while(herr);
#ifdef AD0X0_I2C2_DBG
  ADDBG2_LOW;
#endif
}

/*void 		ad0x0_i2c2_irq_err(void){
	//я бы это не обрабатывал, если бы не пидорский гироскоп, который не прислал нак при адресе...
	//метим команду как необработанную и пробуем по новой
	uint8_t ctypex=ad0x0_i2c2_pcurhwi->ctype;
	uint32_t sr1=0;//,sr2=0;
	sr1=I2CX->SR1;//
	I2CX->SR2;//
	if(sr1 & I2C_SR1_ARLO){
		I2CX->SR1 &= ~I2C_SR1_ARLO;
		
	}else
  switch(ctypex & 0x3f){
  case ADQ_START_ADDR:
		if(sr1 & I2C_SR1_AF){
			__disable_irq();
			I2CX->SR1&= ~I2C_SR1_AF;
			I2CX->CR1 |= I2C_CR1_STOP;
			while((I2CX->CR1 & I2C_CR1_STOP));
			ad0x0_i2c2_pcurhwi->ctype&=~ADQ_PROCESSED;//метим как НЕ обработанную
			ad0x0_i2c2_process();
		}
	break;
	case ADQ_RX_PBUF_STOP_EXT:
	if(sr1 & I2C_SR1_BERR){
		__disable_irq();
		I2CX->SR1&= ~I2C_SR1_BERR;
		I2CX->CR1 |= I2C_CR1_STOP;
		while((I2CX->CR1 & I2C_CR1_STOP));
		ad0x0_i2c2_pcurhwi->ctype&=~ADQ_PROCESSED;//метим как НЕ обработанную
		ad0x0_i2c2_process();
	}
	break;
		default:
      ad0x0_i2c2_err();
	}		
}*/

void		ad0x0_i2c2_MasterRxCpltCallback(void){
	AD_I2C_INT_HIGH
	uint8_t ctypex=ad0x0_i2c2_pcurhwi->ctype;
  switch(ctypex & 0x3f){
	case ADQ_HAL_ADDR_RX_BUF_SEQ_FIRST_EXT:
	case ADQ_HAL_ADDR_RX_BUF_SEQ_LAST_EXT:
		
		#ifdef AD0X0_USE_I2C2_PROCESS_THROUGH_XQUEUE
		xqSendProcess(true);
		#else
		if(!(ad0x0_i2c2_pcurhwi->cbyte & 0x80)){
						ad0x0_i2c_ext_post_process(&i2c_desc,ad0x0_i2c2_pcurhwi->cbyte);
						ad0x0_i2c2_pcurhwi->cbyte|=0x80;
		}
		ad0x0_i2c2_pop();
		if(!(ad0x0_i2c2_pcurhwi->ctype & ADQ_EMPTY)){//(очередь не пустая)
			ad0x0_i2c2_process(true);
		}		
		#endif
	break;
	default:
      ad0x0_i2c2_err();
	}		
	AD_I2C_INT_LOW
}

void		ad0x0_i2c2_MasterTxCpltCallback(void){
	AD_I2C_INT_HIGH
	uint8_t ctypex=ad0x0_i2c2_pcurhwi->ctype;
  switch(ctypex & 0x3f){
	case ADQ_HAL_ADDR_TX_BUF_SEQ_FIRST_EXT:
	case ADQ_HAL_ADDR_TX_BUF_STOP_EXT:
		if(!(ad0x0_i2c2_pcurhwi->cbyte & 0x80)){
						ad0x0_i2c_ext_post_process(&i2c_desc,ad0x0_i2c2_pcurhwi->cbyte);
						ad0x0_i2c2_pcurhwi->cbyte|=0x80;
		}
		#ifdef AD0X0_USE_I2C2_PROCESS_THROUGH_XQUEUE
		xqSendProcess(true);
		#else
		ad0x0_i2c2_pop();
		if(!(ad0x0_i2c2_pcurhwi->ctype & ADQ_EMPTY)){//(очередь не пустая)
			ad0x0_i2c2_process(true);
		}		
		#endif
	break;		
	default:
      ad0x0_i2c2_err();
	}		
	AD_I2C_INT_LOW
}

void		ad0x0_i2c2_ErrorCallback(void){
	uint8_t ctypex=ad0x0_i2c2_pcurhwi->ctype;
	HAL_I2C_StateTypeDef hstate=HAL_I2C_GetState(i2c_desc.phi2c);
	uint32_t herr=HAL_I2C_GetError(i2c_desc.phi2c);
  switch(ctypex & 0x3f){
	case ADQ_HAL_ADDR_TX_BUF_SEQ_FIRST_EXT:
	case ADQ_HAL_ADDR_TX_BUF_STOP_EXT:
	case ADQ_HAL_ADDR_RX_BUF_SEQ_LAST_EXT:
	case ADQ_HAL_ADDR_RX_BUF_SEQ_FIRST_EXT:
	//ad0x0_i2c2_pcurhwi->ctype&=~ADQ_PROCESSED;//метим как НЕ обработанную
		//ad0x0_i2c2_process();
		//ad0x0_i2c_ext_release(ad0x0_i2c2_pcurhwi->cbyte);
		ad0x0_i2c2_restart();
	break;	
		default:
      ad0x0_i2c2_err();
	}		
	if(hstate==0){
	}
}

void	ad0x0_i2c2_restart(void){
	ad0x0_i2c2_err();
	/*i2c_desc.is_i2c_restarting=1;
	if(i2c_desc.pfunc_on_error)i2c_desc.pfunc_on_error();
	ad0x0_timman_remove(ad0x0_i2c2_next);
	ad0x0_i2c2_pop_all();
	I2C2->CR1 &= ~(I2C_CR1_SWRST);
	HAL_I2C_DeInit(i2c_desc.phi2c);
	HAL_I2C_Init(i2c_desc.phi2c);
	i2c_desc.is_i2c_restarting=0;
	if(i2c_desc.pfunc_on_i2c_restart)i2c_desc.pfunc_on_i2c_restart();*/
}

void		ad0x0_i2c2_AbortCpltCallback(void){
	uint8_t ctypex=ad0x0_i2c2_pcurhwi->ctype;
  ad0x0_i2c2_err();	
	ad0x0_i2c2_pop();
	if(!(ad0x0_i2c2_pcurhwi->ctype & ADQ_EMPTY)){//(очередь не пустая)
			ad0x0_i2c2_process(true);
		}
	//xqSendProcess();
}

uint8_t ad0x0_i2c2_is_queue_ready(void){	
	//return ((ad0x0_i2c2_pcurhwi->ctype & ADQ_EMPTY) && (ad0x0_i2c2_pcurhwi->pnext->ctype & ADQ_EMPTY) && !(I2CX->SR1 & I2C_SR2_BUSY));
	return ((ad0x0_i2c2_pcurhwi->ctype & ADQ_EMPTY) && (ad0x0_i2c2_pcurhwi->pnext->ctype & ADQ_EMPTY) && !i2c_desc.is_i2c_restarting);
}

void    ad0x0_i2c2_initq(void){
  ad0x0_i2c2_pcurhwi=ad0x0_i2c2_pcurswi=ad0x0_i2c2_fifo;
  ad0x0_i2c2_fifo[AD0X0_FIFO_COUNT-1].pnext=ad0x0_i2c2_fifo;
  ad0x0_i2c2_fifo[AD0X0_FIFO_COUNT-1].ctype=ADQ_EMPTY;
	ad0x0_i2c2_fifo[AD0X0_FIFO_COUNT-1].cbyte=0;
  for(uint16_t i=0;i<=AD0X0_FIFO_COUNT-2;i++){
    ad0x0_i2c2_fifo[i].pnext=ad0x0_i2c2_fifo+i+1;
    ad0x0_i2c2_fifo[i].ctype=ADQ_EMPTY;
		ad0x0_i2c2_fifo[i].cbyte=0;
  }
}

void    ad0x0_i2c2_err(void){
  ad0x0_err();  
}
  

void ad0x0_i2c2_init(I2C_HandleTypeDef *_phi2c) {
	memset(&i2c_desc,0,sizeof(ad0x0_i2c_desc_s));
	i2c_desc.phi2c=_phi2c;
	i2c_desc.i2cx=I2CX;
	i2c_desc.perrfunc=ad0x0_err;	
	ad0x0_i2c2_initq();
	i2c_desc.last_hwi_process_tick=HAL_GetTick();	
	xqi2c2_01 = xQueueCreate(1,sizeof(struct ad0x0_i2c_cmd_s *));	
	if(!xqi2c2_01)ad0x0_err();
	//I2CX->CR1 |= I2C_CR1_PE;
	//I2CX->CR2 |= (I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN);
//pins configuing in cubemx...main.c  
}

void		ad0x0_i2c2_set_restart_func(void (*_pfunc_on_error)(void), void (*_pfunc_on_i2c_restart)(void))
{
	i2c_desc.pfunc_on_error=_pfunc_on_error;
	i2c_desc.pfunc_on_i2c_restart=_pfunc_on_i2c_restart;	
}

void ad0x0_i2c2_deinit(void) {
  //I2CX->CR2 &= ~(I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN);
	I2CX->CR1 &= ~I2C_CR1_PE;
	while(I2CX->CR1 & I2C_CR1_PE);
	ad0x0_i2c2_initq();
	I2CX->CR1 |= I2C_CR1_PE;
	//I2CX->CR2 |= (I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN);
//pins configuing in cubemx...main.c  
}

uint8_t    ad0x0_i2c2_get_ext_async2(uint8_t *_p_out_handle,void **_p_out_i2c_ext_t){
	while( !ad0x0_i2c_ext_get(_p_out_handle, (ad0x0_i2c_ext_t**)_p_out_i2c_ext_t) ){
		__enable_irq();
		set_events(I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN);
		ad0x0_i2c2_wait_cycles++;
		osDelay(1);	
	}
	return 1;
}

uint8_t    ad0x0_i2c2_get_ext_setbuf(uint8_t *_tx_pbuf,uint8_t *_rx_pbuf, uint8_t _count){
	//c_enter_ext++;
	uint8_t i;	
	ad0x0_i2c_ext_t *pf;
	ad0x0_i2c2_get_ext_async2(&i,(void**)&pf);
//	if(pf->pSetTXRXBuf ||pf->_p_cb_func|| pf->calls_count)ad0x0_i2c2_err();//УБРАТЬ
	pf->pbuf_tx=_tx_pbuf;
	pf->pbuf_rx=_rx_pbuf;
	pf->pbuf_count=_count;
	//pf->i2c=I2;
	pf->p_pre_SetTXRXBuf=EXT_SetTXRXBuf_i2c;//ну я хз, пока делаем так... ПЕРЕДЕЛАТЬ!!!!!!
	return i;
	//ad0x0_i2c2_push(ADQ_USE_EXT,i);
	//c_enter_ext--;
}

void    ad0x0_i2c2_push_ext_setfunc(uint8_t _sf_id,void (*_p_cb_func)(uint8_t _sf_id,ad0x0_i2c_desc_s *pdi2c,void *p_i2c_ext_t)){
	//c_enter_ext++;
	uint8_t i;	
	ad0x0_i2c_ext_t *pf;
	ad0x0_i2c2_get_ext_async2(&i,(void**)&pf);
	pf->sf_id=_sf_id;
	pf->_p_post_cb_func=_p_cb_func;//ну я хз, пока делаем так... ПЕРЕДЕЛАТЬ!!!!!!
	//pf->=SPIX;
	ad0x0_i2c2_push(ADQ_USE_EXT,i);
	//c_enter_ext--;
}
void    ad0x0_i2c2_err2(char *_str){
	if(strcmp(_str,"suka")==0){
		__ASM("nop");
	}
	ad0x0_i2c2_err();
}
