253 lines
12 KiB
C
253 lines
12 KiB
C
/**
|
|
* Marlin 3D Printer Firmware
|
|
*
|
|
* Copyright (c) 2019 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 <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
#pragma once
|
|
|
|
/**
|
|
* Fast IO functions for SAMD51
|
|
*/
|
|
|
|
#include "SAMD51.h"
|
|
|
|
/**
|
|
* Utility functions
|
|
*/
|
|
|
|
#ifndef MASK
|
|
#define MASK(PIN) (1 << PIN)
|
|
#endif
|
|
|
|
/**
|
|
* Magic I/O routines
|
|
*
|
|
* Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, 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].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_INEN); \
|
|
PORT->Group[port].DIRSET.reg = MASK(pin); \
|
|
}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(IO) SET_OUTPUT(IO)
|
|
// Set pin as PWM (open drain)
|
|
#define SET_PWM_OD(IO) SET_OUTPUT_OD(IO)
|
|
|
|
// 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 DIO22_PIN PIN_PD12
|
|
#define DIO6_PIN PIN_PD20
|
|
#define DIO7_PIN PIN_PD21
|
|
|
|
#endif // ADAFRUIT_GRAND_CENTRAL_M4
|