Skip to content

Commit f9cc15e

Browse files
committed
cpu/sam4s: introduce initial support
Signed-off-by: dylad <[email protected]>
1 parent 7e33118 commit f9cc15e

File tree

12 files changed

+315
-0
lines changed

12 files changed

+315
-0
lines changed

cpu/sam4s/Kconfig

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright (c) 2025 Mesotic SAS
2+
#
3+
# This file is subject to the terms and conditions of the GNU Lesser
4+
# General Public License v2.1. See the file LICENSE in the top level
5+
# directory for more details.
6+
#
7+
8+
config CPU_FAM_SAM4S
9+
bool
10+
select CPU_CORE_CORTEX_M4
11+
12+
## CPU Models
13+
config CPU_MODEL_SAM4SD32C
14+
bool
15+
select CPU_FAM_SAM4S
16+
17+
## Common CPU symbols
18+
config CPU_FAM
19+
default "sam4s" if CPU_FAM_SAM4S
20+
21+
config CPU_MODEL
22+
default "sam4sd32c" if CPU_MODEL_SAM4SD32C
23+
24+
config CPU
25+
default "sam4s" if CPU_FAM_SAM4s
26+
27+
source "$(RIOTCPU)/cortexm_common/Kconfig"

cpu/sam4s/Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# define the module that is build
2+
MODULE = cpu
3+
4+
# add a list of subdirectories, that should also be build
5+
DIRS = periph $(RIOTCPU)/cortexm_common $(RIOTCPU)/sam_common
6+
7+
# (file triggers compiler bug. see #5775)
8+
SRC_NOLTO += vectors.c
9+
10+
include $(RIOTBASE)/Makefile.base

cpu/sam4s/Makefile.dep

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include $(RIOTCPU)/sam_common/Makefile.dep

cpu/sam4s/Makefile.features

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CPU_CORE = cortex-m4
2+
CPU_FAM = sam4s
3+
4+
FEATURES_PROVIDED += cortexm_mpu
5+
6+
include $(RIOTCPU)/cortexm_common/Makefile.features

cpu/sam4s/Makefile.include

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
ROM_START_ADDR ?= 0x400000
2+
RAM_START_ADDR ?= 0x20000000
3+
4+
ROM_LEN ?= 0x200000
5+
RAM_LEN ?= 0x28000
6+
7+
include $(RIOTCPU)/sam_common/Makefile.include
8+
include $(RIOTMAKE)/arch/cortexm.inc.mk

cpu/sam4s/cpu.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright (C) 2025 Mesotic SAS
3+
*
4+
* This file is subject to the terms and conditions of the GNU Lesser
5+
* General Public License v2.1. See the file LICENSE in the top level
6+
* directory for more details.
7+
*/
8+
9+
/**
10+
* @ingroup cpu_sam4s
11+
* @{
12+
*
13+
* @file
14+
* @brief Implementation of the CPU initialization
15+
*
16+
* @author Dylan Laduranty <[email protected]>
17+
* @}
18+
*/
19+
20+
#include "cpu.h"
21+
#include "board.h"
22+
#include "kernel_init.h"
23+
#include "periph_conf.h"
24+
#include "periph/init.h"
25+
#include "stdio_base.h"
26+
27+
#define XTAL_STARTUP (8U)
28+
#define PLL_CNT (64U)
29+
30+
#if ((CLOCK_PLL_MUL < 7) || (CLOCK_PLL_MUL > 62))
31+
#error "CLOCK_PLL_MUL has an incorrect value"
32+
#endif
33+
34+
/**
35+
* @brief Initialize the CPU, set IRQ priorities
36+
*/
37+
void cpu_init(void)
38+
{
39+
/* SAM4s MCUs requires WPKEY for enabling peripheral */
40+
PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;
41+
42+
/* disable the watchdog timer */
43+
WDT->WDT_MR |= WDT_MR_WDDIS;
44+
45+
/* initialize the Cortex-M core */
46+
cortexm_init();
47+
48+
/* setup the flash wait states */
49+
EFC0->EEFC_FMR = EEFC_FMR_FWS(CLOCK_FWS);
50+
EFC1->EEFC_FMR = EEFC_FMR_FWS(CLOCK_FWS);
51+
52+
/* enable the Cortex-M Cache Controller */
53+
CMCC->CMCC_CTRL |= CMCC_CTRL_CEN;
54+
55+
/* unlock write protect register for PMC module */
56+
PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;
57+
58+
/* activate the external crystal */
59+
PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD
60+
| CKGR_MOR_MOSCXTST(XTAL_STARTUP)
61+
| CKGR_MOR_MOSCXTEN
62+
| CKGR_MOR_MOSCRCEN;
63+
64+
/* wait for crystal to be stable */
65+
while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)) {}
66+
67+
/* select crystal to clock the main clock */
68+
PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD
69+
| CKGR_MOR_MOSCXTST(XTAL_STARTUP)
70+
| CKGR_MOR_MOSCXTEN
71+
| CKGR_MOR_MOSCRCEN
72+
| CKGR_MOR_MOSCSEL;
73+
74+
/* wait for main oscillator selection to be complete */
75+
while (!(PMC->PMC_SR & PMC_SR_MOSCSELS)) {}
76+
77+
/* setup PLLA */
78+
PMC->CKGR_PLLAR = CKGR_PLLAR_ONE
79+
| CKGR_PLLAR_PLLACOUNT(PLL_CNT)
80+
| CKGR_PLLAR_MULA(CLOCK_PLL_MUL)
81+
| CKGR_PLLAR_DIVA(CLOCK_PLL_DIV);
82+
83+
/* wait for PLL to lock */
84+
while (!(PMC->PMC_SR & PMC_SR_LOCKA)) {}
85+
86+
/* before switching to PLLA, we need to switch to main clock */
87+
PMC->PMC_MCKR = PMC_MCKR_CSS_MAIN_CLK;
88+
while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {}
89+
90+
/* use PLLA as main clock source */
91+
PMC->PMC_MCKR = PMC_MCKR_CSS_PLLA_CLK;
92+
/* wait for master clock to be ready */
93+
while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {}
94+
95+
/* setup the SCLK: switch to external oscillator if applicable */
96+
#if CLOCK_SCLK_XTAL
97+
/* enable external oscillator */
98+
SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_XTALSEL;
99+
while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL_CRYST)) {}
100+
#endif
101+
102+
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
103+
early_init();
104+
105+
/* trigger static peripheral initialization */
106+
periph_init();
107+
}

