/**
  **************************************************************************************************
  * @file		pin.h
  * @author		Kerem Yollu & Edwin Koch
  * @date		01.11.2021
  * @version	1.0
  ************************************************************************************************** 
  * @brief		pin functionalities description and implementation template
  * 
  * **Detailed Description :**
  * 
  * This header file for pin control is based on the most common configuation options
  * curenty awailable for modern hardware. 
  * Depending of the used Chip, some function may vary or be unawailable. 
  * Please take a minute to go and explore the according Chips pin.c file to see woh each function 
  * is implmented.  
  *
  * @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
  **************************************************************************************************
*/

#ifndef _GPIO_H_
#define _GPIO_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
// include the target device definitions -> CMAKE chooses the correct file
#include "hardwareDescription.h"

#ifdef RASPBERRY
#endif

/*! Enum of possible Pin Modes */
typedef enum 
{
	def_mode,	/*!< Is the **default** mode */
	input,		/*!< Set pin as **Input** */
	output, 	/*!< Set pin as **Output** */
	analog, 	/*!< Set pin as **Analog** */
	alternate	/*!< Set pin as **Alternate** */
}pinMode_t;

/*! Enum of possible Outpout Stages */
typedef enum 
{
	def_stage,	/*!< Set ouput stage to **Default** */
	floating,	/*!< Set ouput stage to **Floating** */
	pushPull,	/*!< Set ouput stage to **Push Pull** */
	openDrain	/*!< Set ouput stage to **Open Drain** */
}pinStage_t;

/*! Enum for the internal Pull-Up/Down resistors */
typedef enum 
{
	def_res,	/*!< **Default** internal resistance */
	none,		/*!< **Disbales** internal resistance */
	pullUp,		/*!< Set internal resistance as **Pull-Up** */
	pullDown	/*!< Set internal resistance as **Pull-Down** */
}pinPullUpDown_t;

/*! Enum to set the pin's speed*/
typedef enum 
{
	def_speed,	/*!< set pin's spped to **Default** */
	slow,		/*!< set pin's speed to **Slow** */
	normal,		/*!< set pin's speed to **Normal** */ 
	fast,		/*!< set pin's speed to **Fast** */
	veryFast	/*!< set pin's speed to **Very Fast** */
}pinSpeed_t;

/*! Enum to enable ordisable pin interrupt */
typedef enum 
{
	disabled,	/*!< Interrupt disabled */
	enabled		/*!< Interrupt enabled */ 
}pinInterrupt_t;

/*! Pin configuration typedef struct*/
typedef struct 
{
	pinMode_t md;			/*!< Pin mode */
	pinStage_t st;			/*!< Pin logic state */
	pinPullUpDown_t pud;	/*!< Pin pullup pulldown status */
	pinSpeed_t sp;			/*!< Pin busspeed */
	pinInterrupt_t intr;	/*!< Pin interrupt enable state */
}pinConfiguration_t;

/*! Typedef enum of all possible pin errors */
typedef enum {
	notValidMode,			/*!< Mode is either not valid orsupported by **Hardwaware** */
	UnvalidAlternate,		/*!< Alternateive mode is unvalid */
	OutOfRangeAlternate,	/*!<  */
	NotValidSpeed,			/*!< The choosen bus speed is not supported */
	notValidOut,			/*!<  */
	OutOfRange,				/*!<  */
	NotDeclared,			/*!<  */
	NotReachable,			/*!<  */
	NoPullUpDown,			/*!< Pull-Up mode is not supported by **HARDWARE"" */
	NotAnalog,				/*!< Analog mode is not supported by **HARDWARE** */
	NotDigital,				/*!< Digital mode is not supported by **HARDWARE** */
	Blocked,				/*!<  */
	AlreadyUsed,			/*!<  */
	NotGpio					/*!< This given pin is not a GPIO **HARDWARE** */
}pinErrors_t;

/** 
 * @brief Configuration function that will call all the necessary function for an sucessfull pin initialisation
 * @param pinNo_t mode_t 
 * @retval none
 */
void pinConfig(pinNo_t pinNo, pinMode_t mode, pinStage_t stage, pinPullUpDown_t resistance, pinSpeed_t speed); 

/**
 * @brief Modes to set the direction or function of the pin
 */
void pinSetMode(pinNo_t pinNo, pinMode_t mode);

/**
 * @brief Output Stage Push-Pull High-z ect...
 */
void pinSetOutputStage(pinNo_t pinNo, pinStage_t stage); 

/**
* @brief  Depending of the hardare it is able to select the speed of given pins
*/
void pinSetSpeed(pinNo_t pinNo, pinSpeed_t speed); 

/**
* @brief  If internal Pull-up or Pull-donws are wailable
*/
void pinSetPullUpDonw(pinNo_t pinNo, pinPullUpDown_t resistance); 

/**
* @brief  If pin is set as alternate this function will modify the pins functionality
* If pin isn't set as alternate this function will set the pin to alternate mode. 
*/
void pinSetAlternate(pinNo_t pinNo, uint16_t alternate); 

/**
* @brief  Reads the pin's current value 
*/
uint8_t pinRead(pinNo_t pinNo);

/**
* @brief  Toggles th pin's value
*/
void pinToggle(pinNo_t pinNo);

/**
* @brief  Sets the pin hihg or low.
*/
void pinWrite(pinNo_t pinNo, uint8_t state);

/**
* @brief  Initiates all the preriferals needed for the given pin
*/
void pinInit(pinNo_t pinNo);

/**
* @brief  Deactivates all the preriferals needed for the given pin
*/
void pinDeInit(pinNo_t pinNo);

/**
* @brief  Resets pin to default
*/
void pinReset(pinNo_t pinNo);

/**
* @brief  Will pirnt tthe rurrent devices pin status and their configrarion.
* Dependeing on the platform an the form of information printing.
*/
void pinHardwareInfo(pinNo_t pinNo);

/**
* @brief  Handles the given error and stops all further execution.
* Dependeing on the platfonr an the form of information printing.
*/
void pinThrowError(pinErrors_t error); 	

#ifdef __cplusplus
}
#endif

#endif // _GPIO_H_
