235 lines
6.0 KiB
C
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);
|
|
}
|
|
}
|
|
|