From e6f3f7c6a7ad2fdc00aaa4fa37e878610578994f Mon Sep 17 00:00:00 2001 From: Ibrahim Date: Wed, 5 Oct 2022 00:28:32 +0200 Subject: [PATCH] added GPIO driver --- .gitignore | 1 + GPIOs/.cproject | 115 ++++++ GPIOs/.project | 27 ++ .../.settings/de.innot.avreclipse.core.prefs | 7 + .../org.eclipse.core.resources.prefs | 2 + GPIOs/src/common_macros.h | 34 ++ GPIOs/src/gpio.c | 328 ++++++++++++++++++ GPIOs/src/gpio.h | 99 ++++++ GPIOs/src/std_types.h | 40 +++ 9 files changed, 653 insertions(+) create mode 100644 .gitignore create mode 100644 GPIOs/.cproject create mode 100644 GPIOs/.project create mode 100644 GPIOs/.settings/de.innot.avreclipse.core.prefs create mode 100644 GPIOs/.settings/org.eclipse.core.resources.prefs create mode 100644 GPIOs/src/common_macros.h create mode 100644 GPIOs/src/gpio.c create mode 100644 GPIOs/src/gpio.h create mode 100644 GPIOs/src/std_types.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e10e727 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.metadata/ diff --git a/GPIOs/.cproject b/GPIOs/.cproject new file mode 100644 index 0000000..0b5ca57 --- /dev/null +++ b/GPIOs/.cproject @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GPIOs/.project b/GPIOs/.project new file mode 100644 index 0000000..17e04f8 --- /dev/null +++ b/GPIOs/.project @@ -0,0 +1,27 @@ + + + GPIOs + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + de.innot.avreclipse.core.avrnature + + diff --git a/GPIOs/.settings/de.innot.avreclipse.core.prefs b/GPIOs/.settings/de.innot.avreclipse.core.prefs new file mode 100644 index 0000000..2340aaf --- /dev/null +++ b/GPIOs/.settings/de.innot.avreclipse.core.prefs @@ -0,0 +1,7 @@ +avrtarget/ClockFrequency=16000000 +avrtarget/ExtRAMSize=0 +avrtarget/ExtendedRAM=false +avrtarget/MCUType=atmega32 +avrtarget/UseEEPROM=false +avrtarget/UseExtendedRAMforHeap=true +eclipse.preferences.version=1 diff --git a/GPIOs/.settings/org.eclipse.core.resources.prefs b/GPIOs/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/GPIOs/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/GPIOs/src/common_macros.h b/GPIOs/src/common_macros.h new file mode 100644 index 0000000..68109b6 --- /dev/null +++ b/GPIOs/src/common_macros.h @@ -0,0 +1,34 @@ + /****************************************************************************** + * + * Module: Common - Macros + * File Name: Common_Macros.h + * Description: Commonly used Macros + * Author: Ibrahim Mohamed + * + *******************************************************************************/ + +#ifndef COMMON_MACROS +#define COMMON_MACROS + +/* Set a certain bit in any register */ +#define SET_BIT(REG,BIT) (REG|=(1<>num) | (REG<<(8-num)) ) + +/* Rotate left the register value with specific number of rotates */ +#define ROL(REG,num) ( REG= (REG<>(8-num)) ) + +/* Check if a specific bit is set in any register and return true if yes */ +#define BIT_IS_SET(REG,BIT) ( REG & (1<= NUM_OF_PINS_PER_PORT) || (port_num >= NUM_OF_PORTS)) + { + /* Do Nothing */ + } + else + { + /* Setup the pin direction as required */ + switch(port_num) + { + case PORTA_ID: + if(direction == PIN_OUTPUT) + { + SET_BIT(DDRA,pin_num); + } + else + { + CLEAR_BIT(DDRA,pin_num); + } + break; + case PORTB_ID: + if(direction == PIN_OUTPUT) + { + SET_BIT(DDRB,pin_num); + } + else + { + CLEAR_BIT(DDRB,pin_num); + } + break; + case PORTC_ID: + if(direction == PIN_OUTPUT) + { + SET_BIT(DDRC,pin_num); + } + else + { + CLEAR_BIT(DDRC,pin_num); + } + break; + case PORTD_ID: + if(direction == PIN_OUTPUT) + { + SET_BIT(DDRD,pin_num); + } + else + { + CLEAR_BIT(DDRD,pin_num); + } + break; + } + } +} + +/* + * Description : + * Write the value Logic High or Logic Low on the required pin. + * If the input port number or pin number are not correct, The function will not handle the request. + * If the pin is input, this function will enable/disable the internal pull-up resistor. + */ +void GPIO_writePin(uint8 port_num, uint8 pin_num, uint8 value) +{ + /* + * Check if the input port number is greater than NUM_OF_PINS_PER_PORT value. + * Or if the input pin number is greater than NUM_OF_PINS_PER_PORT value. + * In this case the input is not valid port/pin number + */ + if((pin_num >= NUM_OF_PINS_PER_PORT) || (port_num >= NUM_OF_PORTS)) + { + /* Do Nothing */ + } + else + { + /* Write the pin value as required */ + switch(port_num) + { + case PORTA_ID: + if(value == LOGIC_HIGH) + { + SET_BIT(PORTA,pin_num); + } + else + { + CLEAR_BIT(PORTA,pin_num); + } + break; + case PORTB_ID: + if(value == LOGIC_HIGH) + { + SET_BIT(PORTB,pin_num); + } + else + { + CLEAR_BIT(PORTB,pin_num); + } + break; + case PORTC_ID: + if(value == LOGIC_HIGH) + { + SET_BIT(PORTC,pin_num); + } + else + { + CLEAR_BIT(PORTC,pin_num); + } + break; + case PORTD_ID: + if(value == LOGIC_HIGH) + { + SET_BIT(PORTD,pin_num); + } + else + { + CLEAR_BIT(PORTD,pin_num); + } + break; + } + } +} + +/* + * Description : + * Read and return the value for the required pin, it should be Logic High or Logic Low. + * If the input port number or pin number are not correct, The function will return Logic Low. + */ +uint8 GPIO_readPin(uint8 port_num, uint8 pin_num) +{ + uint8 pin_value = LOGIC_LOW; + + /* + * Check if the input port number is greater than NUM_OF_PINS_PER_PORT value. + * Or if the input pin number is greater than NUM_OF_PINS_PER_PORT value. + * In this case the input is not valid port/pin number + */ + if((pin_num >= NUM_OF_PINS_PER_PORT) || (port_num >= NUM_OF_PORTS)) + { + /* Do Nothing */ + } + else + { + /* Read the pin value as required */ + switch(port_num) + { + case PORTA_ID: + if(BIT_IS_SET(PINA,pin_num)) + { + pin_value = LOGIC_HIGH; + } + else + { + pin_value = LOGIC_LOW; + } + break; + case PORTB_ID: + if(BIT_IS_SET(PINB,pin_num)) + { + pin_value = LOGIC_HIGH; + } + else + { + pin_value = LOGIC_LOW; + } + break; + case PORTC_ID: + if(BIT_IS_SET(PINC,pin_num)) + { + pin_value = LOGIC_HIGH; + } + else + { + pin_value = LOGIC_LOW; + } + break; + case PORTD_ID: + if(BIT_IS_SET(PIND,pin_num)) + { + pin_value = LOGIC_HIGH; + } + else + { + pin_value = LOGIC_LOW; + } + break; + } + } + + return pin_value; +} + +/* + * Description : + * Setup the direction of the required port all pins input/output. + * If the direction value is PORT_INPUT all pins in this port should be input pins. + * If the direction value is PORT_OUTPUT all pins in this port should be output pins. + * If the input port number is not correct, The function will not handle the request. + */ +void GPIO_setupPortDirection(uint8 port_num, GPIO_PortDirectionType direction) +{ + /* + * Check if the input number is greater than NUM_OF_PORTS value. + * In this case the input is not valid port number + */ + if(port_num >= NUM_OF_PORTS) + { + /* Do Nothing */ + } + else + { + /* Setup the port direction as required */ + switch(port_num) + { + case PORTA_ID: + DDRA = direction; + break; + case PORTB_ID: + DDRB = direction; + break; + case PORTC_ID: + DDRC = direction; + break; + case PORTD_ID: + DDRD = direction; + break; + } + } +} + +/* + * Description : + * Write the value on the required port. + * If any pin in the port is output pin the value will be written. + * If any pin in the port is input pin this will activate/deactivate the internal pull-up resistor. + * If the input port number is not correct, The function will not handle the request. + */ +void GPIO_writePort(uint8 port_num, uint8 value) +{ + /* + * Check if the input number is greater than NUM_OF_PORTS value. + * In this case the input is not valid port number + */ + if(port_num >= NUM_OF_PORTS) + { + /* Do Nothing */ + } + else + { + /* Write the port value as required */ + switch(port_num) + { + case PORTA_ID: + PORTA = value; + break; + case PORTB_ID: + PORTB = value; + break; + case PORTC_ID: + PORTC = value; + break; + case PORTD_ID: + PORTD = value; + break; + } + } +} + +/* + * Description : + * Read and return the value of the required port. + * If the input port number is not correct, The function will return ZERO value. + */ +uint8 GPIO_readPort(uint8 port_num) +{ + uint8 value = LOGIC_LOW; + + /* + * Check if the input number is greater than NUM_OF_PORTS value. + * In this case the input is not valid port number + */ + if(port_num >= NUM_OF_PORTS) + { + /* Do Nothing */ + } + else + { + /* Read the port value as required */ + switch(port_num) + { + case PORTA_ID: + value = PINA; + break; + case PORTB_ID: + value = PINB; + break; + case PORTC_ID: + value = PINC; + break; + case PORTD_ID: + value = PIND; + break; + } + } + + return value; +} diff --git a/GPIOs/src/gpio.h b/GPIOs/src/gpio.h new file mode 100644 index 0000000..bd4ff74 --- /dev/null +++ b/GPIOs/src/gpio.h @@ -0,0 +1,99 @@ + /****************************************************************************** + * + * Module: GPIO + * File Name: gpio.h + * Description: Header file for the AVR GPIO driver + * Author: Ibrahim Mohamed + * + *******************************************************************************/ + +#ifndef GPIO_H_ +#define GPIO_H_ + +#include "std_types.h" + +/******************************************************************************* + * Configurations * + *******************************************************************************/ +#define NUM_OF_PORTS 4 +#define NUM_OF_PINS_PER_PORT 8 + +#define PORTA_ID 0 +#define PORTB_ID 1 +#define PORTC_ID 2 +#define PORTD_ID 3 + +#define PIN0_ID 0 +#define PIN1_ID 1 +#define PIN2_ID 2 +#define PIN3_ID 3 +#define PIN4_ID 4 +#define PIN5_ID 5 +#define PIN6_ID 6 +#define PIN7_ID 7 + +/******************************************************************************* + * Types Declaration * + *******************************************************************************/ +typedef enum +{ + PIN_INPUT,PIN_OUTPUT +}GPIO_PinDirectionType; + +typedef enum +{ + PORT_INPUT,PORT_OUTPUT=0xFF +}GPIO_PortDirectionType; + +/******************************************************************************* + * Functions Prototypes * + *******************************************************************************/ + +/* + * Description : + * Setup the direction of the required pin input/output. + * If the input port number or pin number are not correct, The function will not handle the request. + */ +void GPIO_setupPinDirection(uint8 port_num, uint8 pin_num, GPIO_PinDirectionType direction); + +/* + * Description : + * Write the value Logic High or Logic Low on the required pin. + * If the input port number or pin number are not correct, The function will not handle the request. + * If the pin is input, this function will enable/disable the internal pull-up resistor. + */ +void GPIO_writePin(uint8 port_num, uint8 pin_num, uint8 value); + +/* + * Description : + * Read and return the value for the required pin, it should be Logic High or Logic Low. + * If the input port number or pin number are not correct, The function will return Logic Low. + */ +uint8 GPIO_readPin(uint8 port_num, uint8 pin_num); + +/* + * Description : + * Setup the direction of the required port all pins input/output. + * If the direction value is PORT_INPUT all pins in this port should be input pins. + * If the direction value is PORT_OUTPUT all pins in this port should be output pins. + * If the input port number is not correct, The function will not handle the request. + */ +void GPIO_setupPortDirection(uint8 port_num, uint8 direction); + +/* + * Description : + * Write the value on the required port. + * If any pin in the port is output pin the value will be written. + * If any pin in the port is input pin this will activate/deactivate the internal pull-up resistor. + * If the input port number is not correct, The function will not handle the request. + */ +void GPIO_writePort(uint8 port_num, uint8 value); + +/* + * Description : + * Read and return the value of the required port. + * If the input port number is not correct, The function will return ZERO value. + */ +uint8 GPIO_readPort(uint8 port_num); + +#endif /* GPIO_H_ */ diff --git a/GPIOs/src/std_types.h b/GPIOs/src/std_types.h new file mode 100644 index 0000000..883c571 --- /dev/null +++ b/GPIOs/src/std_types.h @@ -0,0 +1,40 @@ + /****************************************************************************** + * + * Module: Common - Platform Types Abstraction + * File Name: std_types.h + * Description: types for AVR + * Author: Ibrahim Mohamed + * + *******************************************************************************/ + +#ifndef STD_TYPES_H_ +#define STD_TYPES_H_ + +/* Boolean Data Type */ +typedef unsigned char boolean; + +/* Boolean Values */ +#ifndef FALSE +#define FALSE (0u) +#endif +#ifndef TRUE +#define TRUE (1u) +#endif + +#define LOGIC_HIGH (1u) +#define LOGIC_LOW (0u) + +#define NULL_PTR ((void*)0) + +typedef unsigned char uint8; /* 0 .. 255 */ +typedef signed char sint8; /* -128 .. +127 */ +typedef unsigned short uint16; /* 0 .. 65535 */ +typedef signed short sint16; /* -32768 .. +32767 */ +typedef unsigned long uint32; /* 0 .. 4294967295 */ +typedef signed long sint32; /* -2147483648 .. +2147483647 */ +typedef unsigned long long uint64; /* 0 .. 18446744073709551615 */ +typedef signed long long sint64; /* -9223372036854775808 .. 9223372036854775807 */ +typedef float float32; +typedef double float64; + +#endif /* STD_TYPE_H_ */