Example #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;
}
Example #2
0
/******************************************************************************
 * @fn      HalUARTInitDMA
 *
 * @brief   Initialize the UART
 *
 * @param   none
 *
 * @return  none
 *****************************************************************************/
static void HalUARTInitDMA(void)
{
  halDMADesc_t *ch;
#if (HAL_UART_DMA == 1)
  PERCFG &= ~HAL_UART_PERCFG_BIT;    // Set UART0 I/O to Alt. 1 location on P0.
#else
  PERCFG |= HAL_UART_PERCFG_BIT;     // Set UART1 I/O to Alt. 2 location on P1.
#endif
  PxSEL  |= HAL_UART_Px_SEL;         // Enable Peripheral control of Rx/Tx on Px.     p0.2 P0.3 set peripheral   //i0 setting
  UxCSR = CSR_MODE;                  // Mode is UART Mode.
  UxUCR = UCR_FLUSH;                 // Flush it.

  P2DIR &= ~P2DIR_PRIPO;                                                                                        //ÓÅÏȼ¶
  P2DIR |= HAL_UART_PRIPO;

  if (DMA_PM)
  {
    // Setup GPIO for interrupts by falling edge on DMA_RDY_IN.
    PxIEN |= DMA_RDYIn_BIT;
    PICTL |= PICTL_BIT;

    HAL_UART_DMA_CLR_RDY_OUT();
    PxDIR |= DMA_RDYOut_BIT;
  }

#if !HAL_UART_TX_BY_ISR
  // Setup Tx by DMA.
  ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_TX );

  // Abort any pending DMA operations (in case of a soft reset).
  HAL_DMA_ABORT_CH( HAL_DMA_CH_TX );

  // The start address of the destination.
  HAL_DMA_SET_DEST( ch, DMA_UxDBUF );

  // Using the length field to determine how many bytes to transfer.
  HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN );

  // One byte is transferred each time.
  HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_BYTE );

  // The bytes are transferred 1-by-1 on Tx Complete trigger.
  HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE );
  HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_TX );

  // The source address is incremented by 1 byte after each transfer.
  HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_1 );

  // The destination address is constant - the Tx Data Buffer.
  HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_0 );

  // The DMA Tx done is serviced by ISR in order to maintain full thruput.
  HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_ENABLE );

  // Xfer all 8 bits of a byte xfer.
  HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS );

  // DMA has highest priority for memory access.
  HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH);
#endif

  // Setup Rx by DMA.
  ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_RX );

  // Abort any pending DMA operations (in case of a soft reset).
  HAL_DMA_ABORT_CH( HAL_DMA_CH_RX );

  // The start address of the source.
  HAL_DMA_SET_SOURCE( ch, DMA_UxDBUF );

  // Using the length field to determine how many bytes to transfer.
  HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN );

  /* The trick is to cfg DMA to xfer 2 bytes for every 1 byte of Rx.
   * The byte after the Rx Data Buffer is the Baud Cfg Register,
   * which always has a known value. So init Rx buffer to inverse of that
   * known value. DMA word xfer will flip the bytes, so every valid Rx byte
   * in the Rx buffer will be preceded by a DMA_PAD char equal to the
   * Baud Cfg Register value.
   */
  HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_WORD );

  // The bytes are transferred 1-by-1 on Rx Complete trigger.
  HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE_REPEATED );
  HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_RX );

  // The source address is constant - the Rx Data Buffer.
  HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_0 );

  // The destination address is incremented by 1 word after each transfer.
  HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_1 );
  HAL_DMA_SET_DEST( ch, dmaCfg.rxBuf );
  HAL_DMA_SET_LEN( ch, HAL_UART_DMA_RX_MAX );

  // The DMA is to be polled and shall not issue an IRQ upon completion.
  HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_DISABLE );

  // Xfer all 8 bits of a byte xfer.
  HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS );

  // DMA has highest priority for memory access.
  HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH);

  volatile uint8 dummy = *(volatile uint8 *)DMA_UxDBUF;  // Clear the DMA Rx trigger.
  HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_RX);
  HAL_DMA_ARM_CH(HAL_DMA_CH_RX);
  (void)memset(dmaCfg.rxBuf, (DMA_PAD ^ 0xFF), HAL_UART_DMA_RX_MAX * sizeof(uint16));
}
Example #3
0
/**************************************************************************************************
 * @fn          HalUARTInitSPI
 *
 * @brief       Initialize the SPI UART Transport.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 */
