SAML21: A different SLOW clock must be used with SERCOM5

This commit is contained in:
Gregory Nutt 2015-06-10 08:18:05 -06:00
parent cc714678d4
commit 85e0da0588
5 changed files with 106 additions and 28 deletions

View File

@ -310,7 +310,7 @@ int sam_usart_internal(const struct sam_usart_config_s * const config)
sam_gclk_chan_enable(config->sercom + GCLK_CHAN_SERCOM0_CORE,
config->gclkgen);
#endif
sercom_slowclk_configure(BOARD_SERCOM_SLOW_GCLKGEN);
sercom_slowclk_configure(config->sercom, BOARD_SERCOM_SLOW_GCLKGEN);
/* Set USART configuration according to the board configuration */

View File

@ -61,6 +61,13 @@
* Pre-processor Definitions
****************************************************************************/
#undef HAVE_SERCOM0_4
#if defined(CONFIG_SAMDL_SERCOM0) || defined(CONFIG_SAMDL_SERCOM1) || \
defined(CONFIG_SAMDL_SERCOM2) || defined(CONFIG_SAMDL_SERCOM3) || \
defined(CONFIG_SAMDL_SERCOM4)
# define HAVE_SERCOM0_4
#endif
/****************************************************************************
* Private Data
****************************************************************************/
@ -146,42 +153,113 @@ void sercom_coreclk_configure(int sercom, int gclkgen, bool wrlock)
*
****************************************************************************/
void sercom_slowclk_configure(int gclkgen)
void sercom_slowclk_configure(int sercom, int gclkgen)
{
#if defined(CONFIG_ARCH_FAMILY_SAML21)
static bool configured = false;
#ifdef HAVE_SERCOM0_4
static bool configured = false;
#endif
#ifdef CONFIG_SAMDL_SERCOM5
static bool configured5 = false;
#endif
#ifdef CONFIG_DEBUG
static uint8_t slowgen = 0xff;
#ifdef HAVE_SERCOM0_4
static uint8_t slowgen = 0xff;
#endif
#ifdef CONFIG_SAMDL_SERCOM5
static uint8_t slowgen5 = 0xff;
#endif
#endif
/* Setup the SERCOMn_GCLK channel. This is common to all SERCOM modules
* and should be done only once.
/* Setup the SERCOMn_GCLK channel. SERCOM0-4 use a common channel, but
* SERCOM5 uses a different channel. Configuration should be done only
* once.
*/
if (!configured)
switch (sercom)
{
/* Configure the common slow clock channel */
sam_gclk_chan_enable(BOARD_SERCOM_SLOW_GCLKCHAN, gclkgen);
/* The slow clock is now configured and should not be configured again. */
configured = true;
#ifdef CONFIG_DEBUG
slowgen = (uint8_t)gclkgen;
#ifdef HAVE_SERCOM0_4
#ifdef CONFIG_SAMDL_SERCOM0
case 0:
#endif
}
#ifdef CONFIG_SAMDL_SERCOM1
case 1:
#endif
#ifdef CONFIG_SAMDL_SERCOM2
case 2:
#endif
#ifdef CONFIG_SAMDL_SERCOM3
case 3:
#endif
#ifdef CONFIG_SAMDL_SERCOM4
case 4:
#endif
if (!configured)
{
/* Configure the common slow clock channel */
sam_gclk_chan_enable(GCLK_CHAN_SERCOM0_SLOW, gclkgen);
/* The slow clock is now configured and should not be configured
* again.
*/
configured = true;
#ifdef CONFIG_DEBUG
slowgen = (uint8_t)gclkgen;
#endif
}
#ifdef CONFIG_DEBUG
/* Already configured. This is okay provided that the same GCLK generator
* is being used. Otherwise, there is a problem.
*/
/* Already configured. This is okay provided that the same GCLK
* generator is being used. Otherwise, there is a problem.
*/
else
{
DEBUGASSERT((int)slowgen == gclkgen);
}
else
{
DEBUGASSERT((int)slowgen == gclkgen);
}
#endif
break;
#endif /* HAVE_SERCOM0_4 */
#ifdef CONFIG_SAMDL_SERCOM5
case 5:
if (!configured5)
{
/* Configure the common slow clock channel */
sam_gclk_chan_enable(GCLK_CHAN_SERCOM5_SLOW, gclkgen);
/* The slow clock is now configured and should not be configured
* again.
*/
configured5 = true;
#ifdef CONFIG_DEBUG
slowgen5 = (uint8_t)gclkgen;
#endif
}
#ifdef CONFIG_DEBUG
/* Already configured. This is okay provided that the same GCLK
* generator is being used. Otherwise, there is a problem.
*/
else
{
DEBUGASSERT((int)slowgen5 == gclkgen);
}
#endif
break;
#endif /* CONFIG_SAMDL_SERCOM5 */
/* Unsupport or invalid SERCOM number provided */
default:
DEBUGPANIC();
break;
}
#elif defined(CONFIG_ARCH_FAMILY_SAMD20)
static bool configured = false;

View File

@ -148,7 +148,7 @@ void sercom_coreclk_configure(int sercom, int gclkgen, bool wrlock);
*
****************************************************************************/
void sercom_slowclk_configure(int gclkgen);
void sercom_slowclk_configure(int sercom, int gclkgen);
#undef EXTERN
#if defined(__cplusplus)

View File

@ -1528,7 +1528,7 @@ struct spi_dev_s *up_spiinitialize(int port)
/* Configure the GCLKs for the SERCOM module */
sercom_coreclk_configure(priv->sercom, priv->gclkgen, false);
sercom_slowclk_configure(BOARD_SERCOM_SLOW_GCLKGEN);
sercom_slowclk_configure(priv->sercom, BOARD_SERCOM_SLOW_GCLKGEN);
/* Set the SERCOM in SPI master mode (no address) */

View File

@ -496,11 +496,11 @@
/* SERCOM definitions ***************************************************************/
/* This is the source clock generator for the GCLK_SERCOM_SLOW clock that is common
* to all SERCOM modules.
* to SERCOM modules 0-4. It will generate clocking on the common SERCOM0-4
* channel.
*/
#define BOARD_SERCOM_SLOW_GCLKGEN 0
#define BOARD_SERCOM_SLOW_GCLKCHAN GCLK_CHAN_SERCOM0_SLOW
/* SERCOM0 SPI is available on EXT1
*