Skip to content

Commit 3cf5a4a

Browse files
committed
✨ RP2040 support
1 parent aa44542 commit 3cf5a4a

40 files changed

+3060
-6
lines changed

.github/workflows/ci-build-tests.yml

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ jobs:
4141
matrix:
4242
test-platform:
4343

44+
# RP2040
45+
- SKR_Pico
46+
4447
# Native
4548
- linux_native
4649
- simulator_linux_release

Marlin/src/HAL/RP2040/HAL.cpp

+188
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/**
2+
* Marlin 3D Printer Firmware
3+
* Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4+
*
5+
* Based on Sprinter and grbl.
6+
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation, either version 3 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
20+
*
21+
*/
22+
#include "../platforms.h"
23+
24+
#ifdef __PLAT_RP2040__
25+
26+
#include "HAL.h"
27+
//#include "usb_serial.h"
28+
29+
#include "../../inc/MarlinConfig.h"
30+
#include "../shared/Delay.h"
31+
32+
extern "C" {
33+
#include "pico/bootrom.h"
34+
#include "hardware/watchdog.h"
35+
}
36+
37+
#if HAS_SD_HOST_DRIVE
38+
#include "msc_sd.h"
39+
#include "usbd_cdc_if.h"
40+
#endif
41+
42+
// ------------------------
43+
// Public Variables
44+
// ------------------------
45+
46+
volatile uint16_t adc_result;
47+
48+
// ------------------------
49+
// Public functions
50+
// ------------------------
51+
52+
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
53+
54+
// HAL initialization task
55+
void MarlinHAL::init() {
56+
// Ensure F_CPU is a constant expression.
57+
// If the compiler breaks here, it means that delay code that should compute at compile time will not work.
58+
// So better safe than sorry here.
59+
constexpr int cpuFreq = F_CPU;
60+
UNUSED(cpuFreq);
61+
62+
#undef SDSS
63+
#define SDSS 2
64+
#define PIN_EXISTS_(P1,P2) (defined(P1##P2) && P1##P2 >= 0)
65+
#if HAS_MEDIA && DISABLED(SDIO_SUPPORT) && PIN_EXISTS_(SDSS,)
66+
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
67+
#endif
68+
69+
#if PIN_EXISTS(LED)
70+
OUT_WRITE(LED_PIN, LOW);
71+
#endif
72+
73+
#if ENABLED(SRAM_EEPROM_EMULATION)
74+
// __HAL_RCC_PWR_CLK_ENABLE();
75+
// HAL_PWR_EnableBkUpAccess(); // Enable access to backup SRAM
76+
// __HAL_RCC_BKPSRAM_CLK_ENABLE();
77+
// LL_PWR_EnableBkUpRegulator(); // Enable backup regulator
78+
// while (!LL_PWR_IsActiveFlag_BRR()); // Wait until backup regulator is initialized
79+
#endif
80+
81+
HAL_timer_init();
82+
83+
#if ENABLED(EMERGENCY_PARSER) && USBD_USE_CDC
84+
USB_Hook_init();
85+
#endif
86+
87+
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
88+
89+
TERN_(HAS_SD_HOST_DRIVE, MSC_SD_init()); // Enable USB SD card access
90+
91+
#if PIN_EXISTS(USB_CONNECT)
92+
OUT_WRITE(USB_CONNECT_PIN, !USB_CONNECT_INVERTING); // USB clear connection
93+
delay_ms(1000); // Give OS time to notice
94+
WRITE(USB_CONNECT_PIN, USB_CONNECT_INVERTING);
95+
#endif
96+
}
97+
98+
uint8_t MarlinHAL::get_reset_source() {
99+
return watchdog_enable_caused_reboot() ? RST_WATCHDOG : 0;
100+
}
101+
102+
void MarlinHAL::reboot() { watchdog_reboot(0, 0, 1); }
103+
104+
// ------------------------
105+
// Watchdog Timer
106+
// ------------------------
107+
108+
#if ENABLED(USE_WATCHDOG)
109+
110+
#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
111+
112+
extern "C" {
113+
#include "hardware/watchdog.h"
114+
}
115+
116+
void MarlinHAL::watchdog_init() {
117+
#if DISABLED(DISABLE_WATCHDOG_INIT)
118+
static_assert(WDT_TIMEOUT_US > 1000, "WDT Timout is too small, aborting");
119+
watchdog_enable(WDT_TIMEOUT_US/1000, true);
120+
#endif
121+
}
122+
123+
void MarlinHAL::watchdog_refresh() {
124+
watchdog_update();
125+
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
126+
TOGGLE(LED_PIN); // heartbeat indicator
127+
#endif
128+
}
129+
130+
#endif
131+
132+
// ------------------------
133+
// ADC
134+
// ------------------------
135+
136+
volatile bool MarlinHAL::adc_has_result = false;
137+
138+
void MarlinHAL::adc_init() {
139+
analogReadResolution(HAL_ADC_RESOLUTION);
140+
::adc_init();
141+
adc_fifo_setup(true, false, 1, false, false);
142+
irq_set_exclusive_handler(ADC_IRQ_FIFO, adc_exclusive_handler);
143+
irq_set_enabled(ADC_IRQ_FIFO, true);
144+
adc_irq_set_enabled(true);
145+
}
146+
147+
void MarlinHAL::adc_enable(const pin_t pin) {
148+
if (pin >= A0 && pin <= A3)
149+
adc_gpio_init(pin);
150+
else if (pin == HAL_ADC_MCU_TEMP_DUMMY_PIN)
151+
adc_set_temp_sensor_enabled(true);
152+
}
153+
154+
void MarlinHAL::adc_start(const pin_t pin) {
155+
adc_has_result = false;
156+
// Select an ADC input. 0...3 are GPIOs 26...29 respectively.
157+
adc_select_input(pin == HAL_ADC_MCU_TEMP_DUMMY_PIN ? 4 : pin - A0);
158+
adc_run(true);
159+
}
160+
161+
void MarlinHAL::adc_exclusive_handler() {
162+
adc_run(false); // Disable since we only want one result
163+
irq_clear(ADC_IRQ_FIFO); // Clear the IRQ
164+
165+
if (adc_fifo_get_level() >= 1) {
166+
adc_result = adc_fifo_get(); // Pop the result
167+
adc_fifo_drain();
168+
adc_has_result = true; // Signal the end of the conversion
169+
}
170+
}
171+
172+
uint16_t MarlinHAL::adc_value() { return adc_result; }
173+
174+
// Reset the system to initiate a firmware flash
175+
void flashFirmware(const int16_t) { hal.reboot(); }
176+
177+
extern "C" {
178+
void * _sbrk(int incr);
179+
extern unsigned int __bss_end__; // end of bss section
180+
}
181+
182+
// Return free memory between end of heap (or end bss) and whatever is current
183+
int freeMemory() {
184+
int free_memory, heap_end = (int)_sbrk(0);
185+
return (int)&free_memory - (heap_end ?: (int)&__bss_end__);
186+
}
187+
188+
#endif // __PLAT_RP2040__

0 commit comments

Comments
 (0)