示例#1
0
/**************************************************************************************************
 * @fn          HalUARTWriteSPI
 *
 * @brief       Transmit data bytes as a SPI packet.
 *
 * input parameters
 *
 * @param       buf - pointer to the memory of the data bytes to send.
 * @param       len - the length of the data bytes to send.
 *
 * output parameters
 *
 * None.
 *
 * @return      Zero for any error; otherwise, 'len'.
 */
static spiLen_t HalUARTWriteSPI(uint8 *buf, spiLen_t len)
{  
  // Already in Tx or Rx transaction
#ifdef RBA_UART_TO_SPI
  // The RBA Bridge is not written to handle re-writes so we must 
  // just let it write
  if (spiTxLen != 0)
#else //!RBA_UART_TO_SPI
  if (spiTxLen != 0 || SPI_RDY_OUT())
#endif
  {
    return 0;
  }
  
  if (len > SPI_MAX_DAT_LEN)
  {
    len = SPI_MAX_DAT_LEN;
  }
        
  spiTxLen = len;
  writeActive = 1;

#if defined HAL_SPI_MASTER
  
  spiTxPkt[SPI_LEN_IDX] = len;
  (void)memcpy(spiTxPkt + SPI_DAT_IDX, buf, len);
  
  spiCalcFcs(spiTxPkt);
  spiTxPkt[SPI_SOF_IDX] = SPI_SOF;
  
  halDMADesc_t *ch = HAL_DMA_GET_DESC1234(HAL_SPI_CH_TX);
  HAL_DMA_SET_LEN(ch, SPI_PKT_LEN(spiTxPkt)); /* DMA TX might need padding */
 
  /* Abort any pending DMA operations */
  HAL_DMA_ABORT_CH( HAL_SPI_CH_RX );
  spiRxIdx = 0;
  (void)memset(spiRxBuf, (DMA_PAD ^ 0xFF), SPI_MAX_PKT_LEN * sizeof(uint16));

  HAL_DMA_ARM_CH(HAL_SPI_CH_RX);
  
  asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");
  asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");

  /* Abort any pending DMA operations */
  HAL_DMA_ABORT_CH( HAL_SPI_CH_TX );
  HAL_DMA_ARM_CH(HAL_SPI_CH_TX);

  asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");
  asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");

  SPI_SET_CSn_OUT();

  while((!SPI_RDY_IN()) && (!spiRdyIsr) );

  HAL_DMA_MAN_TRIGGER(HAL_SPI_CH_TX);

#elif !defined HAL_SPI_MASTER

#ifdef POWER_SAVING
  /* Disable POWER SAVING when transmission is initiated */
  CLEAR_SLEEP_MODE();
#endif

  HAL_DMA_ARM_CH(HAL_SPI_CH_RX);

  asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");
  asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");
  
  spiTxPkt[SPI_LEN_IDX] = len;
  (void)memcpy(spiTxPkt + SPI_DAT_IDX, buf, len);

  spiCalcFcs(spiTxPkt);
  spiTxPkt[SPI_SOF_IDX] = SPI_SOF;

  halDMADesc_t *ch = HAL_DMA_GET_DESC1234(HAL_SPI_CH_TX);
  HAL_DMA_SET_LEN(ch, SPI_PKT_LEN(spiTxPkt) + 1); /* slave DMA TX might drop the last byte */
  HAL_DMA_ARM_CH(HAL_SPI_CH_TX);
  
  asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");
  asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");

  SPI_SET_RDY_OUT();

#endif
  return len;
}
示例#2
0
/**************************************************************************************************
 * @fn          HalUARTPollSPI
 *
 * @brief       SPI Transport Polling Manager.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 */
static void HalUARTPollSPI(void)
{
#ifdef HAL_SPI_MASTER
#else
#if defined POWER_SAVING  
  pktFound = FALSE;
#endif
  if ( ( spiRdyIsr ) || (SPI_RDY_IN()) )
  {
    CLEAR_SLEEP_MODE();

#if defined HAL_SBL_BOOT_CODE
    if(!spiTxLen)
    {   
      UxDBUF = 0x00; /* Zero out garbage from UxDBUF */
      
      HAL_DMA_ARM_CH(HAL_SPI_CH_RX); /* Arm RX DMA */

      asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); 
      asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); 
      asm("NOP");

      halIntState_t intState;      
      HAL_ENTER_CRITICAL_SECTION(intState);
      
      SPI_SET_RDY_OUT(); /* SPI_RDYOut = 0 */
      SPI_CLR_RDY_OUT(); /* SPI_RDYOut = 1 */

      HAL_EXIT_CRITICAL_SECTION(intState);
    }
