#pragma once // pico_shim.h — pico-sdk replacements for Arduino primitives // Used by cs-midi, extracted from tttapa/Control-Surface (GPL-3.0) #include #include #include #include #include #include #include "pico/stdlib.h" #include "pico/time.h" #include "hardware/gpio.h" // --------------------------------------------------------------------------- // Number format bases (Arduino constants) // --------------------------------------------------------------------------- #define DEC 10 #define HEX 16 #define OCT 8 #define BIN 2 // --------------------------------------------------------------------------- // Time // --------------------------------------------------------------------------- static inline unsigned long millis() { return (unsigned long)to_ms_since_boot(get_absolute_time()); } static inline unsigned long micros() { return (unsigned long)to_us_since_boot(get_absolute_time()); } static inline void delay(unsigned long ms) { sleep_ms(ms); } // --------------------------------------------------------------------------- // Flash strings (identity on ARM — unified address space) // --------------------------------------------------------------------------- struct __FlashStringHelper; #define F(x) (reinterpret_cast(x)) using FlashString_t = const __FlashStringHelper *; #define PROGMEM #define pgm_read_byte_near(ptr) (*((const uint8_t *)(ptr))) #define pgm_read_ptr_near(ptr) ((void *)*(ptr)) // --------------------------------------------------------------------------- // Print / Printable // --------------------------------------------------------------------------- class Printable; class Print { public: virtual ~Print() = default; virtual size_t write(uint8_t) = 0; virtual size_t write(const uint8_t *buf, size_t len) { size_t n = 0; while (len--) n += write(*buf++); return n; } size_t write(const char *str) { if (!str) return 0; return write((const uint8_t *)str, std::strlen(str)); } virtual void flush() {} // print: strings size_t print(const __FlashStringHelper *s) { return write(reinterpret_cast(s)); } size_t print(const char *s) { return write(s); } size_t print(char c) { return write((uint8_t)c); } // print: integers size_t print(long n, int base = DEC) { if (base == DEC && n < 0) { size_t t = write('-'); return t + printUnsigned((unsigned long)(-n), base); } return printUnsigned((unsigned long)n, base); } size_t print(int n, int base = DEC) { return print((long)n, base); } size_t print(unsigned long n, int base = DEC) { return printUnsigned(n, base); } size_t print(unsigned int n, int base = DEC) { return print((unsigned long)n, base); } size_t print(unsigned char n, int base = DEC) { return print((unsigned long)n, base); } // print: float/double size_t print(double d, int prec = 2) { char buf[32]; std::snprintf(buf, sizeof(buf), "%.*f", prec, d); return write(buf); } // print: bool size_t print(bool b) { return print(b ? "true" : "false"); } // print: Printable size_t print(const Printable &p); // println size_t println() { return write("\r\n"); } template size_t println(T v) { size_t n = print(v); return n + println(); } template size_t println(T v, int fmt) { size_t n = print(v, fmt); return n + println(); } private: size_t printUnsigned(unsigned long n, int base) { char buf[8 * sizeof(long) + 1]; char *p = buf + sizeof(buf) - 1; *p = '\0'; if (n == 0) { *--p = '0'; } else { while (n > 0) { uint8_t d = n % base; *--p = d < 10 ? '0' + d : 'A' + d - 10; n /= base; } } return write(p); } }; class Printable { public: virtual ~Printable() = default; virtual size_t printTo(Print &p) const = 0; }; inline size_t Print::print(const Printable &p) { return p.printTo(*this); } // --------------------------------------------------------------------------- // Macros // --------------------------------------------------------------------------- #ifndef constrain #define constrain(amt, low, high) \ ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) #endif #define HIGH 0x1 #define LOW 0x0 #define INPUT 0x0 #define OUTPUT 0x1 #define INPUT_PULLUP 0x2 #define LED_BUILTIN 25 typedef bool boolean; // --------------------------------------------------------------------------- // GPIO — real implementations via pico-sdk // --------------------------------------------------------------------------- static inline void pinMode(uint8_t pin, uint8_t mode) { gpio_init(pin); if (mode == OUTPUT) gpio_set_dir(pin, GPIO_OUT); else { gpio_set_dir(pin, GPIO_IN); if (mode == INPUT_PULLUP) gpio_pull_up(pin); } } static inline void digitalWrite(uint8_t pin, uint8_t val) { gpio_put(pin, val); } static inline int digitalRead(uint8_t pin) { return gpio_get(pin) ? HIGH : LOW; } // --------------------------------------------------------------------------- // ADC // --------------------------------------------------------------------------- #include "hardware/adc.h" #define NUM_DIGITAL_PINS 48 #define NUM_ANALOG_INPUTS 8 static inline int analogRead(uint8_t pin) { // GPIO 26-29 = ADC 0-3 on RP2350 uint8_t ch = pin; if (pin >= 26) ch = pin - 26; adc_select_input(ch); return (int)adc_read(); } static inline void analogReadResolution(int) {} static inline void analogWrite(uint8_t, int) {} // --------------------------------------------------------------------------- // Shift register // --------------------------------------------------------------------------- #define MSBFIRST 1 #define LSBFIRST 0 static inline void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val) { for (uint8_t i = 0; i < 8; i++) { if (bitOrder == LSBFIRST) gpio_put(dataPin, (val >> i) & 1); else gpio_put(dataPin, (val >> (7 - i)) & 1); gpio_put(clockPin, 1); gpio_put(clockPin, 0); } } // --------------------------------------------------------------------------- // Misc // --------------------------------------------------------------------------- static inline void yield() {} static inline void cli() { __asm volatile("cpsid i"); } static inline void sei() { __asm volatile("cpsie i"); } #define noInterrupts() cli() #define interrupts() sei()