static void HalUARTInitSPI(void)
{
#if (HAL_UART_SPI == 1)
  PERCFG &= ~HAL_UART_PERCFG_BIT;    /* Set UART0 I/O to Alt. 1 location on P0 */
#else
  PERCFG |= HAL_UART_PERCFG_BIT;     /* Set UART1 I/O to Alt. 2 location on P1 */
#endif
#if defined HAL_SPI_MASTER
  PxSEL |= HAL_UART_Px_SEL_M;        /* SPI-Master peripheral select */
  UxCSR = 0;                         /* Mode is SPI-Master Mode */
  UxGCR =  15;                       /* Cfg for the max Rx/Tx baud of 2-MHz */
  UxBAUD = 255;
#elif !defined HAL_SPI_MASTER
  PxSEL |= HAL_UART_Px_SEL_S;        /* SPI-Slave peripheral select */
  UxCSR = CSR_SLAVE;                 /* Mode is SPI-Slave Mode */
#endif
  UxUCR = UCR_FLUSH;                 /* Flush it */
  UxGCR |= BV(5);                    /* Set bit order to MSB */

  P2DIR &= ~P2DIR_PRIPO;
  P2DIR |= HAL_UART_PRIPO;

  /* Setup GPIO for interrupts by falling edge on SPI_RDY_IN */
  PxIEN |= SPI_RDYIn_BIT;
  PICTL |= PICTL_BIT;

  SPI_CLR_RDY_OUT();
  PxDIR |= SPI_RDYOut_BIT;

  /* Setup Tx by DMA */
  halDMADesc_t *ch = HAL_DMA_GET_DESC1234( HAL_SPI_CH_TX );
  
  /* Abort any pending DMA operations (in case of a soft reset) */
  HAL_DMA_ABORT_CH( HAL_SPI_CH_TX );

  /* The start address of the destination */
  HAL_DMA_SET_DEST( ch, DMA_UxDBUF );

  /* Using the length field to determine how many bytes to transfer */
  HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN );

  /* One byte is transferred each time */
  HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_BYTE );

  /* The bytes are transferred 1-by-1 on Tx Complete trigger */
  HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE );
  HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_TX );

  /* The source address is incremented by 1 byte after each transfer */
  HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_1 );
  HAL_DMA_SET_SOURCE( ch, spiTxPkt );

  /* The destination address is constant - the Tx Data Buffer */
  HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_0 );

  /* The DMA Tx done is serviced by ISR */
  HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_ENABLE );

  /* Xfer all 8 bits of a byte xfer */
  HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS );

  /* DMA has highest priority for memory access */
  HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH );

  /* Setup Rx by DMA */
  ch = HAL_DMA_GET_DESC1234( HAL_SPI_CH_RX );
  
  /* Abort any pending DMA operations (in case of a soft reset) */
  HAL_DMA_ABORT_CH( HAL_SPI_CH_RX );

  /* The start address of the source */
  HAL_DMA_SET_SOURCE( ch, DMA_UxDBUF );

  /* Using the length field to determine how many bytes to transfer */
  HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN );

  /* The trick is to cfg DMA to xfer 2 bytes for every 1 byte of Rx.
   * The byte after the Rx Data Buffer is the Baud Cfg Register,
   * which always has a known value. So init Rx buffer to inverse of that
   * known value. DMA word xfer will flip the bytes, so every valid Rx byte
   * in the Rx buffer will be preceded by a DMA_PAD char equal to the
   * Baud Cfg Register value.
   */
  HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_WORD );

  /* The bytes are transferred 1-by-1 on Rx Complete trigger */
  HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE_REPEATED );
  HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_RX );

  /* The source address is constant - the Rx Data Buffer */
  HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_0 );

  /* The destination address is incremented by 1 word after each transfer */
  HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_1 );
  HAL_DMA_SET_DEST( ch, spiRxBuf );
  HAL_DMA_SET_LEN( ch, SPI_MAX_PKT_LEN );

  /* The DMA is to be polled and shall not issue an IRQ upon completion */
  HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_DISABLE );

  /* Xfer all 8 bits of a byte xfer */
  HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS );

  /* DMA has highest priority for memory access */
  HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH );

  volatile uint8 dummy = *(volatile uint8 *)DMA_UxDBUF;  /* Clear the DMA Rx trigger */
  HAL_DMA_CLEAR_IRQ(HAL_SPI_CH_RX);
  HAL_DMA_ARM_CH(HAL_SPI_CH_RX);
  (void)memset(spiRxBuf, (DMA_PAD ^ 0xFF), SPI_MAX_PKT_LEN * sizeof(uint16));
}
/**************************************************************************************************
 * @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)
{  
  if (spiTxLen != 0)
  {
    return 0;
  }
  
  if (len > SPI_MAX_DAT_LEN)
  {
    len = SPI_MAX_DAT_LEN;
  }

  spiTxLen = len;

#if defined HAL_SPI_MASTER

  spiRdyIsr = 0;
  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

  SPI_CLR_RDY_OUT();

  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");

  if ( SPI_RDY_IN() )
  {
    SPI_SET_RDY_OUT();
  }
  
  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;
}