Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for RP2040 and BTT SKR Pico (WIP) #24042

Open
wants to merge 1 commit into
base: bugfix-2.1.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci-build-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ jobs:
matrix:
test-platform:

# RP2040
- SKR_Pico

# Native
- linux_native
- simulator_linux_release
Expand Down
188 changes: 188 additions & 0 deletions Marlin/src/HAL/RP2040/HAL.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../platforms.h"

#ifdef __PLAT_RP2040__

#include "HAL.h"
//#include "usb_serial.h"

#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"

extern "C" {
#include "pico/bootrom.h"
#include "hardware/watchdog.h"
}

#if HAS_SD_HOST_DRIVE
#include "msc_sd.h"
#include "usbd_cdc_if.h"
#endif

// ------------------------
// Public Variables
// ------------------------

volatile uint16_t adc_result;

// ------------------------
// Public functions
// ------------------------

TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());

// HAL initialization task
void MarlinHAL::init() {
// Ensure F_CPU is a constant expression.
// If the compiler breaks here, it means that delay code that should compute at compile time will not work.
// So better safe than sorry here.
constexpr int cpuFreq = F_CPU;
UNUSED(cpuFreq);

#undef SDSS
#define SDSS 2
#define PIN_EXISTS_(P1,P2) (defined(P1##P2) && P1##P2 >= 0)
#if HAS_MEDIA && DISABLED(SDIO_SUPPORT) && PIN_EXISTS_(SDSS,)
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
#endif

#if PIN_EXISTS(LED)
OUT_WRITE(LED_PIN, LOW);
#endif

#if ENABLED(SRAM_EEPROM_EMULATION)
// __HAL_RCC_PWR_CLK_ENABLE();
// HAL_PWR_EnableBkUpAccess(); // Enable access to backup SRAM
// __HAL_RCC_BKPSRAM_CLK_ENABLE();
// LL_PWR_EnableBkUpRegulator(); // Enable backup regulator
// while (!LL_PWR_IsActiveFlag_BRR()); // Wait until backup regulator is initialized
#endif

HAL_timer_init();

#if ENABLED(EMERGENCY_PARSER) && USBD_USE_CDC
USB_Hook_init();
#endif

TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler

TERN_(HAS_SD_HOST_DRIVE, MSC_SD_init()); // Enable USB SD card access

#if PIN_EXISTS(USB_CONNECT)
OUT_WRITE(USB_CONNECT_PIN, !USB_CONNECT_INVERTING); // USB clear connection
delay_ms(1000); // Give OS time to notice
WRITE(USB_CONNECT_PIN, USB_CONNECT_INVERTING);
#endif
}

uint8_t MarlinHAL::get_reset_source() {
return watchdog_enable_caused_reboot() ? RST_WATCHDOG : 0;
}

void MarlinHAL::reboot() { watchdog_reboot(0, 0, 1); }

// ------------------------
// Watchdog Timer
// ------------------------

#if ENABLED(USE_WATCHDOG)

#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout

extern "C" {
#include "hardware/watchdog.h"
}

void MarlinHAL::watchdog_init() {
#if DISABLED(DISABLE_WATCHDOG_INIT)
static_assert(WDT_TIMEOUT_US > 1000, "WDT Timout is too small, aborting");
watchdog_enable(WDT_TIMEOUT_US/1000, true);
#endif
}

void MarlinHAL::watchdog_refresh() {
watchdog_update();
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
TOGGLE(LED_PIN); // heartbeat indicator
#endif
}

#endif

// ------------------------
// ADC
// ------------------------

volatile bool MarlinHAL::adc_has_result = false;

void MarlinHAL::adc_init() {
analogReadResolution(HAL_ADC_RESOLUTION);
::adc_init();
adc_fifo_setup(true, false, 1, false, false);
irq_set_exclusive_handler(ADC_IRQ_FIFO, adc_exclusive_handler);
irq_set_enabled(ADC_IRQ_FIFO, true);
adc_irq_set_enabled(true);
}

void MarlinHAL::adc_enable(const pin_t pin) {
if (pin >= A0 && pin <= A3)
adc_gpio_init(pin);
else if (pin == HAL_ADC_MCU_TEMP_DUMMY_PIN)
adc_set_temp_sensor_enabled(true);
}

void MarlinHAL::adc_start(const pin_t pin) {
adc_has_result = false;
// Select an ADC input. 0...3 are GPIOs 26...29 respectively.
adc_select_input(pin == HAL_ADC_MCU_TEMP_DUMMY_PIN ? 4 : pin - A0);
adc_run(true);
}

void MarlinHAL::adc_exclusive_handler() {
adc_run(false); // Disable since we only want one result
irq_clear(ADC_IRQ_FIFO); // Clear the IRQ

if (adc_fifo_get_level() >= 1) {
adc_result = adc_fifo_get(); // Pop the result
adc_fifo_drain();
adc_has_result = true; // Signal the end of the conversion
}
}

uint16_t MarlinHAL::adc_value() { return adc_result; }

// Reset the system to initiate a firmware flash
void flashFirmware(const int16_t) { hal.reboot(); }

extern "C" {
void * _sbrk(int incr);
extern unsigned int __bss_end__; // end of bss section
}

// Return free memory between end of heap (or end bss) and whatever is current
int freeMemory() {
int free_memory, heap_end = (int)_sbrk(0);
return (int)&free_memory - (heap_end ?: (int)&__bss_end__);
}

#endif // __PLAT_RP2040__
Loading
Loading