Esempio n. 1
0
/**************************************************************************************************
 * @fn          spiParseRx
 *
 * @brief       Parse all available bytes from the spiRxBuf[]; parse Rx data into the spiRxDat[].
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 */
static void spiParseRx(void)
{
  uint8 done = 0;
  halIntState_t  cs;
  
#ifdef HAL_SPI_MASTER
  uint8 numNotSOF = 0;
  uint8 count = 0;

  SPI_SET_CSn_OUT();
#endif //HAL_SPI_MASTER
  
  while (!done)
  {
    if (!SPI_NEW_RX_BYTE(spiRxIdx))
    {
#if defined HAL_SPI_MASTER
      // Clock a byte from slave
      SPI_CLOCK_RX(1);
#else
      break;
#endif
    }

    uint8 ch = SPI_GET_RX_BYTE(spiRxIdx);
    SPI_CLR_RX_BYTE(spiRxIdx);
    SPI_LEN_T_INCR(spiRxIdx);
    
#ifdef HAL_SPI_MASTER
    // If searching for a SOF byte limit the number of bytes searched
    // to SPI_FRM_LEN
    if ( spiRxPktState == SPIRX_STATE_SOF )
    {
      count++;
      numNotSOF = ( ch == SPI_SOF ) ? numNotSOF : numNotSOF + 1;
      
      // Haven't recieved an SOF. Assume not a packet but only break if there is
      // no new bytes in the RX buffer to read
      if ( numNotSOF > SPI_FRM_LEN && numNotSOF == count ) 
      {
        // Clear all Rx'ed NULL bytes
        while(SPI_NEW_RX_BYTE(spiRxIdx))
        {
          SPI_CLR_RX_BYTE(spiRxIdx);
          SPI_LEN_T_INCR(spiRxIdx);
        }
        break;
      }
    }
#endif //HAL_SPI_MASTER
    
    switch (spiRxPktState)
    {
    case SPIRX_STATE_SOF:
      if (ch == SPI_SOF)
      {
        spiRxPktState = SPIRX_STATE_LEN;

        /* At this point, the master has effected the protocol for ensuring that the SPI slave is
         * awake, so set the spiRxLen to non-zero to prevent the slave from re-entering sleep until
         * the entire packet is received - even if the master interrupts the sending of the packet
         * by de-asserting/re-asserting MRDY one or more times
	 */
        spiRxLen = 1;
      }
      break;

    case SPIRX_STATE_LEN:
      if ((ch == 0) || (ch > SPI_MAX_DAT_LEN))
      {
        spiRxPktState = SPIRX_STATE_SOF;
        spiRxLen = 0;
      }
      else
      {
        spiRxFcs = spiRxLen = ch;
        spiRxTemp = spiRxTail;
        spiRxCnt = 0;
        spiRxPktState = SPIRX_STATE_DATA;
#if defined HAL_SPI_MASTER
        if (!SPI_NEW_RX_BYTE(spiRxIdx)) /* Fix for simultaneous TX/RX to avoid extra clock pulses to SPI Slave */
        {
          halIntState_t intState;      
          HAL_ENTER_CRITICAL_SECTION(intState);
          SPI_CLOCK_RX(ch + 1); /* Clock out the SPI Frame Data bytes and FCS */
          HAL_EXIT_CRITICAL_SECTION(intState);
        }
#endif
      }
      break;

    case SPIRX_STATE_DATA:
      spiRxFcs ^= ch;
      spiRxDat[spiRxTemp] = ch;

      SPI_LEN_T_INCR(spiRxTemp);

      if (++spiRxCnt == spiRxLen)
      {
        spiRxPktState = SPIRX_STATE_FCS;
      }
      break;

    case SPIRX_STATE_FCS:
      spiRxPktState = SPIRX_STATE_SOF;
#ifdef POWER_SAVING
      pktFound = TRUE;
#endif

      if (ch == spiRxFcs)
      {
        spiRxTail = spiRxTemp;
      }
      else
      {
        dbgFcsByte = ch;
#ifdef RBA_UART_TO_SPI
        badFcsPktCount++;
#endif
      }
      spiRxCnt = spiRxLen = 0;

#ifdef HAL_SPI_MASTER
      // Clear any trailing empty Rx'ed bytes
      // Should only receive one frame per MRDY assertion
      while(SPI_NEW_RX_BYTE(spiRxIdx))
      {
        SPI_CLR_RX_BYTE(spiRxIdx);
        SPI_LEN_T_INCR(spiRxIdx);
      }
      done = 1;
#endif //HAL_SPI_MASTER
      
      break;

    default:
      HAL_ASSERT(0);
      break;
    }
  }
  spiTxLen = 0;
  
  HAL_ENTER_CRITICAL_SECTION(cs);
  spiRdyIsr = 0;
  HAL_EXIT_CRITICAL_SECTION(cs);

#ifdef HAL_SPI_MASTER
  SPI_CLR_CSn_OUT();
  
#ifdef RBA_UART_TO_SPI
  // Must wait until slave has ended transaction because
  // the RBA implementation cannot delay writes so this is a 
  // forced delay....
  while(SPI_RDY_IN());
#endif
#else
  SPI_CLR_RDY_OUT();
#endif //HAL_SPI_MASTER
  
}
Esempio n. 2
0
/**************************************************************************************************
 * @fn          spiParseRx
 *
 * @brief       Parse all available bytes from the spiRxBuf[]; parse Rx data into the spiRxDat[].
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 */
static void spiParseRx(void)
{
  while (1)
  {
    if (!SPI_NEW_RX_BYTE(spiRxIdx))
    {
#if defined HAL_SPI_MASTER
      if (SPI_RDY_IN() && (spiTxLen == 0))
      {
        SPI_CLOCK_RX(1);
        continue;
      }
#endif
      break;
    }

    uint8 ch = SPI_GET_RX_BYTE(spiRxIdx);
    SPI_CLR_RX_BYTE(spiRxIdx);
    SPI_LEN_T_INCR(spiRxIdx);

    switch (spiRxPktState)
    {
    case SPIRX_STATE_SOF:
      if (ch == SPI_SOF)
      {
        spiRxPktState = SPIRX_STATE_LEN;

        /* At this point, the master has effected the protocol for ensuring that the SPI slave is
         * awake, so set the spiRxLen to non-zero to prevent the slave from re-entering sleep until
         * the entire packet is received - even if the master interrupts the sending of the packet
         * by de-asserting/re-asserting MRDY one or more times
	 */
        spiRxLen = 1;
      }
      break;

    case SPIRX_STATE_LEN:
      if ((ch == 0) || (ch > SPI_MAX_DAT_LEN))
      {
        spiRxPktState = SPIRX_STATE_SOF;
        spiRxLen = 0;
      }
      else
      {
        spiRxFcs = spiRxLen = ch;
        spiRxTemp = spiRxTail;
        spiRxCnt = 0;
        spiRxPktState = SPIRX_STATE_DATA;
#if defined HAL_SPI_MASTER
        if (!SPI_NEW_RX_BYTE(spiRxIdx)) /* Fix for simultaneous TX/RX to avoid extra clock pulses to SPI Slave */
        {
          halIntState_t intState;      
          HAL_ENTER_CRITICAL_SECTION(intState);
          SPI_CLOCK_RX(ch + 1); /* Clock out the SPI Frame Data bytes and FCS */
          HAL_EXIT_CRITICAL_SECTION(intState);
        }
#endif
      }
      break;

    case SPIRX_STATE_DATA:
      spiRxFcs ^= ch;
      spiRxDat[spiRxTemp] = ch;

      SPI_LEN_T_INCR(spiRxTemp);

      if (++spiRxCnt == spiRxLen)
      {
        spiRxPktState = SPIRX_STATE_FCS;
      }
      break;

    case SPIRX_STATE_FCS:
      spiRxPktState = SPIRX_STATE_SOF;
#ifdef POWER_SAVING
      pktFound = TRUE;
#endif
      SPI_CLR_RDY_OUT(); /* SPI_RDYOut = 1 */

      if (ch == spiRxFcs)
      {
        spiRxTail = spiRxTemp;
      }
      else
      {
        dbgFcsByte = ch;
#ifdef RBA_UART_TO_SPI
        badFcsPktCount++;
#endif
      }
      spiRxCnt = spiRxLen = 0;
      break;

    default:
      HAL_ASSERT(0);
      break;
    }
  }
}
Esempio n. 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

#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
}
Esempio n. 4
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;

}