Skip to content

Commit

Permalink
fixup! cpu/sam0_common: implement SERCOM time-sharing
Browse files Browse the repository at this point in the history
  • Loading branch information
maribu committed Nov 27, 2024
1 parent f5abef9 commit 935ac6e
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 56 deletions.
19 changes: 19 additions & 0 deletions cpu/sam0_common/include/periph_cpu_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,25 @@ typedef void (*sercom_irq_cb_t)(void *arg);
void sercom_acquire(sercom_t sercom, uint8_t gclk,
sercom_irq_cb_t irq_cb, void *irq_arg);

/**
* @brief Enable the SERCOM APB clock
* @param[in] sercom The SERCOM to enable the clock of
*/
static inline void sercom_apb_enable(sercom_t sercom);

/**
* @brief Disable the SERCOM APB clock
* @param[in] sercom The SERCOM to disable the clock of
*/
static inline void sercom_apb_disable(sercom_t sercom);

/**
* @brief Enable GCLK clock signal to the given SEROM
* @param[in] sercom The SERCOM to clock
* @param[in] gclk Generator clock
*/
static inline void sercom_gclk_enable(sercom_t sercom, uint8_t gclk);

/**
* @brief Release exclusive access to the given SERCOM and disable it
* (low power mode)
Expand Down
59 changes: 3 additions & 56 deletions cpu/sam0_common/periph/sercom.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,44 +86,10 @@ Sercom *sercom_get_baseaddr(sercom_t sercom)
*/
static void _sercom_clk_enable(sercom_t sercom, uint8_t gclk)
{
#if defined(CPU_COMMON_SAMD21)
PM->APBCMASK.reg |= (PM_APBCMASK_SERCOM0 << sercom);
#elif defined (CPU_COMMON_SAMD5X)
if (sercom < 2) {
MCLK->APBAMASK.reg |= (1 << (sercom + 12));
} else if (sercom < 4) {
MCLK->APBBMASK.reg |= (1 << (sercom + 7));
} else {
MCLK->APBDMASK.reg |= (1 << (sercom - 4));
}
#else
if (sercom < 5) {
MCLK->APBCMASK.reg |= (MCLK_APBCMASK_SERCOM0 << sercom);
}
#if defined(CPU_COMMON_SAML21)
else {
MCLK->APBDMASK.reg |= (MCLK_APBDMASK_SERCOM5);
}
#endif /* CPU_COMMON_SAML21 */
#endif
sercom_apb_enable(sercom);

sam0_gclk_enable(gclk);
#if defined(CPU_COMMON_SAMD21)
GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(gclk) |
(SERCOM0_GCLK_ID_CORE + sercom));
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
#elif defined(CPU_COMMON_SAMD5X)
GCLK->PCHCTRL[_sercom_gclk_id_core(sercom)].reg = (GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclk));
#else
if (sercom < 5) {
GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE + sercom].reg = (GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclk));
}
#if defined(CPU_COMMON_SAML21)
else {
GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = (GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclk));
}
#endif /* CPU_COMMON_SAML21 */
#endif
sercom_gclk_enable(sercom, gclk);
}

/**
Expand All @@ -133,26 +99,7 @@ static void _sercom_clk_enable(sercom_t sercom, uint8_t gclk)
*/
static void _sercom_clk_disable(sercom_t sercom)
{
#if defined(CPU_COMMON_SAMD21)
PM->APBCMASK.reg &= ~(PM_APBCMASK_SERCOM0 << sercom);
#elif defined (CPU_COMMON_SAMD5X)
if (sercom < 2) {
MCLK->APBAMASK.reg &= ~(1 << (sercom + 12));
} else if (sercom < 4) {
MCLK->APBBMASK.reg &= ~(1 << (sercom + 7));
} else {
MCLK->APBDMASK.reg &= ~(1 << (sercom - 4));
}
#else
if (sercom < 5) {
MCLK->APBCMASK.reg &= ~(MCLK_APBCMASK_SERCOM0 << sercom);
}
#if defined (CPU_COMMON_SAML21)
else {
MCLK->APBDMASK.reg &= ~(MCLK_APBDMASK_SERCOM5);
}
#endif /* CPU_COMMON_SAML21 */
#endif
sercom_apb_disable(sercom);
}

