diff options
Diffstat (limited to 'Marlin/src/HAL/SAMD51/fastio.h')
-rw-r--r-- | Marlin/src/HAL/SAMD51/fastio.h | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/Marlin/src/HAL/SAMD51/fastio.h b/Marlin/src/HAL/SAMD51/fastio.h new file mode 100644 index 0000000..a95b7ca --- /dev/null +++ b/Marlin/src/HAL/SAMD51/fastio.h @@ -0,0 +1,253 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) + * + * 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/>. + * + */ +#pragma once + +/** + * Fast IO functions for SAMD51 + */ + +#include "SAMD51.h" + +/** + * Utility functions + */ + +#ifndef MASK + #define MASK(PIN) _BV(PIN) +#endif + +/** + * Magic I/O routines + * + * Now you can simply SET_OUTPUT(IO); WRITE(IO, HIGH); WRITE(IO, LOW); + */ + +// Read a pin +#define READ(IO) ((PORT->Group[(EPortType)GET_SAMD_PORT(IO)].IN.reg & MASK(GET_SAMD_PIN(IO))) != 0) + +// Write to a pin +#define WRITE(IO,V) do{ \ + const EPortType port = (EPortType)GET_SAMD_PORT(IO); \ + const uint32_t mask = MASK(GET_SAMD_PIN(IO)); \ + \ + if (V) PORT->Group[port].OUTSET.reg = mask; \ + else PORT->Group[port].OUTCLR.reg = mask; \ + }while(0) + +// Toggle a pin +#define TOGGLE(IO) PORT->Group[(EPortType)GET_SAMD_PORT(IO)].OUTTGL.reg = MASK(GET_SAMD_PIN(IO)); + +// Set pin as input +#define SET_INPUT(IO) do{ \ + const EPortType port = (EPortType)GET_SAMD_PORT(IO); \ + const uint32_t pin = GET_SAMD_PIN(IO); \ + \ + PORT->Group[port].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_INEN); \ + PORT->Group[port].DIRCLR.reg = MASK(pin); \ + }while(0) +// Set pin as input with pullup +#define SET_INPUT_PULLUP(IO) do{ \ + const EPortType port = (EPortType)GET_SAMD_PORT(IO); \ + const uint32_t pin = GET_SAMD_PIN(IO); \ + const uint32_t mask = MASK(pin); \ + \ + PORT->Group[port].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_INEN | PORT_PINCFG_PULLEN); \ + PORT->Group[port].DIRCLR.reg = mask; \ + PORT->Group[port].OUTSET.reg = mask; \ + }while(0) +// Set pin as input with pulldown +#define SET_INPUT_PULLDOWN(IO) do{ \ + const EPortType port = (EPortType)GET_SAMD_PORT(IO); \ + const uint32_t pin = GET_SAMD_PIN(IO); \ + const uint32_t mask = MASK(pin); \ + \ + PORT->Group[port].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_INEN | PORT_PINCFG_PULLEN); \ + PORT->Group[port].DIRCLR.reg = mask; \ + PORT->Group[port].OUTCLR.reg = mask; \ + }while(0) +// Set pin as output (push pull) +#define SET_OUTPUT(IO) do{ \ + const EPortType port = (EPortType)GET_SAMD_PORT(IO); \ + const uint32_t pin = GET_SAMD_PIN(IO); \ + \ + PORT->Group[port].DIRSET.reg = MASK(pin); \ + PORT->Group[port].PINCFG[pin].reg = 0; \ + }while(0) +// Set pin as output (open drain) +#define SET_OUTPUT_OD(IO) do{ \ + const EPortType port = (EPortType)GET_SAMD_PORT(IO); \ + const uint32_t pin = GET_SAMD_PIN(IO); \ + \ + PORT->Group[port].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_PULLEN); \ + PORT->Group[port].DIRCLR.reg = MASK(pin); \ + }while(0) +// Set pin as PWM (push pull) +#define SET_PWM SET_OUTPUT +// Set pin as PWM (open drain) +#define SET_PWM_OD SET_OUTPUT_OD + +// check if pin is an output +#define IS_OUTPUT(IO) ((PORT->Group[(EPortType)GET_SAMD_PORT(IO)].DIR.reg & MASK(GET_SAMD_PIN(IO))) \ + || (PORT->Group[(EPortType)GET_SAMD_PORT(IO)].PINCFG[GET_SAMD_PIN(IO)].reg & (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN)) == PORT_PINCFG_PULLEN) +// check if pin is an input +#define IS_INPUT(IO) !IS_OUTPUT(IO) + +// Shorthand +#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0) +#define OUT_WRITE_OD(IO,V) do{ SET_OUTPUT_OD(IO); WRITE(IO,V); }while(0) + +// digitalRead/Write wrappers +#define extDigitalRead(IO) digitalRead(IO) +#define extDigitalWrite(IO,V) digitalWrite(IO,V) + +/** + * Ports and functions + * Added as necessary or if I feel like it- not a comprehensive list! + */ + +#ifdef ADAFRUIT_GRAND_CENTRAL_M4 + + /* + * Adafruit Grand Central M4 has a lot of PWMs the availables are listed here. + * Some of these share the same source and so can't be used in the same time + */ + #define PWM_PIN(P) (WITHIN(P, 2, 13) || WITHIN(P, 22, 23) || WITHIN(P, 44, 45) || P == 48) + + // Return fullfilled ADCx->INPUTCTRL.reg + #define PIN_TO_INPUTCTRL(P) ( (PIN_TO_AIN(P) == 0) ? ADC_INPUTCTRL_MUXPOS_AIN0 \ + : (PIN_TO_AIN(P) == 1) ? ADC_INPUTCTRL_MUXPOS_AIN1 \ + : (PIN_TO_AIN(P) == 2) ? ADC_INPUTCTRL_MUXPOS_AIN2 \ + : (PIN_TO_AIN(P) == 3) ? ADC_INPUTCTRL_MUXPOS_AIN3 \ + : (PIN_TO_AIN(P) == 4) ? ADC_INPUTCTRL_MUXPOS_AIN4 \ + : (PIN_TO_AIN(P) == 5) ? ADC_INPUTCTRL_MUXPOS_AIN5 \ + : (PIN_TO_AIN(P) == 6) ? ADC_INPUTCTRL_MUXPOS_AIN6 \ + : (PIN_TO_AIN(P) == 7) ? ADC_INPUTCTRL_MUXPOS_AIN7 \ + : (PIN_TO_AIN(P) == 8) ? ADC_INPUTCTRL_MUXPOS_AIN8 \ + : (PIN_TO_AIN(P) == 9) ? ADC_INPUTCTRL_MUXPOS_AIN9 \ + : (PIN_TO_AIN(P) == 10) ? ADC_INPUTCTRL_MUXPOS_AIN10 \ + : (PIN_TO_AIN(P) == 11) ? ADC_INPUTCTRL_MUXPOS_AIN11 \ + : (PIN_TO_AIN(P) == 12) ? ADC_INPUTCTRL_MUXPOS_AIN12 \ + : (PIN_TO_AIN(P) == 13) ? ADC_INPUTCTRL_MUXPOS_AIN13 \ + : (PIN_TO_AIN(P) == 14) ? ADC_INPUTCTRL_MUXPOS_AIN14 \ + : ADC_INPUTCTRL_MUXPOS_AIN15) + + #define ANAPIN_TO_SAMDPIN(P) ( (P == 0) ? PIN_TO_SAMD_PIN(67) \ + : (P == 1) ? PIN_TO_SAMD_PIN(68) \ + : (P == 2) ? PIN_TO_SAMD_PIN(69) \ + : (P == 3) ? PIN_TO_SAMD_PIN(70) \ + : (P == 4) ? PIN_TO_SAMD_PIN(71) \ + : (P == 5) ? PIN_TO_SAMD_PIN(72) \ + : (P == 6) ? PIN_TO_SAMD_PIN(73) \ + : (P == 7) ? PIN_TO_SAMD_PIN(74) \ + : (P == 8) ? PIN_TO_SAMD_PIN(54) \ + : (P == 9) ? PIN_TO_SAMD_PIN(55) \ + : (P == 10) ? PIN_TO_SAMD_PIN(56) \ + : (P == 11) ? PIN_TO_SAMD_PIN(57) \ + : (P == 12) ? PIN_TO_SAMD_PIN(58) \ + : (P == 13) ? PIN_TO_SAMD_PIN(59) \ + : (P == 14) ? PIN_TO_SAMD_PIN(60) \ + : (P == 15) ? PIN_TO_SAMD_PIN(61) \ + : (P == 16) ? PIN_TO_SAMD_PIN(12) \ + : (P == 17) ? PIN_TO_SAMD_PIN(13) \ + : PIN_TO_SAMD_PIN(9)) + + #define digitalPinToAnalogInput(P) (WITHIN(P, 67, 74) ? (P) - 67 : WITHIN(P, 54, 61) ? 8 + (P) - 54 : WITHIN(P, 12, 13) ? 16 + (P) - 12 : P == 9 ? 18 : -1) + + /* + * pins + */ + + // PORTA + #define DIO67_PIN PIN_PA02 // A0 + #define DIO59_PIN PIN_PA04 // A13 + #define DIO68_PIN PIN_PA05 // A1 + #define DIO60_PIN PIN_PA06 // A14 + #define DIO61_PIN PIN_PA07 // A15 + #define DIO26_PIN PIN_PA12 + #define DIO27_PIN PIN_PA13 + #define DIO28_PIN PIN_PA14 + #define DIO23_PIN PIN_PA15 + #define DIO37_PIN PIN_PA16 + #define DIO36_PIN PIN_PA17 + #define DIO35_PIN PIN_PA18 + #define DIO34_PIN PIN_PA19 + #define DIO33_PIN PIN_PA20 + #define DIO32_PIN PIN_PA21 + #define DIO31_PIN PIN_PA22 + #define DIO30_PIN PIN_PA23 + // PORTB + #define DIO12_PIN PIN_PB00 // A16 + #define DIO13_PIN PIN_PB01 // A17 + #define DIO9_PIN PIN_PB02 // A18 + #define DIO69_PIN PIN_PB03 // A2 + #define DIO74_PIN PIN_PB04 // A7 + #define DIO54_PIN PIN_PB05 // A8 + #define DIO55_PIN PIN_PB06 // A9 + #define DIO56_PIN PIN_PB07 // A10 + #define DIO57_PIN PIN_PB08 // A11 + #define DIO58_PIN PIN_PB09 // A12 + #define DIO18_PIN PIN_PB12 + #define DIO19_PIN PIN_PB13 + #define DIO39_PIN PIN_PB14 + #define DIO38_PIN PIN_PB15 + #define DIO14_PIN PIN_PB16 + #define DIO15_PIN PIN_PB17 + #define DIO8_PIN PIN_PB18 + #define DIO29_PIN PIN_PB19 + #define DIO20_PIN PIN_PB20 + #define DIO21_PIN PIN_PB21 + #define DIO10_PIN PIN_PB22 + #define DIO11_PIN PIN_PB23 + #define DIO1_PIN PIN_PB24 + #define DIO0_PIN PIN_PB25 + #define DIO83_PIN PIN_PB28 // SD_CS + #define DIO95_PIN PIN_PB31 // SD_CD + // PORTC + #define DIO70_PIN PIN_PC00 // A3 + #define DIO71_PIN PIN_PC01 // A4 + #define DIO72_PIN PIN_PC02 // A5 + #define DIO73_PIN PIN_PC03 // A6 + #define DIO48_PIN PIN_PC04 + #define DIO49_PIN PIN_PC05 + #define DIO46_PIN PIN_PC06 + #define DIO47_PIN PIN_PC07 + #define DIO45_PIN PIN_PC10 + #define DIO44_PIN PIN_PC11 + #define DIO41_PIN PIN_PC12 + #define DIO40_PIN PIN_PC13 + #define DIO43_PIN PIN_PC14 + #define DIO42_PIN PIN_PC15 + #define DIO25_PIN PIN_PC16 + #define DIO24_PIN PIN_PC17 + #define DIO2_PIN PIN_PC18 + #define DIO3_PIN PIN_PC19 + #define DIO4_PIN PIN_PC20 + #define DIO5_PIN PIN_PC21 + #define DIO16_PIN PIN_PC22 + #define DIO17_PIN PIN_PC23 + #define DIO88_PIN PIN_PC24 // NEOPIXEL + // PORTD + #define DIO53_PIN PIN_PD10 + #define DIO22_PIN PIN_PD12 + #define DIO6_PIN PIN_PD20 + #define DIO7_PIN PIN_PD21 + +#endif // ADAFRUIT_GRAND_CENTRAL_M4 |