#endif
#if defined POWER_SAVING      
    pktFound = TRUE;
#endif
  }
#endif

#ifdef HAL_SPI_MASTER
  if ( spiRdyIsr && !writeActive) 
  {
    spiParseRx();
  }
#else //SPI Slave
  if ( spiRdyIsr && !writeActive )
  {
     if ( !(UxCSR & CSR_ACTIVE) )
     {
       // MRDY has gone low to set spiRdyIsr
       // and has now gone high if SPI_RDY_IN
       // is false, read RXed bytes
       spiParseRx();
     }
     else
     {
       // MRDY has gone low and is still low
       // Set SRDY low to signal ready to RX
       SPI_SET_RDY_OUT();
     }
  }
#endif //HAL_SPI_MASTER

#if defined HAL_SPI_MASTER
  if( SPI_RX_RDY())
#else
  if (SPI_RX_RDY() && !spiTxLen)
#endif
  {
    if (spiCB != NULL)
    {
      spiCB((HAL_UART_SPI - 1), HAL_UART_RX_TIMEOUT);
    }
  }

#if defined POWER_SAVING
  if  ( SPI_RDY_IN()|| SPI_RX_RDY() || spiRxLen || spiTxLen || spiRdyIsr ||  pktFound || SPI_RDY_OUT() )
  {
    CLEAR_SLEEP_MODE();
  }
  else if ( (!pktFound) && (!SPI_NEW_RX_BYTE(spiRxIdx)) )
  {
    PxIEN |= SPI_RDYIn_BIT; 
    SPI_CLR_RDY_OUT();
  }
#endif
}
示例#3
0
/**************************************************************************************************
 * @fn          HalUARTPollSPI
 *
 * @brief       SPI Transport Polling Manager.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 */
static void HalUARTPollSPI(void)
{
#ifdef HAL_SPI_MASTER
#else
#if defined POWER_SAVING  
  pktFound = FALSE;
#endif
  if ( ( spiRdyIsr ) || (SPI_RDY_IN()) )
  {
    CLEAR_SLEEP_MODE();

#if defined HAL_SBL_BOOT_CODE
    if(!spiTxLen)
    {   
      UxDBUF = 0x00; /* Zero out garbage from UxDBUF */
      
      HAL_DMA_ARM_CH(HAL_SPI_CH_RX); /* Arm RX DMA */

      asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); 
      asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); 
      asm("NOP");

      halIntState_t intState;      
      HAL_ENTER_CRITICAL_SECTION(intState);
      
      SPI_SET_RDY_OUT(); /* SPI_RDYOut = 0 */
      SPI_CLR_RDY_OUT(); /* SPI_RDYOut = 1 */

      HAL_EXIT_CRITICAL_SECTION(intState);
    }
#endif
#if defined POWER_SAVING      
    pktFound = TRUE;
#endif
  }
#endif

#if defined HAL_SPI_MASTER  
  if (!spiTxLen) 
#else
  if ((!spiTxLen) && (!SPI_RDY_IN()))
#endif
  {
    SPI_CLR_RDY_OUT(); /* SPI_RDYOut = 1; */
    spiParseRx();
  }

#if defined HAL_SPI_MASTER
  if( SPI_RX_RDY())
#else
  if (SPI_RX_RDY() && !spiTxLen)
#endif
  {
    if (spiCB != NULL)
    {
      spiCB((HAL_UART_SPI - 1), HAL_UART_RX_TIMEOUT);
    }
  }

  if (!spiTxLen)
  {
    if ( SPI_RDY_OUT () )
    {
      SPI_CLR_RDY_OUT();  /* Clear the ready-out signal */
    }
  }

#if defined POWER_SAVING
  if  ( SPI_RDY_IN()|| SPI_RX_RDY() || spiRxLen || spiTxLen || spiRdyIsr ||  pktFound || SPI_RDY_OUT() )
  {
    CLEAR_SLEEP_MODE();
  }
  else if ( (!pktFound) && (!SPI_NEW_RX_BYTE(spiRxIdx)) )
  {
    PxIEN |= SPI_RDYIn_BIT; 
    SPI_CLR_RDY_OUT();
  }
#endif
  spiRdyIsr = 0;

}