/*
개념
Falling Edge 
 
1  LOW CS
2. HIGH MOSI
3. LOW CLK

4. LOOP
   int i;
   for (i = 0; i < 7; i++)
   {
	   GPIO_MOSI = DATA(i);
	   GPIO_MISO = DATA(i);
	   HIGH CLK
	   LOW  CLK
   }

5. HIGH MOSI
6. HIGH CS


소스코드 예졔1
*/
#include "GPIO_SPI.h"
#define SDA_SETUP_TIME 4
#define CS_SETUP_TIME  SDA_SETUP_TIME
// LSB 방식

uint8_t  dummy_data;
/*=========== GPIO Port F ===============*/
#define Lora_NCS_CLR        HAL_GPIO_WritePin(GPIOB,SX1276_NSS_Pin,RESET)
#define Lora_NCS_SET        HAL_GPIO_WritePin(GPIOB,SX1276_NSS_Pin,SET)

#define Lora_SCLK_CLR        HAL_GPIO_WritePin(GPIOB,SX1276_CLK_Pin,RESET)
#define Lora_SCLK_SET        HAL_GPIO_WritePin(GPIOB,SX1276_CLK_Pin,SET)
//
//#define Lora_MISO_CLR        HAL_GPIO_WritePin(GPIOB,SX1276_MISO_Pin,RESET)
//#define Lora_MISO_SET        HAL_GPIO_WritePin(GPIOB,SX1276_MISO_Pin,SET)

#define Lora_MOSI_CLR        HAL_GPIO_WritePin(GPIOB,SX1276_MOSI_Pin,RESET)
#define Lora_MOSI_SET        HAL_GPIO_WritePin(GPIOB,SX1276_MOSI_Pin,SET)

#define Lora_MISO_READ       HAL_GPIO_ReadPin(GPIOB,SX1276_MISO_Pin)


#define Read_SX1278_SDO()  Lora_MISO_READ
#define Set_SX1278_SDI()   Lora_MOSI_SET
#define Set_SX1278_SCK()   Lora_SCLK_SET
 
#define Clr_SX1278_SDI()   Lora_MOSI_CLR
#define Clr_SX1278_SCK()   Lora_SCLK_CLR

uint8_t SPIReadByte(uint8_t addr);
uint8_t SPIWriteByte(uint8_t addr, uint8_t data);
uint8_t SPIGPIOTxRx(uint8_t addr, uint8_t data);

void SPI_Delay(int ustime)
{
	volatile int i;
	volatile int k;
	for(i = 0; i < ustime; i++)
	{
		k++;
	}
}

#if 1 // PYJ.2019.04.02_BEGIN -- 
#ifdef STM32F1
void SpiInOut(uint8_t addr_write)
{
 
    uint8_t i;

    for (i = 0; i < 8; i++)
    {
        SPI_Delay(SDA_SETUP_TIME);

        Clr_SX1278_SCK();
        if (addr_write & 0x80)
        {
            Set_SX1278_SDI();
        }
        else
        {
            Clr_SX1278_SDI();
        }
        SPI_Delay(SDA_SETUP_TIME);

        Set_SX1278_SCK();
        addr_write = addr_write << 1;
        SPI_Delay(SDA_SETUP_TIME);
    }
    Clr_SX1278_SCK();
 
}
uint8_t SpiRead(void)
{
 
    uint8_t i = 0,Readdata = 0;
 
    for (i = 0; i < 8; i++)   
    {
        Readdata <<= 1;
        SPI_Delay(SDA_SETUP_TIME);
        Set_SX1278_SCK();
        if (Read_SX1278_SDO())
            Readdata |= 0x01;
        else
            Readdata &= 0xfe;
        SPI_Delay(SDA_SETUP_TIME);
        Clr_SX1278_SCK();
    }
    
    return Readdata;
}
#if 1 // PYJ.2019.04.02_BEGIN -- 
uint8_t SPIGPIOTxRx(uint8_t addr, uint8_t data){
    uint8_t readdata;
     Lora_NCS_CLR;
    SpiInOut(addr);
    SpiInOut(data);
    readdata = SpiRead(); 
     Lora_NCS_SET;
    return readdata;
}
#endif // PYJ.2019.04.02_END -- 

#endif


