Platform/ECM3532/M3/hw/csp/ecm3532/m3/csp/src/eta_csp_spi.c
/***************************************************************************/
/**
 *
 * EtaCspSpiInit - Initialize the SPI module. Ensure that
 *   EtaCspSocCtrlUstFreqSet is called BEFORE calling this function.
 *
 *  @param iNum the SPI number.
 *  @param tSpiConfig SPI Configurtation struct
 *  @return The result.
 *
 ******************************************************************************/
Initialize the SPI module. Ensure that
EtaCspSocCtrlUstFreqSet is called BEFORE calling this function.

@param iNum the SPI number.
@param tSpiConfig SPI Configurtation struct
@return The result.
Initialize the SPI module . Ensure that EtaCspSocCtrlUstFreqSet is called BEFORE calling this function . @param iNum the SPI number . @param tSpiConfig SPI Configurtation struct @return The result .
tEtaStatus
EtaCspSpiInit(tSpiNum iNum, tSpiConfig iSpiConfig)
{
  uint32_t spi_config;
  uint32_t spi_config2;
  uint32_t spi_divclk;
  uint32_t hfo_freq;
  if (iSpiConfig.ui8IntSize > 0x1F) {
    return (eEtaSpiInvalidConfig);
  }
  spi_config          = (iSpiConfig.ui8IntSize          << BP_SPI_CONFIG_FIFO_LEVEL_TRIG) |
                        (iSpiConfig.spiBitEndian        << BP_SPI_CONFIG_END)             |
                        (iSpiConfig.spiClkPhase         << BP_SPI_CONFIG_CPHA)            |
                        (iSpiConfig.spiClkPol           << BP_SPI_CONFIG_CPOL)            ;
  spi_config2         = (iSpiConfig.spiByteEndian       << BP_SPI_CONFIG2_RX_BYTE2_END)    |
                        (iSpiConfig.spiByteEndian       << BP_SPI_CONFIG2_TX_BYTE2_END)    |
                        (0x1                            << BP_SPI_CONFIG2_AGGR_CLK_GATING) |
                        (0x0                            << BP_SPI_CONFIG2_CLK_ON)          |
                        (0x1                            << BP_SPI_CONFIG2_STALL_IF_RXFULL) ;
  switch (EtaCspSocCtrlUstFreqGet())
  {
    case (eSocCtrlUSTSel8MHz) : hfo_freq = 8000; break;
    case (eSocCtrlUSTSel4MHz) : hfo_freq = 4000; break;
    case (eSocCtrlUSTSel2MHz) : hfo_freq = 2000; break;
    default :
         return (eEtaSpiInvalidConfig);
         break;
  }
  if ((iSpiConfig.spiClkFreq*2) > hfo_freq) 
    return (eEtaSpiInvalidConfig);
  if ((iSpiConfig.spiClkFreq << 4) < hfo_freq) 
    return (eEtaSpiInvalidConfig);
  spi_divclk = ((hfo_freq/iSpiConfig.spiClkFreq)-1) & BM_SPI_CLKDIV_CLKDIV;
  switch (spi_divclk)
  {
    case (0) : return (eEtaSpiInvalidConfig); break; 
    case (1) : spi_config2 |= (1 << BP_SPI_CONFIG2_RX_SAMPLE_TIME) | BM_SPI_CONFIG2_DISABLE_MISO_METAFLOP; break;
    case (2) : spi_config2 |= (2 << BP_SPI_CONFIG2_RX_SAMPLE_TIME); break;
    default  : break;
  }
  if (iSpiConfig.ui8ICG == 0xff) {
    spi_divclk |= (spi_divclk & BM_SPI_CLKDIV_CLKDIV) << BP_SPI_CLKDIV_ICG;
  }
  else {
    if (iSpiConfig.ui8ICG <= 0xF) {
      spi_divclk |= (iSpiConfig.ui8ICG << BP_SPI_CLKDIV_ICG) & BM_SPI_CLKDIV_ICG;
    }
    else {
      return (eEtaSpiInvalidConfig);
    }
  }
  if (iSpiConfig.ui8IBG == 0xff) {
    spi_divclk |= (spi_divclk & BM_SPI_CLKDIV_CLKDIV) << BP_SPI_CLKDIV_IBG;
  }
  else {
    if (iSpiConfig.ui8IBG <= 0xF) {
      spi_divclk |= (iSpiConfig.ui8IBG << BP_SPI_CLKDIV_IBG) & BM_SPI_CLKDIV_IBG;
    }
    else {
      return (eEtaSpiInvalidConfig);
    }
  }
  REG_SPI_CONFIG(iNum).V  = spi_config;
  REG_SPI_CONFIG2(iNum).V = spi_config2;
  REG_SPI_CLKDIV(iNum).V  = spi_divclk;
  REG_SPI_SLAVE_MODE(iNum).BF.SLAVE_EN = iSpiConfig.bSpiSlave;
  return (eEtaSuccess);
}
tEtaStatus EtaCspSpiInit ( tSpiNum iNum , tSpiConfig iSpiConfig ) { uint32_t spi_config ; uint32_t spi_config2 ; uint32_t spi_divclk ; uint32_t hfo_freq ; if ( iSpiConfig . ui8IntSize > 0x1F ) { return ( eEtaSpiInvalidConfig ) ; } spi_config = ( iSpiConfig . ui8IntSize << BP_SPI_CONFIG_FIFO_LEVEL_TRIG ) | ( iSpiConfig . spiBitEndian << BP_SPI_CONFIG_END ) | ( iSpiConfig . spiClkPhase << BP_SPI_CONFIG_CPHA ) | ( iSpiConfig . spiClkPol << BP_SPI_CONFIG_CPOL ) ; spi_config2 = ( iSpiConfig . spiByteEndian << BP_SPI_CONFIG2_RX_BYTE2_END ) | ( iSpiConfig . spiByteEndian << BP_SPI_CONFIG2_TX_BYTE2_END ) | ( 0x1 << BP_SPI_CONFIG2_AGGR_CLK_GATING ) | ( 0x0 << BP_SPI_CONFIG2_CLK_ON ) | ( 0x1 << BP_SPI_CONFIG2_STALL_IF_RXFULL ) ; switch ( EtaCspSocCtrlUstFreqGet ( ) ) { case ( eSocCtrlUSTSel8MHz ) : hfo_freq = 8000 ; break ; case ( eSocCtrlUSTSel4MHz ) : hfo_freq = 4000 ; break ; case ( eSocCtrlUSTSel2MHz ) : hfo_freq = 2000 ; break ; default : return ( eEtaSpiInvalidConfig ) ; break ; } if ( ( iSpiConfig . spiClkFreq * 2 ) > hfo_freq ) return ( eEtaSpiInvalidConfig ) ; if ( ( iSpiConfig . spiClkFreq << 4 ) < hfo_freq ) return ( eEtaSpiInvalidConfig ) ; spi_divclk = ( ( hfo_freq / iSpiConfig . spiClkFreq ) - 1 ) & BM_SPI_CLKDIV_CLKDIV ; switch ( spi_divclk ) { case ( 0 ) : return ( eEtaSpiInvalidConfig ) ; break ; case ( 1 ) : spi_config2 |= ( 1 << BP_SPI_CONFIG2_RX_SAMPLE_TIME ) | BM_SPI_CONFIG2_DISABLE_MISO_METAFLOP ; break ; case ( 2 ) : spi_config2 |= ( 2 << BP_SPI_CONFIG2_RX_SAMPLE_TIME ) ; break ; default : break ; } if ( iSpiConfig . ui8ICG == 0xff ) { spi_divclk |= ( spi_divclk & BM_SPI_CLKDIV_CLKDIV ) << BP_SPI_CLKDIV_ICG ; } else { if ( iSpiConfig . ui8ICG <= 0xF ) { spi_divclk |= ( iSpiConfig . ui8ICG << BP_SPI_CLKDIV_ICG ) & BM_SPI_CLKDIV_ICG ; } else { return ( eEtaSpiInvalidConfig ) ; } } if ( iSpiConfig . ui8IBG == 0xff ) { spi_divclk |= ( spi_divclk & BM_SPI_CLKDIV_CLKDIV ) << BP_SPI_CLKDIV_IBG ; } else { if ( iSpiConfig . ui8IBG <= 0xF ) { spi_divclk |= ( iSpiConfig . ui8IBG << BP_SPI_CLKDIV_IBG ) & BM_SPI_CLKDIV_IBG ; } else { return ( eEtaSpiInvalidConfig ) ; } } REG_SPI_CONFIG ( iNum ) . V = spi_config ; REG_SPI_CONFIG2 ( iNum ) . V = spi_config2 ; REG_SPI_CLKDIV ( iNum ) . V = spi_divclk ; REG_SPI_SLAVE_MODE ( iNum ) . BF . SLAVE_EN = iSpiConfig . bSpiSlave ; return ( eEtaSuccess ) ; }
EtaCspSpiInit - Initialize the SPI module.
EtaCspSpiInit - Initialize the SPI module .
// Configurations // Determine what our source clock is // Check if desired close is within range // Cannot achieve freq (max) // Cannot achieve freq (min) // Add some subtle tweaks for corner cases // Illegal // Add in inter command gap // Add in inter byte gap