cpu/sam4s/doc.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @defgroup cpu_sam4s Atmel SAM4S
3+
* @ingroup cpu
4+
* @brief Atmel SAM4S Cortex-M4 MCU specific implementation.
5+
*
6+
* This module contains Atmel SAM4S specific code and definition.
7+
*
8+
* @see cpu_sam_common
9+
*/

cpu/sam4s/include/periph_cpu.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (C) 2025 Mesotic SAS
3+
*
4+
* This file is subject to the terms and conditions of the GNU Lesser
5+
* General Public License v2.1. See the file LICENSE in the top level
6+
* directory for more details.
7+
*/
8+
9+
/**
10+
* @ingroup cpu_sam4s
11+
* @{
12+
*
13+
* @file
14+
* @brief CPU specific definitions for internal peripheral handling
15+
*
16+
* @author Dylan Laduranty <[email protected]>
17+
*
18+
*/
19+
20+
#ifndef PERIPH_CPU_H
21+
#define PERIPH_CPU_H
22+
23+
#include "periph_cpu_common.h"
24+
#include "macros/units.h"
25+
26+
#ifdef __cplusplus
27+
extern "C" {
28+
#endif
29+
30+
#ifdef __cplusplus
31+
}
32+
#endif
33+
34+
#endif /* PERIPH_CPU_H */
35+
/** @} */

cpu/sam4s/periph/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include $(RIOTMAKE)/periph.mk

