diff --git a/arch/arm/src/samd5e5/Make.defs b/arch/arm/src/samd5e5/Make.defs index 8468325b135..b5b3656a2fa 100644 --- a/arch/arm/src/samd5e5/Make.defs +++ b/arch/arm/src/samd5e5/Make.defs @@ -88,7 +88,8 @@ endif CHIP_ASRCS = CHIP_CSRCS = sam_clockconfig.c sam_cmcc.c sam_gclk.c sam_irq.c -CHIP_CSRCS += sam_lowputc.c sam_port.c sam_serial.c sam_start.c sam_usart.c +CHIP_CSRCS += sam_lowputc.c sam_port.c sam_serial.c sam_sercom.c sam_start.c +CHIP_CSRCS += sam_usart.c # Configuration-dependent SAMD5x/E5x files diff --git a/arch/arm/src/samd5e5/sam_clockconfig.c b/arch/arm/src/samd5e5/sam_clockconfig.c index e5364e6a4ed..95658b85e5a 100644 --- a/arch/arm/src/samd5e5/sam_clockconfig.c +++ b/arch/arm/src/samd5e5/sam_clockconfig.c @@ -732,7 +732,7 @@ static void sam_dfll_configure(const struct sam_dfll_config_s *config) { /* Configure the GCLK channel */ - sam_gclk_chan_enable(GCLK_CHAN_OSCCTRL_DFLL, config->gclk); + sam_gclk_chan_enable(GCLK_CHAN_OSCCTRL_DFLL, config->gclk, true); } /* Setup the DFLLMUL register */ @@ -936,7 +936,7 @@ static void sam_dpll_gclkchannel(uint8_t chan, { /* Yes.. configure the GCLK channel */ - sam_gclk_chan_enable(chan, config->gclk); + sam_gclk_chan_enable(chan, config->gclk, true); } } diff --git a/arch/arm/src/samd5e5/sam_gclk.c b/arch/arm/src/samd5e5/sam_gclk.c index aaa843ea310..c7e0e77e5e2 100644 --- a/arch/arm/src/samd5e5/sam_gclk.c +++ b/arch/arm/src/samd5e5/sam_gclk.c @@ -209,13 +209,14 @@ void sam_gclk_config(FAR const struct sam_gclkconfig_s *config) * Input Parameters: * channel - Index of the GCLK channel to be enabled * srcgen - The GCLK source generator index + * wrlock - True: set writelock * * Returned Value: * None * ****************************************************************************/ -void sam_gclk_chan_enable(uint8_t channel, uint8_t srcgen) +void sam_gclk_chan_enable(uint8_t channel, uint8_t srcgen, bool wrlock) { irqstate_t flags; uint32_t regaddr; @@ -235,14 +236,23 @@ void sam_gclk_chan_enable(uint8_t channel, uint8_t srcgen) regval = GCLK_PCHCTRL_GEN(srcgen); putreg32(regval, regaddr); - /* Enable the peripheral channel */ + /* Enable the peripheral channel, setting the writelock if so requested. */ regval |= GCLK_PCHCTRL_CHEN; + + if (wrlock) + { + regval |= GCLK_PCHCTRL_WRTLOCK; + } + putreg32(regval, regaddr); /* Wait for clock synchronization */ - while ((getreg32(regaddr) &GCLK_PCHCTRL_CHEN) == 0); + while ((getreg32(regaddr) &GCLK_PCHCTRL_CHEN) == 0) + { + } + leave_critical_section(flags); } diff --git a/arch/arm/src/samd5e5/sam_gclk.h b/arch/arm/src/samd5e5/sam_gclk.h index fc3e1f54049..f3fa1dc0539 100644 --- a/arch/arm/src/samd5e5/sam_gclk.h +++ b/arch/arm/src/samd5e5/sam_gclk.h @@ -116,13 +116,14 @@ void sam_gclk_config(FAR const struct sam_gclkconfig_s *config); * Input Parameters: * channel - Index of the GCLK channel to be enabled * srcgen - The GCLK source generator index + * wrlock - True: set writelock * * Returned Value: * None * ****************************************************************************/ -void sam_gclk_chan_enable(uint8_t channel, uint8_t srcgen); +void sam_gclk_chan_enable(uint8_t channel, uint8_t srcgen, bool wrlock); /**************************************************************************** * Name: sam_gclk_chan_disable diff --git a/arch/arm/src/samd5e5/sam_i2c_master.c b/arch/arm/src/samd5e5/sam_i2c_master.c index 95d9528c977..f70526b381c 100644 --- a/arch/arm/src/samd5e5/sam_i2c_master.c +++ b/arch/arm/src/samd5e5/sam_i2c_master.c @@ -1142,7 +1142,6 @@ static void i2c_hw_initialize(struct sam_i2c_dev_s *priv, uint32_t frequency) irqstate_t flags; uint32_t regval; uint32_t ctrla = 0; - int channel; i2cinfo("I2C%d Initializing\n", priv->attr->i2c); @@ -1154,10 +1153,6 @@ static void i2c_hw_initialize(struct sam_i2c_dev_s *priv, uint32_t frequency) /* Configure the GCLKs for the SERCOM module */ sercom_coreclk_configure(priv->attr->sercom, priv->attr->coregen, false); - - channel = priv->attr->sercom + GCLK_CHAN_SERCOM0_CORE; - sam_gclk_chan_enable(channel, priv->attr->coregen); - sercom_slowclk_configure(priv->attr->sercom, priv->attr->slowgen); /* Check if module is enabled */ @@ -1243,12 +1238,12 @@ static void i2c_pad_configure(struct sam_i2c_dev_s *priv) if (priv->attr->pad0 != 0) { - sam_configport(priv->attr->pad0); + sam_portconfig(priv->attr->pad0); } if (priv->attr->pad1 != 0) { - sam_configport(priv->attr->pad1); + sam_portconfig(priv->attr->pad1); } } diff --git a/arch/arm/src/samd5e5/sam_lowputc.c b/arch/arm/src/samd5e5/sam_lowputc.c index f194da4a497..fba7998b93c 100644 --- a/arch/arm/src/samd5e5/sam_lowputc.c +++ b/arch/arm/src/samd5e5/sam_lowputc.c @@ -251,22 +251,22 @@ sam_pad_configure(const struct sam_usart_config_s * const config) if (config->pad0 != 0) { - sam_configport(config->pad0); + sam_portconfig(config->pad0); } if (config->pad1 != 0) { - sam_configport(config->pad1); + sam_portconfig(config->pad1); } if (config->pad2 != 0) { - sam_configport(config->pad2); + sam_portconfig(config->pad2); } if (config->pad3 != 0) { - sam_configport(config->pad3); + sam_portconfig(config->pad3); } } #endif @@ -284,7 +284,6 @@ sam_pad_configure(const struct sam_usart_config_s * const config) #ifdef SAMD5E5_HAVE_USART int sam_usart_internal(const struct sam_usart_config_s * const config) { - int channel; int ret; /* Enable clocking to the SERCOM module */ @@ -294,10 +293,6 @@ int sam_usart_internal(const struct sam_usart_config_s * const config) /* Configure the GCLKs for the SERCOM module */ sercom_coreclk_configure(config->sercom, config->coregen, false); - - channel = config->sercom + GCLK_CHAN_SERCOM0_CORE; - sam_gclk_chan_enable(channel, config->coregen); - sercom_slowclk_configure(config->sercom, config->slowgen); /* Set USART configuration according to the board configuration */ diff --git a/arch/arm/src/samd5e5/sam_port.c b/arch/arm/src/samd5e5/sam_port.c index 8e6c0c7ec9f..0d345ab35f8 100644 --- a/arch/arm/src/samd5e5/sam_port.c +++ b/arch/arm/src/samd5e5/sam_port.c @@ -445,14 +445,14 @@ static inline void sam_configreset(uintptr_t base, port_pinset_t pinset) ****************************************************************************/ /**************************************************************************** - * Name: sam_configport + * Name: sam_portconfig * * Description: * Configure a PORT pin based on bit-encoded description of the pin. * ****************************************************************************/ -int sam_configport(port_pinset_t pinset) +int sam_portconfig(port_pinset_t pinset) { uintptr_t base = sam_portbase(pinset); irqstate_t flags; diff --git a/arch/arm/src/samd5e5/sam_port.h b/arch/arm/src/samd5e5/sam_port.h index f78bb9bbfc7..12763f7d1c3 100644 --- a/arch/arm/src/samd5e5/sam_port.h +++ b/arch/arm/src/samd5e5/sam_port.h @@ -55,7 +55,7 @@ * Pre-processor Declarations ****************************************************************************/ -/* Bit-encoded input to sam_configport() */ +/* Bit-encoded input to sam_portconfig() */ /* 24-bit Encoding. This could be compacted into 16-bits by making the bit usage * mode specific. However, by giving each bit field a unique position, we handle @@ -344,7 +344,7 @@ extern "C" ****************************************************************************/ /**************************************************************************** - * Name: sam_configport + * Name: sam_portconfig * * Description: * Configure a PORT pin based on bit-encoded description of the pin. @@ -354,7 +354,7 @@ extern "C" * ****************************************************************************/ -int sam_configport(port_pinset_t pinset); +int sam_portconfig(port_pinset_t pinset); /**************************************************************************** * Name: sam_portwrite diff --git a/arch/arm/src/samd5e5/sam_sercom.c b/arch/arm/src/samd5e5/sam_sercom.c index 83f0ecb12a9..6a60b6c14df 100644 --- a/arch/arm/src/samd5e5/sam_sercom.c +++ b/arch/arm/src/samd5e5/sam_sercom.c @@ -47,30 +47,20 @@ #include "sam_config.h" -#include "sam_pm.h" +#include "chip.h" +#include "chip/sam_pm.h" #include "sam_gclk.h" #include "sam_sercom.h" #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#undef HAVE_SERCOM0_4 -#if defined(CONFIG_SAMD5E5_SERCOM0) || defined(CONFIG_SAMD5E5_SERCOM1) || \ - defined(CONFIG_SAMD5E5_SERCOM2) || defined(CONFIG_SAMD5E5_SERCOM3) || \ - defined(CONFIG_SAMD5E5_SERCOM4) -# define HAVE_SERCOM0_4 -#endif - /**************************************************************************** * Private Data ****************************************************************************/ static bool g_slowclk_configured = false; #ifdef CONFIG_DEBUG_ASSERTIONS -static uint8_t g_slowclk_gclkgen = 0xff; +static uint8_t g_slowgen = 0xff; #endif static const uint8_t g_corclk_channel[SAMD5E5_NSERCOM] = @@ -174,46 +164,16 @@ void sercom_enable(int sercom) * ****************************************************************************/ -void sercom_coreclk_configure(int sercom, int gclkgen, bool wrlock) +void sercom_coreclk_configure(int sercom, int coregen, bool wrlock) { - uint16_t regval; - uint8_t gclkcore; + uint8_t corechan; DEBUGASSERT((unsigned)sercom < SAMD5E5_NSERCOM); /* Set up the SERCOMn_GCLK_ID_CORE clock */ - gclkcore = g_corclk_channel[sercom]; - regval = ((uint16_t)gclkcore << GCLK_CLKCTRL_ID_SHIFT); - - /* Select and disable the SERCOMn_GCLK_ID_CORE generic clock */ - - putreg16(regval, SAM_GCLK_CLKCTRL); - - /* Wait for clock to become disabled */ - - while ((getreg16(SAM_GCLK_CLKCTRL) & GCLK_CLKCTRL_CLKEN) != 0); - - /* Select the SERCOMn_GCLK_ID_CORE source clock generator */ - - regval |= (uint16_t)gclkgen << GCLK_CLKCTRL_GEN_SHIFT; - - /* Write the new configuration */ - - putreg16(regval, SAM_GCLK_CLKCTRL); - - /* Enable the SERCOMn_GCLK_ID_CORE generic clock, optionally locking - * further writes to this GCLK. - */ - - regval |= GCLK_CLKCTRL_CLKEN; - - if (wrlock) - { - regval |= GCLK_CLKCTRL_WRTLOCK; - } - - putreg16(regval, SAM_GCLK_CLKCTRL); + corechan = g_corclk_channel[sercom]; + sam_gclk_chan_enable(corechan, coregen, wrlock); } /**************************************************************************** @@ -230,7 +190,7 @@ void sercom_coreclk_configure(int sercom, int gclkgen, bool wrlock) * ****************************************************************************/ -void sercom_slowclk_configure(int sercom, int gclkgen) +void sercom_slowclk_configure(int sercom, int slowgen) { DEBUGASSERT((unsigned)sercom < SAMD5E5_NSERCOM); @@ -242,7 +202,7 @@ void sercom_slowclk_configure(int sercom, int gclkgen) * of SERCOM modules and, hence, only need to configured once. */ - sam_gclk_chan_enable(GCLK_CHAN_SERCOMn_SLOW, gclkgen); + sam_gclk_chan_enable(GCLK_CHAN_SERCOMn_SLOW, slowgen, true); /* The slow clock is now configured and should not be re=configured * again. @@ -250,7 +210,7 @@ void sercom_slowclk_configure(int sercom, int gclkgen) g_slowclk_configured = true; #ifdef CONFIG_DEBUG_ASSERTIONS - g_slowclk_gclkgen = (uint8_t)gclkgen; + g_slowgen = (uint8_t)slowgen; #endif } @@ -261,7 +221,7 @@ void sercom_slowclk_configure(int sercom, int gclkgen) else { - DEBUGASSERT((int)g_slowclk_gclkgen == gclkgen); + DEBUGASSERT((int)g_slowgen == slowgen); } #endif } diff --git a/arch/arm/src/samd5e5/sam_spi.c b/arch/arm/src/samd5e5/sam_spi.c index a4e0368ae48..6bd0409918c 100644 --- a/arch/arm/src/samd5e5/sam_spi.c +++ b/arch/arm/src/samd5e5/sam_spi.c @@ -1506,22 +1506,22 @@ static void spi_pad_configure(struct sam_spidev_s *priv) if (priv->pad0 != 0) { - sam_configport(priv->pad0); + sam_portconfig(priv->pad0); } if (priv->pad1 != 0) { - sam_configport(priv->pad1); + sam_portconfig(priv->pad1); } if (priv->pad2 != 0) { - sam_configport(priv->pad2); + sam_portconfig(priv->pad2); } if (priv->pad3 != 0) { - sam_configport(priv->pad3); + sam_portconfig(priv->pad3); } } @@ -1576,10 +1576,6 @@ struct spi_dev_s *sam_spibus_initialize(int port) struct sam_spidev_s *priv; irqstate_t flags; uint32_t regval; - int channel; -#if 0 /* Not used */ - int ret; -#endif /* Get the port state structure */ @@ -1663,10 +1659,6 @@ struct spi_dev_s *sam_spibus_initialize(int port) /* Configure the GCLKs for the SERCOM module */ sercom_coreclk_configure(priv->sercom, priv->coregen, false); - - channel = priv->sercom + GCLK_CHAN_SERCOM0_CORE; - sam_gclk_chan_enable(channel, priv->coregen); - sercom_slowclk_configure(priv->sercom, priv->slowgen); /* Set the SERCOM in SPI master mode (no address) */ diff --git a/configs/metro-m4/src/sam_autoleds.c b/configs/metro-m4/src/sam_autoleds.c index bea2a72e3ea..572c7241080 100644 --- a/configs/metro-m4/src/sam_autoleds.c +++ b/configs/metro-m4/src/sam_autoleds.c @@ -80,6 +80,7 @@ #include "up_arch.h" #include "up_internal.h" +#include "sam_port.h" #include "metro-m4.h" #include @@ -206,7 +207,7 @@ static int led_pm_prepare(struct pm_callback_s *cb, int domain, void board_autoled_initialize(void) { - (void)sam_configport(PORT_RED_LED); + (void)sam_portconfig(PORT_RED_LED); } /**************************************************************************** diff --git a/configs/metro-m4/src/sam_boot.c b/configs/metro-m4/src/sam_boot.c index 85a8a00288d..825b22b3984 100644 --- a/configs/metro-m4/src/sam_boot.c +++ b/configs/metro-m4/src/sam_boot.c @@ -52,7 +52,7 @@ ****************************************************************************/ /**************************************************************************** - * Name: sam_boardinitialize + * Name: sam_board_initialize * * Description: * All SAMD5/E5 architectures must provide the following entry point. @@ -62,7 +62,7 @@ * ****************************************************************************/ -void sam_boardinitialize(void) +void sam_board_initialize(void) { #ifdef CONFIG_ARCH_LEDS /* Configure on-board LEDs if LED support has been selected. */ diff --git a/configs/metro-m4/src/sam_userleds.c b/configs/metro-m4/src/sam_userleds.c index 33f371007ee..18e4148a3f4 100644 --- a/configs/metro-m4/src/sam_userleds.c +++ b/configs/metro-m4/src/sam_userleds.c @@ -60,6 +60,7 @@ #include #include "up_arch.h" +#include "sam_port.h" #include "metro-m4.h" @@ -188,7 +189,7 @@ static int led_pm_prepare(struct pm_callback_s *cb, int domain, void board_userled_initialize(void) { - (void)sam_configport(PORT_STATUS_LED); + (void)sam_portconfig(PORT_STATUS_LED); } /****************************************************************************