/**
Expand Down
17 changes: 17 additions & 0 deletions cpu/samd21/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,23 @@ static inline int _sercom_id(SercomUsart *sercom)
return ((((uint32_t)sercom) >> 10) & 0x7) - 2;
}

static inline void sercom_apb_enable(sercom_t sercom)

Check failure on line 98 in cpu/samd21/include/periph_cpu.h

View workflow job for this annotation

GitHub Actions / static-tests

Member sercom_apb_enable(sercom_t sercom) (function) of file periph_cpu.h is not documented.
{
PM->APBCMASK.reg |= (PM_APBCMASK_SERCOM0 << sercom);
}

static inline void sercom_apb_disable(sercom_t sercom)

Check failure on line 103 in cpu/samd21/include/periph_cpu.h

View workflow job for this annotation

GitHub Actions / static-tests

Member sercom_apb_disable(sercom_t sercom) (function) of file periph_cpu.h is not documented.
{
PM->APBCMASK.reg &= ~(PM_APBCMASK_SERCOM0 << sercom);
}

static inline void sercom_gclk_enable(sercom_t sercom, uint8_t gclk)

Check failure on line 108 in cpu/samd21/include/periph_cpu.h

View workflow job for this annotation

GitHub Actions / static-tests

Member sercom_gclk_enable(sercom_t sercom, uint8_t gclk) (function) of file periph_cpu.h is not documented.
{
GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(gclk) |
(SERCOM0_GCLK_ID_CORE + sercom));
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
}

/**
* @brief Pins that can be used for ADC input
*/
Expand Down
31 changes: 31 additions & 0 deletions cpu/samd5x/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,37 @@ struct sam0_aux_cfg_mapping {
#define SAM0_SDHC1_PIN_SDCK GPIO_PIN(PA, 21) /**< Clock */
/** @} */

static inline void sercom_apb_enable(sercom_t sercom)

Check failure on line 299 in cpu/samd5x/include/periph_cpu.h

View workflow job for this annotation

GitHub Actions / static-tests

Member sercom_apb_enable(sercom_t sercom) (function) of file periph_cpu.h is not documented.
{
if (sercom < 2) {
MCLK->APBAMASK.reg |= (1 << (sercom + 12));
}
else if (sercom < 4) {
MCLK->APBBMASK.reg |= (1 << (sercom + 7));
}
else {
MCLK->APBDMASK.reg |= (1 << (sercom - 4));
}
}

static inline void sercom_apb_disable(sercom_t sercom)

Check failure on line 312 in cpu/samd5x/include/periph_cpu.h

View workflow job for this annotation

GitHub Actions / static-tests

Member sercom_apb_disable(sercom_t sercom) (function) of file periph_cpu.h is not documented.
{
if (sercom < 2) {
MCLK->APBAMASK.reg &= ~(1 << (sercom + 12));
}
else if (sercom < 4) {
MCLK->APBBMASK.reg &= ~(1 << (sercom + 7));
}
else {
MCLK->APBDMASK.reg &= ~(1 << (sercom - 4));
}
}

static inline void sercom_gclk_enable(sercom_t sercom, uint8_t gclk)

Check failure on line 325 in cpu/samd5x/include/periph_cpu.h

View workflow job for this annotation

GitHub Actions / static-tests

Member sercom_gclk_enable(sercom_t sercom, uint8_t gclk) (function) of file periph_cpu.h is not documented.
{
GCLK->PCHCTRL[_sercom_gclk_id_core(sercom)].reg = (GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclk));
}

#ifdef __cplusplus
}
#endif
Expand Down
15 changes: 15 additions & 0 deletions cpu/saml1x/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@ struct sam0_aux_cfg_mapping {
uint32_t user_crc; /**< CRC of NVM User Row bits 223:64 (words 2…6) */
};

static inline void sercom_apb_enable(sercom_t sercom)

Check failure on line 158 in cpu/saml1x/include/periph_cpu.h

View workflow job for this annotation

GitHub Actions / static-tests

Member sercom_apb_enable(sercom_t sercom) (function) of file periph_cpu.h is not documented.
{
MCLK->APBCMASK.reg |= (MCLK_APBCMASK_SERCOM0 << sercom);
}

static inline void sercom_apb_disable(sercom_t sercom)

Check failure on line 163 in cpu/saml1x/include/periph_cpu.h

View workflow job for this annotation

GitHub Actions / static-tests

Member sercom_apb_disable(sercom_t sercom) (function) of file periph_cpu.h is not documented.
{
MCLK->APBCMASK.reg &= ~(MCLK_APBCMASK_SERCOM0 << sercom);
}

static inline void sercom_gclk_enable(sercom_t sercom, uint8_t gclk)

Check failure on line 168 in cpu/saml1x/include/periph_cpu.h

View workflow job for this annotation

GitHub Actions / static-tests

Member sercom_gclk_enable(sercom_t sercom, uint8_t gclk) (function) of file periph_cpu.h is not documented.
{
GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE + sercom].reg = (GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclk));
}

#ifdef __cplusplus
}
#endif
Expand Down
30 changes: 30 additions & 0 deletions cpu/saml21/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,36 @@ struct sam0_aux_cfg_mapping {
};
/** @} */

static inline void sercom_apb_enable(sercom_t sercom)

Check failure on line 172 in cpu/saml21/include/periph_cpu.h

View workflow job for this annotation

GitHub Actions / static-tests

Member sercom_apb_enable(sercom_t sercom) (function) of file periph_cpu.h is not documented.
{
if (sercom < 5) {
MCLK->APBCMASK.reg |= (MCLK_APBCMASK_SERCOM0 << sercom);
}
else {
MCLK->APBDMASK.reg |= (MCLK_APBDMASK_SERCOM5);
}
}

static inline void sercom_apb_disable(sercom_t sercom)
{
if (sercom < 5) {
MCLK->APBCMASK.reg &= ~(MCLK_APBCMASK_SERCOM0 << sercom);
}
else {
MCLK->APBDMASK.reg &= ~(MCLK_APBDMASK_SERCOM5);
}
}

static inline void sercom_gclk_enable(sercom_t sercom, uint8_t gclk)
{
if (sercom < 5) {
GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE + sercom].reg = (GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclk));
}
else {
GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = (GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclk));
}
}

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit 935ac6e

Please sign in to comment.