/**
* @brief  Write data into TX FIFO
* @param  cNbBytes: number of bytes to be written into TX FIFO
* @param  pcBuffer: pointer to data to write
* @retval SPIRIT status
*/
SpiritStatus SpiritSpiWriteLinearFifo(uint8_t cNbBytes, uint8_t* pcBuffer)
{
  uint16_t tmpstatus = 0x0000;
  uint8_t header[2];
  int i, index;
  SpiritStatus *status=(SpiritStatus *)&tmpstatus;
  
  
  /* Built the header bytes */
  header[0]=WRITE_HEADER;
  header[1]=LINEAR_FIFO_ADDRESS;
  
  SPI_ENTER_CRITICAL();
  
  /* Put the SPI chip select low to start the transaction */
  SpiritSPICSLow();
  
  {
    volatile uint16_t iv;
    for(iv=0; iv < CS_TO_SCLK_DELAY; iv++);
  }
  
  /* Write the header bytes and read the SPIRIT status bytes */
  for(i=0; i<2; i++)
  {
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
    SPI_SendData(SPIRIT_SPI_PERIPH_NB, header[i]);
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_RXNE) == RESET);
    tmpstatus += ((uint16_t)(SPI_ReceiveData(SPIRIT_SPI_PERIPH_NB)))<<((1-i)*8);
  }
  
  /* Write the data into the FIFO according to the number of bytes */
  for(index=0; index<cNbBytes; index++)
  {
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
    SPI_SendData(SPIRIT_SPI_PERIPH_NB, pcBuffer[index]);
  }
  
  /* To be sure to don't rise the Chip Select before the end of last sending */
  while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
  
  if(SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_RXNE) == SET)
  {
    SPI_ReceiveData(SPIRIT_SPI_PERIPH_NB);
  }
  
  /* Put the SPI chip select high to end the transaction */
  SpiritSPICSHigh();
  
  SPI_EXIT_CRITICAL();
  
  return *status;
  
}
/**
* @brief  Read single or multiple SPIRIT register
* @param  cRegAddress: base register's address to be read
* @param  cNbBytes: number of registers and bytes to be read
* @param  pcBuffer: pointer to the buffer of registers' values read
* @retval SPIRIT status
*/
SpiritStatus
SpiritSpiReadRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer)
{
  uint16_t tmpstatus = 0x0000;
  uint8_t header[2];
  uint8_t dummy=0xFF;
  int i, index;
  SpiritStatus *status=(SpiritStatus *)&tmpstatus;
  
  /* Built the header bytes */
  header[0]=READ_HEADER;
  header[1]=cRegAddress;
  
  SPI_ENTER_CRITICAL();
  
  /* Put the SPI chip select low to start the transaction */
  SpiritSPICSLow();
  
  {
    volatile uint16_t iv;
    for(iv = 0; iv < CS_TO_SCLK_DELAY; iv++);
  }

  /* Write the header bytes and read the SPIRIT status bytes */
  for(i=0; i<2; i++)
  {
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
    SPI_SendData(SPIRIT_SPI_PERIPH_NB, header[i]);
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_RXNE) == RESET);
    tmpstatus += ((uint16_t)(SPI_ReceiveData(SPIRIT_SPI_PERIPH_NB)))<<((1-i)*8);
  }
  
  /* Read the registers according to the number of bytes */
  for(index=0; index<cNbBytes; index++)
  {
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
    SPI_SendData(SPIRIT_SPI_PERIPH_NB, dummy);
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_RXNE) == RESET);
    *pcBuffer = SPI_ReceiveData(SPIRIT_SPI_PERIPH_NB);
    pcBuffer++;
  }
  
  while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
  
  /* Put the SPI chip select high to end the transaction */
  SpiritSPICSHigh();
  
  SPI_EXIT_CRITICAL();
  
  return *status;
  
}
/* XXX mlu: what does this work around? legacy function. */
void SpiritWorkaroundRx(void)
{
  uint8_t header;
  volatile uint8_t i;
  
  /* Built the header bytes */
  header=WRITE_HEADER;
  
  /* Put the SPI chip select low to start the transaction */
  SpiritSPICSLow();
  for(i = 0; i < 0x1; i++);
  SPI_SendData(SPIRIT_SPI_PERIPH_NB, header);
  header=0xA8;
  //  for(volatile uint8_t i=0;i<0x1;i++);
  SPI_SendData(SPIRIT_SPI_PERIPH_NB, header);
  for(i = 0; i < 0x1; i++);
  header = 0x10;
  SPI_SendData(SPIRIT_SPI_PERIPH_NB, header);
  for(i = 0; i < 0x1; i++);

  /* Put the SPI chip select high to end the transaction */
  SpiritSPICSHigh();
  for(i = 0; i < 0x1; i++);
  
  /* Put the SPI chip select low to start the transaction */
  SpiritSPICSLow();
  for(i = 0; i < 0x1; i++);
  SPI_SendData(SPIRIT_SPI_PERIPH_NB, header);
  header=0xA8;
  //  for(volatile uint8_t i=0;i<0x1;i++);
  SPI_SendData(SPIRIT_SPI_PERIPH_NB, header);
  for(i = 0; i < 0x1; i++);
  header = 0x00;
  SPI_SendData(SPIRIT_SPI_PERIPH_NB, header);
  for(i = 0; i < 0x1; i++);

  /* Put the SPI chip select high to end the transaction */
  SpiritSPICSHigh();
}
/**
* @brief  Read data from RX FIFO
* @param  cNbBytes: number of bytes to read from RX FIFO
* @param  pcBuffer: pointer to data read from RX FIFO
* @retval SPIRIT status
*/
StatusBytes SdkEvalSpiReadFifo(uint8_t cNbBytes, uint8_t* pcBuffer)
{
  uint16_t tmpstatus = 0x0000;
  StatusBytes *status=(StatusBytes *)&tmpstatus;
  
  SPI_ENTER_CRITICAL();
  
  uint8_t header[2];
  uint8_t dummy=0xFF;
  
  /* Built the header bytes */
  header[0]=READ_HEADER;
  header[1]=LINEAR_FIFO_ADDRESS;
  
  /* Put the SPI chip select low to start the transaction */
  SpiritSPICSLow();
  
  for(volatile uint16_t i=0;i<CS_TO_SCLK_DELAY;i++);
  
  /* Write the header bytes and read the SPIRIT status bytes */
  for(int i=0; i<2; i++)
  {
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
    SPI_SendData(SPIRIT_SPI_PERIPH_NB, header[i]);
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_RXNE) == RESET);
    tmpstatus += ((uint16_t)(SPI_ReceiveData(SPIRIT_SPI_PERIPH_NB)))<<(i*8);
  }
  
  /* Read the data from the FIFO according to the number of bytes */
  for(int index=0; index<cNbBytes; index++)
  {
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
    SPI_SendData(SPIRIT_SPI_PERIPH_NB, dummy);
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_RXNE) == RESET);
    *pcBuffer = SPI_ReceiveData(SPIRIT_SPI_PERIPH_NB);
    pcBuffer++;
  }
  
  /* To be sure to don't rise the Chip Select before the end of last sending */
  while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
  
  /* Put the SPI chip select high to end the transaction */
  SpiritSPICSHigh();
  
  SPI_EXIT_CRITICAL();
  
  return *status;
  
}
/**
* @brief  Write single or multiple SPIRIT register
* @param  cRegAddress: base register's address to be write
* @param  cNbBytes: number of registers and bytes to be write
* @param  pcBuffer: pointer to the buffer of values have to be written into registers
* @retval SPIRIT status
*/
StatusBytes SdkEvalSpiWriteRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer)
{
  uint8_t header[2];
  uint16_t tmpstatus = 0x0000;
  StatusBytes *status=(StatusBytes *)&tmpstatus;
  
  /* Built the header bytes */
  header[0]=WRITE_HEADER;
  header[1]=cRegAddress;
  
  SPI_ENTER_CRITICAL();
  
  /* Puts the SPI chip select low to start the transaction */
  SpiritSPICSLow();
  
  for(volatile uint16_t i=0;i<CS_TO_SCLK_DELAY;i++);
  
  /* Writes the header bytes and read the SPIRIT status bytes */
  for(int i=0; i<2; i++)
  {
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
    SPI_SendData(SPIRIT_SPI_PERIPH_NB, header[i]);
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_RXNE) == RESET);
    tmpstatus += ((uint16_t)(SPI_ReceiveData(SPIRIT_SPI_PERIPH_NB)))<<(i*8);
  }
  
  /* Writes the registers according to the number of bytes */
  for(int index=0; index<cNbBytes; index++)
  {
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
    SPI_SendData(SPIRIT_SPI_PERIPH_NB, pcBuffer[index]);   
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_RXNE) == RESET);
    SPI_ReceiveData(SPIRIT_SPI_PERIPH_NB);
  }
  
  /* Puts the SPI chip select high to end the transaction */
  SpiritSPICSHigh();
  
  /* To be sure to don't rise the Chip Select before the end of last sending */
  while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
  
  SPI_EXIT_CRITICAL();
  
  return *status;
  
}
/**
* @brief  Send a command
* @param  cCommandCode: command code to be sent
* @retval SPIRIT status
*/
SpiritStatus SpiritSpiCommandStrobes(uint8_t cCommandCode)
{
  uint8_t header[2];
  uint16_t tmpstatus = 0x0000;
  SpiritStatus *status=(SpiritStatus *)&tmpstatus;
  int i;
  
  /* Built the header bytes */
  header[0]=COMMAND_HEADER;
  header[1]=cCommandCode;
  
  SPI_ENTER_CRITICAL();
  
  /* Puts the SPI chip select low to start the transaction */
  SpiritSPICSLow();
  {
    volatile uint16_t iv;
    for(iv = 0; iv < CS_TO_SCLK_DELAY; iv++);
  }
  
  /* Writes the header bytes and read the SPIRIT status bytes */
  for(i=0; i<2; i++)
  {
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
    SPI_SendData(SPIRIT_SPI_PERIPH_NB, header[i]);
    while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_RXNE) == RESET);
    tmpstatus += ((uint16_t)(SPI_ReceiveData(SPIRIT_SPI_PERIPH_NB)))<<((1-i)*8);
  }
  
  while (SPI_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_FLAG_TXE) == RESET);
  
  /* Puts the SPI chip select high to end the transaction */
  SpiritSPICSHigh();
  
  SPI_EXIT_CRITICAL();
  
  return *status;
  
}