1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author         Notes
8  * 2021-01-28     flybreak       first version
9  * 2023-01-22     rose_man       add RT_USING_SMP
10  */
11 
12 #include <rthw.h>
13 #include <rtthread.h>
14 #include <stdio.h>
15 #include "board.h"
16 #include <pico/bootrom.h>
17 #include <pico/stdlib.h>
18 #include <hardware/clocks.h>
19 #include <hardware/structs/systick.h>
20 #include <drv_uart.h>
21 
22 #define PLL_SYS_KHZ (133 * 1000)
23 
isr_systick(void)24 void isr_systick(void)
25 {
26     /* enter interrupt */
27 #ifndef RT_USING_SMP
28     rt_interrupt_enter();
29 #endif
30 
31     rt_tick_increase();
32 
33     /* leave interrupt */
34 #ifndef RT_USING_SMP
35     rt_interrupt_leave();
36 #endif
37 }
38 
systick_config(uint32_t ticks)39 uint32_t systick_config(uint32_t ticks)
40 {
41     if ((ticks - 1UL) > M0PLUS_SYST_RVR_RELOAD_BITS)
42     {
43         return (1UL);                                                   /* Reload value impossible */
44     }
45 
46     systick_hw->rvr    = (uint32_t)(ticks - 1UL);                         /* set reload register */
47     systick_hw->csr  = M0PLUS_SYST_CSR_CLKSOURCE_BITS |
48                    M0PLUS_SYST_CSR_TICKINT_BITS   |
49                    M0PLUS_SYST_CSR_ENABLE_BITS;                     /* Enable SysTick IRQ and SysTick Timer */
50     return (0UL);                                                     /* Function successful */
51 }
52 
rt_hw_board_init()53 void rt_hw_board_init()
54 {
55     set_sys_clock_khz(PLL_SYS_KHZ, true);
56 
57 #ifdef RT_USING_HEAP
58     rt_system_heap_init(HEAP_BEGIN, HEAP_END);
59 #endif
60 
61 #ifdef RT_USING_SMP
62     extern rt_hw_spinlock_t _cpus_lock;
63     rt_hw_spin_lock_init(&_cpus_lock);
64 #endif
65 
66     alarm_pool_init_default();
67 
68     // Start and end points of the constructor list,
69     // defined by the linker script.
70     extern void (*__init_array_start)();
71     extern void (*__init_array_end)();
72 
73     // Call each function in the list.
74     // We have to take the address of the symbols, as __init_array_start *is*
75     // the first function pointer, not the address of it.
76     for (void (**p)() = &__init_array_start; p < &__init_array_end; ++p)
77     {
78         (*p)();
79     }
80 
81     /* Configure the SysTick */
82     systick_config(clock_get_hz(clk_sys) / RT_TICK_PER_SECOND);
83 
84 #ifdef RT_USING_COMPONENTS_INIT
85     rt_components_board_init();
86 #endif
87 
88 #ifdef RT_USING_SERIAL
89     stdio_init_all();
90     rt_hw_uart_init();
91 #endif
92 
93 #ifdef RT_USING_CONSOLE
94     rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
95 #endif
96 }
97 
98 #ifdef RT_USING_MSH
pico_reboot(int argc,char * argv[])99 static int pico_reboot(int argc, char *argv[])
100 {
101     reset_usb_boot(0, 0);
102     return 0;
103 }
104 MSH_CMD_EXPORT_ALIAS(pico_reboot, reboot, reset Pico to BOOTSEL mode);
105 #endif
106