Example #1
0
/*****************************************************************************
 * @fn      HalUARTReadSPI
 *
 * @brief   Execute a blocking read from master if Rx buffer is empty. Otherwise return up to 'len'
 *          bytes of read data.
 *
 * @param   buf  - valid data buffer at least 'len' bytes in size
 *          len  - max length number of bytes to copy to 'buf'
 *
 * @return  length of buffer that was read
 *****************************************************************************/
uint16 HalUARTReadSPI(uint8 *buf, uint16 len)
{
  uint16 cnt = 0;

  if ((spiCfg.rxHead == 0) && (spiCfg.rxHead == spiCfg.rxTail))
  {
    uint8 tmp;

    UxDBUF = 0;
    URXxIF = 0;
    // Slave signals ready for read by setting its ready flag first.
    SRDY_SET();
    while (!MRDY_SET);

    do {
      while (!URXxIF && MRDY_SET);
      tmp = UxDBUF;
      URXxIF = 0;

      // Master ends slave read by clearing its ready flag first.
      if (!MRDY_SET)
      {
        break;
      }

      spiCfg.rxBuf[spiCfg.rxTail] = tmp;
      if (++spiCfg.rxTail >= HAL_UART_SPI_RX_MAX)
      {
        spiCfg.rxTail = 0;
      }
    } while(1);

    // Master blocks waiting for slave to clear its ready flag before continuing.
    SRDY_CLR();
  }

  while ((spiCfg.rxHead != spiCfg.rxTail) && (cnt < len))
  {
    *buf++ = spiCfg.rxBuf[spiCfg.rxHead++];
    if (spiCfg.rxHead >= HAL_UART_SPI_RX_MAX)
    {
      spiCfg.rxHead = 0;
    }
    cnt++;
  }

  if (cnt == 0)
  {
    spiCfg.rxHead = spiCfg.rxTail = 0;
  }

  return cnt;
}
Example #2
0
/******************************************************************************
 * @fn      HalUARTWriteSPI
 *
 * @brief   Write a buffer to the UART.
 * @brief   Execute a blocking write to the master.
 *
 * @param   buf - pointer to the buffer that will be written, not freed
 *          len - length of
 *
 * @return  length of the buffer that was sent
 *****************************************************************************/
uint16 HalUARTWriteSPI(uint8 *buf, uint16 len)
{
  uint16 cnt;

  // Enforce all or none and at least one.
  if ((HAL_UART_SPI_TX_AVAIL() < len) || (len == 0))
  {
    return 0;
  }

  UxDBUF = *buf++;
  for (cnt = 1; cnt < len; cnt++)
  {
    spiCfg.txBuf[spiCfg.txTail] = *buf++;

    if (spiCfg.txTail >= HAL_UART_SPI_TX_MAX-1)
    {
      spiCfg.txTail = 0;
    }
    else
    {
      spiCfg.txTail++;
    }
  }

  URXxIF = 0;
  // Master signals ready for slave write by setting its ready flag first.
  while (!MRDY_SET);
  // Master blocks waiting for slave to set its ready flag before continuing.
  SRDY_SET();

  do {
    while (!URXxIF && MRDY_SET);
    UxDBUF = spiCfg.txBuf[spiCfg.txHead];
    URXxIF = 0;

    if (spiCfg.txHead == spiCfg.txTail)
    {
      spiCfg.txBuf[spiCfg.txHead] = 0;
    }
    else if (++spiCfg.txHead >= HAL_UART_SPI_TX_MAX)
    {
      spiCfg.txHead = 0;
    }
  } while(MRDY_SET);  // Master ends slave write by clearing its ready flag first.

  // Master blocks waiting for slave to set its ready flag before continuing.
  SRDY_CLR();

  return cnt;
}
Example #3
0
/**************************************************************************************************
 * @fn          sblWait
 *
 * @brief       A timed-out wait loop that exits early upon receiving a force code/sbl byte.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      TRUE to run the code image, FALSE to run the SBL.
 **************************************************************************************************
 */
static uint8 sblWait(uint16 sbl_wait_time)
{
  uint32 dlyCnt;
  uint8 rtrn = FALSE;
  uint8 sbExec_rc;
  uint8 ch;

  if (znpCfg1 == ZNP_CFG1_SPI)
  {
    // Slave signals ready for read by setting its ready flag first.
    SRDY_SET();
    // Flag to sbRx() to poll for 1 Rx byte instead of blocking read until MRDY_CLR.
    spiPoll = TRUE;
    dlyCnt = 0x38;  // About 50 msecs.
  }
  else
  {
    URX0IE = 1;
    HAL_ENABLE_INTERRUPTS();
    dlyCnt = (uint32)0x7332 * sbl_wait_time; //0x7332 gives about 1 second

    sbReportState(SB_STATE_WAITING);
  }

  while (1)
  {
    if (znpCfg1 == ZNP_CFG1_UART)
    {
      sbUartPoll();

      sbExec_rc = sbExec();
      if (sbExec_rc == SB_CMND_ENABLE_STATE_REPORTING)
      {
        sbReportState(SB_STATE_WAITING);
      }
      else if (sbExec_rc == SB_CMND_FORCE_RUN)
      {
        dlyCnt = 0;
      }
      else if ((sbExec_rc != SB_CMND_IDLE) && (sbExec_rc != SB_CMND_UNSUPPORTED))
      {
        break;
      }
    }
    else // Note: the SPI implementation was left unchanged, since the new implementation
         // (as implemented for the UART) was not tested with SPI at this time.
    {
      if (sbRx(&ch, 1))
      {
        if (ch == SB_FORCE_BOOT)
        {
          break;
        }
        else if (ch == SB_FORCE_RUN)
        {
          dlyCnt = 0;
        }
      }
    }

    if (dlyCnt-- == 0)
    {
      rtrn = TRUE;
      break;
    }
  }

  if (znpCfg1 == ZNP_CFG1_SPI)
  {
    // Master blocks waiting for slave to clear its ready flag before continuing.
    SRDY_CLR();
    // Flag to sbRx() to now block while reading Rx bytes until MRDY_CLR.
    spiPoll = FALSE;
  }
  else
  {
    HAL_DISABLE_INTERRUPTS();
    URX0IE = 0;
  }

  return rtrn;
}