-
Notifications
You must be signed in to change notification settings - Fork 0
/
DIO_operations.h
150 lines (138 loc) · 5.03 KB
/
DIO_operations.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#ifndef DIO_operations
#define DIO_operations
#include "data_types_def.h"
#include "bit_operations.h"
#include "DIO_def.h"
//operations on ports
// the value passed to these functions is the value of every single bit in the PORT as 0b01011110 or 0x2F...
void DIO_setPortMode(u8 PORT, u8 value)
{
// switching over the PORT and setting it to the specified value
switch (PORT)
{
case PORTA : DDRA_reg = value; break;
case PORTB : DDRB_reg = value; break;
case PORTC : DDRC_reg = value; break;
case PORTD : DDRD_reg = value; break;
default: // exit (EXIT_FAILURE);
break;
}
}
void DIO_setPortVal(u8 PORT, u8 value)
{
// switching over the PORT and setting it to the specified value
switch (PORT)
{
case PORTA : PORTA_reg = value; break;
case PORTB : PORTB_reg = value; break;
case PORTC : PORTC_reg = value; break;
case PORTD : PORTD_reg = value; break;
default: // exit (EXIT_FAILURE);
break;
}
}
void DIO_setPortPullUp(u8 PORT,u8 value)
{
// to enable the pull-up resistance, the pin must be input and we enable it by writing high on the port register
DIO_setPortMode(PORT, INPUT);
DIO_setPortVal(PORT, value);
}
u8 DIO_getPortVal(u8 PORT)
{
if (PORT<PORTA || PORT> PORTD) // we could eliminate this line and use 'default' in the 'switch...case' but, using this line is cheaper
return 0xff; // returning a false value
//Notice that : we could use a temp variable to store the data but, using the return statement directly is a way more cheaper
switch (PORT)
{
// we left the break statement for the sake of readability
case PORTA: return (PINA_reg); break;
case PORTB: return (PINB_reg); break;
case PORTC: return (PINC_reg); break;
case PORTD: return (PIND_reg); break;
}
return 0xff; // returning a false value "this line is useless I put it here to avoid some annoying warnings"
}
//operations on pins
void DIO_setPinMode(u8 PORT, u8 PIN, u8 value)
{
if (PIN < PIN0 || PIN > PIN7) // wrong value for the pin !
return;
if (PORT<PORTA || PORT> PORTD) // we could eliminate this line and use 'default' in the 'switch...case' but, using this line is cheaper
return;
if (value == INPUT)
{
switch (PORT)
{
case PORTA: clr_bit(DDRA_reg,PIN); break;
case PORTB: clr_bit(DDRB_reg,PIN); break;
case PORTC: clr_bit(DDRC_reg,PIN); break;
case PORTD: clr_bit(DDRD_reg,PIN); break;
//default: // exit (EXIT_FAILURE); break;
}
}
else // if any other value is passed then, use it as OUTPUT, you can edit this line using else if (OUTPUT)
{
switch (PORT)
{
case PORTA: set_bit(DDRA_reg,PIN); break;
case PORTB: set_bit(DDRB_reg,PIN); break;
case PORTC: set_bit(DDRC_reg,PIN); break;
case PORTD: set_bit(DDRD_reg,PIN); break;
//default: // exit (EXIT_FAILURE); break;
}
}
}
void DIO_setPinVal(u8 PORT, u8 PIN, u8 value)
{
if (PIN < PIN0 || PIN > PIN7) // wrong value for the pin !
return;
if (PORT<PORTA || PORT> PORTD) // we could eliminate this line and use 'default' in the 'switch...case' but, using this line is cheaper
return;
if (value == LOW)
{
switch (PORT)
{
case PORTA: clr_bit(PORTA_reg,PIN); break;
case PORTB: clr_bit(PORTB_reg,PIN); break;
case PORTC: clr_bit(PORTC_reg,PIN); break;
case PORTD: clr_bit(PORTD_reg,PIN); break;
//default: // exit (EXIT_FAILURE); break;
}
}
else // if any other value is passed then, use it as HIGH ! you can edit this line using else if (HIGH)
{
switch (PORT)
{
case PORTA: set_bit(PORTA_reg,PIN); break;
case PORTB: set_bit(PORTB_reg,PIN); break;
case PORTC: set_bit(PORTC_reg,PIN); break;
case PORTD: set_bit(PORTD_reg,PIN); break;
//default: // exit (EXIT_FAILURE); break;
}
}
}
void DIO_setPinPullUp(u8 PORT, u8 PIN, u8 status)
{
// to enable the pull-up resistance, the pin must be input and we enable it by writing high on the port register
DIO_setPinMode(PORT, PIN, INPUT);
DIO_setPinVal(PORT, PIN, status); // HIGH if ENABLE , LOW if DISABLE
}
u8 DIO_getPinVal(u8 PORT, u8 PIN)
{
// PINx --> Port INput register, PIN --> a DIO pin of the ports of the MCU
if (PIN < PIN0 || PIN > PIN7) // wrong value for the pin !
return 0xff; // returning a false value as a single pin can't hold 0xff !
if (PORT<PORTA || PORT> PORTD) // we could eliminate this line and use 'default' in the 'switch...case' but, using this line is cheaper
return 0xff; // returning a false value as a single pin can't hold 0xff !
//Notice that : we could use a temp variable to store the data but, using the return statement directly is a way more cheaper
switch (PORT)
{
// we left the break statement for the sake of readability
case PORTA: return (get_bit(PINA_reg,PIN)); break;
case PORTB: return (get_bit(PINB_reg,PIN)); break;
case PORTC: return (get_bit(PINC_reg,PIN)); break;
case PORTD: return (get_bit(PIND_reg,PIN)); break;
}
return 0xff; // returning a false value "this line is useless I put it here to avoid some annoying warnings"
}
#endif