cpu/sam4s/vectors.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright (C) 2025 Mesotic SAS
3+
*
4+
* This file is subject to the terms and conditions of the GNU Lesser
5+
* General Public License v2.1. See the file LICENSE in the top level
6+
* directory for more details.
7+
*/
8+
9+
/**
10+
* @ingroup cpu_sam4s
11+
* @{
12+
*
13+
* @file
14+
* @brief Startup code and interrupt vector definition
15+
*
16+
* @author Dylan Laduranty <[email protected]>
17+
*
18+
* @}
19+
*/
20+
21+
#include <stdint.h>
22+
#include "vectors_cortexm.h"
23+
24+
/* define a local dummy handler as it needs to be in the same compilation unit
25+
* as the alias definition */
26+
void dummy_handler(void) {
27+
dummy_handler_default();
28+
}
29+
30+
/* Cortex-M common interrupt vectors */
31+
WEAK_DEFAULT void isr_svc(void);
32+
WEAK_DEFAULT void isr_pendsv(void);
33+
WEAK_DEFAULT void isr_systick(void);
34+
/* SAM4S specific interrupt vector */
35+
WEAK_DEFAULT void isr_supc(void);
36+
WEAK_DEFAULT void isr_rstc(void);
37+
WEAK_DEFAULT void isr_rtc(void);
38+
WEAK_DEFAULT void isr_rtt(void);
39+
WEAK_DEFAULT void isr_wdt(void);
40+
WEAK_DEFAULT void isr_pmc(void);
41+
WEAK_DEFAULT void isr_eefc0(void);
42+
WEAK_DEFAULT void isr_eefc1(void);
43+
WEAK_DEFAULT void isr_uart0(void);
44+
WEAK_DEFAULT void isr_uart1(void);
45+
WEAK_DEFAULT void isr_smc(void);
46+
WEAK_DEFAULT void isr_pioa(void);
47+
WEAK_DEFAULT void isr_piob(void);
48+
WEAK_DEFAULT void isr_pioc(void);
49+
WEAK_DEFAULT void isr_usart0(void);
50+
WEAK_DEFAULT void isr_usart1(void);
51+
WEAK_DEFAULT void isr_hsmci(void);
52+
WEAK_DEFAULT void isr_twi0(void);
53+
WEAK_DEFAULT void isr_twi1(void);
54+
WEAK_DEFAULT void isr_spi(void);
55+
WEAK_DEFAULT void isr_ssc(void);
56+
WEAK_DEFAULT void isr_tc0(void);
57+
WEAK_DEFAULT void isr_tc1(void);
58+
WEAK_DEFAULT void isr_tc2(void);
59+
WEAK_DEFAULT void isr_tc3(void);
60+
WEAK_DEFAULT void isr_tc4(void);
61+
WEAK_DEFAULT void isr_tc5(void);
62+
WEAK_DEFAULT void isr_adc(void);
63+
WEAK_DEFAULT void isr_dacc(void);
64+
WEAK_DEFAULT void isr_pwm(void);
65+
WEAK_DEFAULT void isr_crccu(void);
66+
WEAK_DEFAULT void isr_acc(void);
67+
WEAK_DEFAULT void isr_udp(void);
68+
69+
/* CPU specific interrupt vector table */
70+
ISR_VECTOR(1) const isr_t vector_cpu[CPU_IRQ_NUMOF] = {
71+
isr_supc, /* 0 Supply Controller */
72+
isr_rstc, /* 1 Reset Controller */
73+
isr_rtc, /* 2 Real Time Clock */
74+
isr_rtt, /* 3 Real Timer Timer */
75+
isr_wdt, /* 4 Watchdog Timer */
76+
isr_pmc, /* 5 Power Management Controller */
77+
isr_eefc0, /* 6 Enhanced Embedded Flash Controller 0 */
78+
isr_eefc1, /* 7 Enhanced Embedded Flash Controller 1 */
79+
isr_uart0, /* 8 Universal Asynchronous Receiver Transceiver 0 */
80+
isr_uart1, /* 9 Universal Asynchronous Receiver Transceiver 1 */
81+
isr_smc, /* 10 Static Memory Controller */
82+
isr_pioa, /* 11 GPIO port A */
83+
isr_piob, /* 12 GPIO port B */
84+
isr_pioc, /* 13 GPIO port C */
85+
isr_usart0, /* 14 USART0 */
86+
isr_usart1, /* 15 USART1 */
87+
(0UL), /* Reserved */
88+
(0UL), /* Reserved */
89+
isr_hsmci, /* 18 Multimedia Card Interface */
90+
isr_twi0, /* 19 Two-wire Interface 0 */
91+
isr_twi1, /* 20 Two-wire Interface 1 */
92+
isr_spi, /* 21 Serial Peripheral Interface */
93+
isr_ssc, /* 22 Synchronous Serial Controller */
94+
isr_tc0, /* 23 Timer Counter 0 */
95+
isr_tc1, /* 24 Timer Counter 1 */
96+
isr_tc2, /* 25 Timer Counter 2 */
97+
isr_tc3, /* 26 Timer Counter 3 */
98+
isr_tc4, /* 27 Timer Counter 4 */
99+
isr_tc5, /* 28 Timer Counter 5 */
100+
isr_adc, /* 29 Analog/Digital Converter */
101+
isr_dacc, /* 30 Digital/Analog Converter Controller */
102+
isr_pwm, /* 31 Pulse Width Modulation */
103+
isr_crccu, /* 32 CRC Calculation Unit */
104+
isr_acc, /* 33 Analog Comparator Controller */
105+
isr_udp, /* 34 USB Device Port */
106+
};

0 commit comments

Comments
 (0)