237 lines
6.7 KiB
C++
237 lines
6.7 KiB
C++
#pragma once
|
|
|
|
// pico_shim.h — pico-sdk replacements for Arduino primitives
|
|
// Used by cs-midi, extracted from tttapa/Control-Surface (GPL-3.0)
|
|
|
|
#include <cstdint>
|
|
#include <cstddef>
|
|
#include <cstring>
|
|
#include <cstdlib>
|
|
#include <cmath>
|
|
#include <cstdio>
|
|
|
|
#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<const __FlashStringHelper *>(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<const char *>(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 <class T>
|
|
size_t println(T v) { size_t n = print(v); return n + println(); }
|
|
template <class T>
|
|
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()
|