|
|
|
@ -1,3 +1,25 @@
|
|
|
|
|
/**
|
|
|
|
|
**************************************************************************************************
|
|
|
|
|
* @file pin.c
|
|
|
|
|
* @author Kerem Yollu & Edwin Koch
|
|
|
|
|
* @date 02.11.2021
|
|
|
|
|
* @version 1.0
|
|
|
|
|
**************************************************************************************************
|
|
|
|
|
* @brief Implementation of pin.h for the STM32F042K6 MCU
|
|
|
|
|
*
|
|
|
|
|
* **Detailed Description :**
|
|
|
|
|
*
|
|
|
|
|
* This source code uses bit manipulation in order to minimise the footprint of pin initialisation
|
|
|
|
|
* and manipulation. It's based on the CMSIS/Device/ST/STM32F0xx/Include/stm32f042x6.h Header file
|
|
|
|
|
* to get the obtain the right Registers.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @todo
|
|
|
|
|
* - 01.11.2021 : Should we add a seprate header in the cls layer containing the pinNo_t ?
|
|
|
|
|
* - 01.11.2021 : Depending on request implment a pinLock() function
|
|
|
|
|
**************************************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "pin.h"
|
|
|
|
|
|
|
|
|
|
#define MODER_IN 0x0UL
|
|
|
|
@ -16,8 +38,10 @@
|
|
|
|
|
#define OTYPER_PUSH_PULL 0x0UL
|
|
|
|
|
#define OTYPER_OPEN_DRAIN 0x1UL
|
|
|
|
|
|
|
|
|
|
#define PIN_BASE ((GPIO_TypeDef *)(pinNo&~0xFF))
|
|
|
|
|
|
|
|
|
|
#define PIN_BASE ((GPIO_TypeDef *)(pinNo&~0xFF))
|
|
|
|
|
#define PIN_NO (pinNo & 0x0F)
|
|
|
|
|
#define PIN_PORT ((pinNo & 0xF0)>>4)
|
|
|
|
|
/*! Table for binding the Pin mode_t enum index to the values that the MODER register needs */
|
|
|
|
|
const uint32_t moderMode[5] = {
|
|
|
|
|
MODER_ANALOG,
|
|
|
|
|
MODER_IN,
|
|
|
|
@ -26,18 +50,27 @@ const uint32_t moderMode[5] = {
|
|
|
|
|
MODER_ALTERNATE
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Table for binding the Pin pinNo_t's Port Offet to the PORT gesiter that needs to be activated
|
|
|
|
|
*/
|
|
|
|
|
const uint32_t pinPort[3] = {
|
|
|
|
|
RCC_AHBENR_GPIOAEN,
|
|
|
|
|
RCC_AHBENR_GPIOBEN,
|
|
|
|
|
RCC_AHBENR_GPIOFEN
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Table for binding the Pin pullUpDown_t enum index to the values that the PUPDR register needs
|
|
|
|
|
*/
|
|
|
|
|
const uint32_t pinPullUpDown[3] = {
|
|
|
|
|
PUPDR_NO_PULL,
|
|
|
|
|
PUPDR_PULL_UP,
|
|
|
|
|
PUPDR_PULL_DOWN
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Table for binding the Pin speed_t enum index to the values that the OSPEEDR register needs
|
|
|
|
|
*/
|
|
|
|
|
const uint32_t speedList[4] = {
|
|
|
|
|
OSPEEDR_LOW,
|
|
|
|
|
OSPEEDR_LOW,
|
|
|
|
@ -45,6 +78,10 @@ const uint32_t speedList[4] = {
|
|
|
|
|
OSPEEDR_HIGH
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Table for binding the Pin stage_t enum index to the values that the OTYPER register needs
|
|
|
|
|
*/
|
|
|
|
|
const uint32_t outputStgeList[3] =
|
|
|
|
|
{
|
|
|
|
|
OTYPER_OPEN_DRAIN,
|
|
|
|
@ -55,29 +92,41 @@ const uint32_t outputStgeList[3] =
|
|
|
|
|
void pinSetMode(pinNo_t pinNo, mode_t mode)
|
|
|
|
|
{
|
|
|
|
|
//Clear entry.
|
|
|
|
|
PIN_BASE->MODER &=~ (0x3 << ((pinNo & 0x0F) * 2));
|
|
|
|
|
PIN_BASE->MODER &=~ (0x3 << (PIN_NO * 2));
|
|
|
|
|
//Set to corresponding mode.
|
|
|
|
|
PIN_BASE->MODER |= (moderMode[mode] << ((pinNo & 0x0F) * 2));
|
|
|
|
|
PIN_BASE->MODER |= (moderMode[mode] << (PIN_NO * 2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pinSetOutputStage(pinNo_t pinNo, stage_t stage)
|
|
|
|
|
{
|
|
|
|
|
PIN_BASE->OSPEEDR &= 1 << (pinNo & 0x0F);
|
|
|
|
|
PIN_BASE->OSPEEDR |= (outputStgeList[stage] << (pinNo & 0x0F));
|
|
|
|
|
PIN_BASE->OTYPER &= ~(1 << PIN_NO);
|
|
|
|
|
PIN_BASE->OTYPER |= (outputStgeList[stage] << PIN_NO);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pinSetPullUpDonw(pinNo_t pinNo, pullUpDown_t resistance)
|
|
|
|
|
{
|
|
|
|
|
PIN_BASE->PUPDR &= ~(0x3 << ((pinNo & 0x0F) * 2));
|
|
|
|
|
PIN_BASE->PUPDR |= (pinPullUpDown[resistance] << ((pinNo & 0x0F) * 2));
|
|
|
|
|
PIN_BASE->PUPDR &= ~(0x3 << (PIN_NO * 2));
|
|
|
|
|
PIN_BASE->PUPDR |= (pinPullUpDown[resistance] << (PIN_NO * 2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pinSetSpeed(pinNo_t pinNo, speed_t speed)
|
|
|
|
|
{
|
|
|
|
|
PIN_BASE->OSPEEDR &= (0x3 << ((pinNo & 0x0F) * 2));
|
|
|
|
|
PIN_BASE->OSPEEDR |= (speedList[speed] << ((pinNo & 0x0F) * 2));
|
|
|
|
|
PIN_BASE->OSPEEDR &= (0x3 << (PIN_NO * 2));
|
|
|
|
|
PIN_BASE->OSPEEDR |= (speedList[speed] << (PIN_NO * 2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pinSetAlternate(pinNo_t pinNo, uint16_t alternate)
|
|
|
|
|
{
|
|
|
|
|
if(PIN_NO > 7)
|
|
|
|
|
{
|
|
|
|
|
PIN_BASE->AFR[0] &= ~(0x0F << (PIN_NO * 2));
|
|
|
|
|
PIN_BASE->AFR[0] |= ((alternate & 0x0f) << (PIN_NO * 2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PIN_BASE->AFR[1] &= ~(0x0F << (PIN_NO * 2));
|
|
|
|
|
PIN_BASE->AFR[1] |= ((alternate & 0x0f) << (PIN_NO * 2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pinConfig(pinNo_t pinNo, mode_t mode, stage_t stage, pullUpDown_t resistance, speed_t speed)
|
|
|
|
|
{
|
|
|
|
|
pinInit(pinNo); //Very important to init first so that the corresponding bus gets his clock
|
|
|
|
@ -89,26 +138,26 @@ void pinConfig(pinNo_t pinNo, mode_t mode, stage_t stage, pullUpDown_t resistanc
|
|
|
|
|
|
|
|
|
|
uint8_t pinRead(pinNo_t pinNo)
|
|
|
|
|
{
|
|
|
|
|
return ((PIN_BASE->IDR & (1<<(pinNo & 0x0F))) >> (pinNo & 0x0F));
|
|
|
|
|
return ((PIN_BASE->IDR & (1<<PIN_NO)) >> PIN_NO);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pinToggle(pinNo_t pinNo)
|
|
|
|
|
{
|
|
|
|
|
if(pinRead(pinNo))
|
|
|
|
|
{
|
|
|
|
|
PIN_BASE->BSRR |= (GPIO_BSRR_BR_0 << ((pinNo & 0xF)));
|
|
|
|
|
PIN_BASE->BSRR |= (GPIO_BSRR_BR_0 << (PIN_NO));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
PIN_BASE->BSRR |= (GPIO_BSRR_BS_0 << ((pinNo & 0xF)));
|
|
|
|
|
PIN_BASE->BSRR |= (GPIO_BSRR_BS_0 << (PIN_NO));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pinWrite(pinNo_t pinNo, uint8_t state)
|
|
|
|
|
{
|
|
|
|
|
if(state) {
|
|
|
|
|
PIN_BASE->BSRR |= (GPIO_BSRR_BS_0 << ((pinNo & 0xF)));
|
|
|
|
|
PIN_BASE->BSRR |= (GPIO_BSRR_BS_0 << (PIN_NO));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
PIN_BASE->BSRR |= (GPIO_BSRR_BR_0 << ((pinNo & 0xF)));
|
|
|
|
|
PIN_BASE->BSRR |= (GPIO_BSRR_BR_0 << (PIN_NO));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Enable the pin port's clock
|
|
|
|
@ -117,7 +166,7 @@ void pinWrite(pinNo_t pinNo, uint8_t state)
|
|
|
|
|
//DS Page : 121
|
|
|
|
|
void pinInit(pinNo_t pinNo)
|
|
|
|
|
{
|
|
|
|
|
RCC->AHBENR |= pinPort[((pinNo & 0xF0)>>4)];
|
|
|
|
|
RCC->AHBENR |= pinPort[PIN_PORT];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//in this family of MCU ell the cloks are on the same bus that is why we dion't need to
|
|
|
|
@ -125,10 +174,15 @@ void pinInit(pinNo_t pinNo)
|
|
|
|
|
//DS Page : 121
|
|
|
|
|
void pinDeInit(pinNo_t pinNo)
|
|
|
|
|
{
|
|
|
|
|
RCC->AHBENR &=~(pinPort[((pinNo & 0xF0)>>4)]);
|
|
|
|
|
RCC->AHBENR &=~(pinPort[PIN_PORT]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void pinReset(pinNo_t pinNo)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pinHardwareInfo(pinNo_t pinNo)
|
|
|
|
|
{
|
|
|
|
|
//TODO : define where to print anh woh to print
|
|
|
|
|