//#else
#if 0 // PYJ.2019.04.02_BEGIN -- 
void BLUECELL_SPI_Transmit(uint8_t data) // int 가 16Bit 일때
{
	int i;
	Lora_MOSI_SET; 
//	Lora_NCS_SET;

	Lora_SCLK_CLR;  // CLK Low
//	Lora_NCS_CLR;   // 
    
    SPI_Delay(CS_SETUP_TIME);
	for(i = 0; i < 8; i++)
	{
		Lora_SCLK_CLR;   // CLK LOW
		SPI_Delay(SDA_SETUP_TIME);
		if(data & 0x80) {
			Lora_MOSI_SET;
		}
		else {
			Lora_MOSI_CLR;
		}

		SPI_Delay(SDA_SETUP_TIME);
		data <<= 1 ;
		Lora_SCLK_SET;
		SPI_Delay(SDA_SETUP_TIME);
	}
//	Lora_NCS_SET;
//	Lora_MOSI_SET;
//	SPI_Delay(SDA_SETUP_TIME);
}
#else
void BLUECELL_SPI_Transmit(uint8_t data) {
    SpiInOut(data);
}

#endif // PYJ.2019.04.02_END -- 
#if 0 // PYJ.2019.04.01_BEGIN -- 

// MSB 방식
void SOUT(int data) // int 가 16Bit 일때
{
	int i;
	uint16_t mask = 0x8000;
	SET_SPI_MOSI; 
	SET_SPI_CS;

	CLR_SPI_SCL;  // CLK Low
	CLR_SPI_CS;   // 
 
    SPI_Delay(CS_SETUP_TIME);

	for(i = 0; i < 16; i++)
	{
		CLR_SPI_SCL;   // CLK LOW
		SPI_Delay(SCL_LOW_TIME);
		if(data & mask)) {
			SET_SPI_SDA;
		}
		else {
			CLR_SPI_SDA;
		}

		SPI_Delay(SDA_SETUP_TIME);
		mask >> =1;
		SET_SPI_SCL;
		SPI_Delay(SCL_HIGH_TIME);
	}
	SET_SPI_CS;
	SET_SPI_SDA;
	SPI_Delay(CS_PULSE_TIME);
}
#endif // PYJ.2019.04.01_END -- 




//소스 예제 2 Read 시는 Addr 의 취상위비트가 0, Write 시에는 취상위비트가 1


uint8_t SPIReadByte(uint8_t addr)
{
    /* Read Command */
    uint8_t readdata;
     Lora_NCS_CLR;
    SpiInOut(addr);
    readdata = SpiRead(); 
    Lora_NCS_SET;
    return readdata;
}

uint8_t SPIWriteByte(uint8_t addr, uint8_t data)
{
    /* Write Command */
    addr |= 0x80;
    dummy_data = SPIGPIOTxRx(addr, data);

    //return SPIGPIOTxRx(data);
    return dummy_data;
}

#if 0 // PYJ.2019.04.02_BEGIN -- 
uint8_t SPIGPIOTxRx(uint8_t addr, uint8_t data)
{
    uint8_t i;
    uint8_t rx;
    uint8_t mask;
    uint16_t wdata, wmask;
    
    rx         = 0;
    mask       = 0x80;
    wmask      = 0x8000;

    Lora_SCLK_CLR;
    Lora_NCS_CLR;
          
    if ( addr & 0x80 ) {

      wdata = (uint16_t)(addr << 8) | data;
      // write
      for ( i = 0 ; i < 16 ; i++ ) {

          if ( wdata & wmask ) Lora_MOSI_SET;
          else                 Lora_MOSI_CLR;
    
          Lora_SCLK_SET;

          if ( Lora_MISO_READ ) rx |= wmask;
          else              rx &= ~wmask;

          wmask <<= 1;

          Lora_SCLK_CLR;

      }      
    } 
      else {
        
      // read
      for ( i = 0 ; i < 8 ; i++ ) {
          Lora_SCLK_SET;
          SPI_Delay(SDA_SETUP_TIME);
          if ( addr & mask ) Lora_MOSI_SET;
          else               Lora_MOSI_CLR;
          SPI_Delay(SDA_SETUP_TIME);
          Lora_SCLK_CLR ;
          mask <<= 1;
      }
      Lora_NCS_SET;
       for ( i = 0 ; i < 8 ; i++ ){    
           Lora_SCLK_SET;
          if ( Lora_MISO_READ ) rx |= mask;
          else              rx &= ~mask;
          Lora_SCLK_CLR ;
       }
    }

    Lora_NCS_SET;
    Lora_SCLK_CLR;
    Lora_MOSI_CLR;

    return rx;
}
#endif // PYJ.2019.04.02_END -- 
#endif // PYJ.2019.04.02_END -- 

