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          sblInit
 *
 * @brief       Initialization for SBL.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
static void sblInit(void)
{
  HAL_BOARD_INIT();
  vddWait(VDD_MIN_RUN);
  magicByte = SB_MAGIC_VALUE;

  /* This is in place of calling HalDmaInit() which would require init of the other 4 DMA
   * descriptors in addition to just Channel 0.
   */
  HAL_DMA_SET_ADDR_DESC0(&dmaCh0);

#if defined CC2530_MK
  znpCfg1 = ZNP_CFG1_SPI;
#else
  znpCfg1 = P2_0;
#endif
  if (znpCfg1 == ZNP_CFG1_SPI)
  {
    SRDY_CLR();

    // Select general purpose on I/O pins.
    P0SEL &= ~(NP_RDYIn_BIT);      // P0.3 MRDY - GPIO
    P0SEL &= ~(NP_RDYOut_BIT);     // P0.4 SRDY - GPIO

    // Select GPIO direction.
    P0DIR &= ~NP_RDYIn_BIT;        // P0.3 MRDY - IN
    P0DIR |= NP_RDYOut_BIT;        // P0.4 SRDY - OUT

    P0INP &= ~NP_RDYIn_BIT;        // Pullup/down enable of MRDY input.
    P2INP &= ~BV(5);               // Pullup all P0 inputs.

    HalUARTInitSPI();
  }
  else
  {
    halUARTCfg_t uartConfig;

    HalUARTInitISR();
    uartConfig.configured           = TRUE;
    uartConfig.baudRate             = HAL_UART_BR_115200;
    uartConfig.flowControl          = FALSE;
    uartConfig.flowControlThreshold = 0;  // CC2530 by #define - see hal_board_cfg.h
    uartConfig.rx.maxBufSize        = 0;  // CC2530 by #define - see hal_board_cfg.h
    uartConfig.tx.maxBufSize        = 0;  // CC2530 by #define - see hal_board_cfg.h
    uartConfig.idleTimeout          = 0;  // CC2530 by #define - see hal_board_cfg.h
    uartConfig.intEnable            = TRUE;
    uartConfig.callBackFunc         = NULL;
    HalUARTOpenISR(&uartConfig);
  }
}
Example #4
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;
}