Files
beyon-motion/TMC2209/lib/tmc/hal/Landungsbruecke/tmc/IOs.c
2026-03-31 13:10:37 +02:00

235 lines
6.0 KiB
C

/*******************************************************************************
* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG
* (now owned by Analog Devices Inc.),
*
* Copyright © 2023 Analog Devices Inc. All Rights Reserved. This software is
* proprietary & confidential to Analog Devices, Inc. and its licensors.
*******************************************************************************/
#include "hal/HAL.h"
#include "hal/IOs.h"
static void init();
static void setPinConfiguration(IOPinTypeDef *pin);
static void copyPinConfiguration(IOPinInitTypeDef *from, IOPinTypeDef*to);
static void resetPinConfiguration(IOPinTypeDef *pin);
static void setPin2Output(IOPinTypeDef *pin);
static void setPin2Input(IOPinTypeDef *pin);
static void setPinHigh(IOPinTypeDef *pin);
static void setPinLow(IOPinTypeDef *pin);
static void setPinState(IOPinTypeDef *pin, IO_States state);
static IO_States getPinState(IOPinTypeDef *pin);
static uint8_t isPinHigh(IOPinTypeDef *pin);
IOsTypeDef IOs =
{
.init = init,
.set = setPinConfiguration,
.reset = resetPinConfiguration,
.copy = copyPinConfiguration,
.toOutput = setPin2Output,
.toInput = setPin2Input,
.setHigh = setPinHigh,
.setLow = setPinLow,
.setToState = setPinState,
.getState = getPinState,
.isHigh = isPinHigh
};
static void init()
{
// Set the Clock divider for core/system clock
// 96 MHz / 2 = 48 MHz
SIM_CLKDIV1 |= SIM_CLKDIV1_OUTDIV1(1);
SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK| SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK |SIM_SCGC5_PORTD_MASK);
// Ausgabe des 16Mhz Taktes auf den CLK16 Pin
SIM_SOPT2 &= ~SIM_SOPT2_CLKOUTSEL_MASK;
SIM_SOPT2 |= SIM_SOPT2_CLKOUTSEL(6);
PORTC_PCR3 = PORT_PCR_MUX(5);
}
static void setPinConfiguration(IOPinTypeDef *pin)
{
if(IS_DUMMY_PIN(pin))
return;
uint32_t config = 0;
switch(pin->configuration.GPIO_Mode)
{
case GPIO_Mode_IN:
GPIO_PDD_SetPortInputDirectionMask(pin->GPIOBase, pin->bitWeight);
config |= PORT_PCR_MUX(1);
break;
case GPIO_Mode_OUT:
GPIO_PDD_SetPortOutputDirectionMask(pin->GPIOBase, pin->bitWeight);
config |= PORT_PCR_MUX(1);
break;
case GPIO_Mode_AN: config |= PORT_PCR_MUX(0); break;
case GPIO_Mode_AF1: config |= PORT_PCR_MUX(1); break;
case GPIO_Mode_AF2: config |= PORT_PCR_MUX(2); break;
case GPIO_Mode_AF3: config |= PORT_PCR_MUX(3); break;
case GPIO_Mode_AF4: config |= PORT_PCR_MUX(4); break;
case GPIO_Mode_AF5: config |= PORT_PCR_MUX(5); break;
case GPIO_Mode_AF6: config |= PORT_PCR_MUX(6); break;
case GPIO_Mode_AF7: config |= PORT_PCR_MUX(7); break;
}
switch(pin->configuration.GPIO_OType)
{
case GPIO_OType_PP:
break;
case GPIO_OType_OD:
config |= PORT_PCR_ODE_MASK; // enable open drain
break;
}
switch(pin->configuration.GPIO_Speed) // die Auswahl der Frequenz bewirkt keine Änderung
{
case GPIO_Speed_2MHz: break;
case GPIO_Speed_25MHz: break;
case GPIO_Speed_50MHz: break;
case GPIO_Speed_100MHz: break;
}
switch(pin->configuration.GPIO_PuPd)
{
case GPIO_PuPd_NOPULL:
config &= ~PORT_PCR_PE_MASK;
break;
case GPIO_PuPd_UP:
config |= PORT_PCR_PE_MASK;
config |= PORT_PCR_PS_MASK;
break;
case GPIO_PuPd_DOWN:
config |= PORT_PCR_PE_MASK;
config &= ~(PORT_PCR_PS_MASK);
break;
}
PORT_PCR_REG(pin->portBase, pin->bit) = config;
}
static void setPin2Output(IOPinTypeDef *pin)
{
if(IS_DUMMY_PIN(pin))
return;
pin->configuration.GPIO_Mode = GPIO_Mode_OUT;
setPinConfiguration(pin);
}
static void setPin2Input(IOPinTypeDef *pin)
{
if(IS_DUMMY_PIN(pin))
return;
pin->configuration.GPIO_Mode = GPIO_Mode_IN;
setPinConfiguration(pin);
}
static void setPinState(IOPinTypeDef *pin, IO_States state)
{
if(IS_DUMMY_PIN(pin))
return;
switch(state)
{
case IOS_LOW:
pin->configuration.GPIO_Mode = GPIO_Mode_OUT;
pin->configuration.GPIO_PuPd = GPIO_PuPd_NOPULL;
pin->configuration.GPIO_OType = GPIO_OType_PP;
setPinConfiguration(pin);
*pin->resetBitRegister = pin->bitWeight;
break;
case IOS_HIGH:
pin->configuration.GPIO_Mode = GPIO_Mode_OUT;
pin->configuration.GPIO_PuPd = GPIO_PuPd_NOPULL;
pin->configuration.GPIO_OType = GPIO_OType_PP;
setPinConfiguration(pin);
*pin->setBitRegister = pin->bitWeight;
break;
case IOS_OPEN:
pin->configuration.GPIO_Mode = GPIO_Mode_AN;
setPinConfiguration(pin);
break;
case IOS_NOCHANGE:
break;
}
pin->state = state;
setPinConfiguration(pin);
}
static IO_States getPinState(IOPinTypeDef *pin)
{
if(IS_DUMMY_PIN(pin))
return IOS_OPEN;
if(pin->configuration.GPIO_Mode == GPIO_Mode_AN)
pin->state = IOS_OPEN;
else if(GPIO_PDIR_REG(pin->GPIOBase) & pin->bitWeight)
pin->state = IOS_HIGH;
else
pin->state = IOS_LOW;
return pin->state;
}
static void setPinHigh(IOPinTypeDef *pin)
{
if(IS_DUMMY_PIN(pin))
return;
*pin->setBitRegister = pin->bitWeight;
pin->state = IOS_HIGH;
}
static void setPinLow(IOPinTypeDef *pin)
{
if(IS_DUMMY_PIN(pin))
return;
*pin->resetBitRegister = pin->bitWeight;
pin->state = IOS_LOW;
}
static uint8_t isPinHigh(IOPinTypeDef *pin) // Die Abfrage eines Pins funktioniert nur, wenn der Pin AF1 ist
{
if(IS_DUMMY_PIN(pin))
return -1;
return (GPIO_PDIR_REG(pin->GPIOBase) & pin->bitWeight)? 1 : 0;
}
static void copyPinConfiguration(IOPinInitTypeDef *from, IOPinTypeDef *to)
{
if(IS_DUMMY_PIN(to))
return;
to->configuration.GPIO_Mode = from->GPIO_Mode;
to->configuration.GPIO_OType = from->GPIO_OType;
to->configuration.GPIO_PuPd = from->GPIO_PuPd;
to->configuration.GPIO_Speed = from->GPIO_Speed;
setPinConfiguration(to);
}
static void resetPinConfiguration(IOPinTypeDef *pin)
{
if(IS_DUMMY_PIN(pin))
return;
copyPinConfiguration(&(pin->resetConfiguration), pin);
// Extra Reset Konfiguration für CLK16
if(pin == &IOMap.CLK16)
{
SIM_SOPT2 &= ~SIM_SOPT2_CLKOUTSEL_MASK;
SIM_SOPT2 |= SIM_SOPT2_CLKOUTSEL(6);
PORTC_PCR3 = PORT_PCR_MUX(5);
}
}