-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbtn.c
159 lines (142 loc) · 5.71 KB
/
btn.c
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
151
152
153
154
155
156
157
158
//*********************************************************************************
// State Button Debouncer - Platform Independent
//
// Revision: 1.6
//
// Description: Debounces buttons on a single port being used by the application.
// This module takes what the signal on a GPIO port is doing and removes
// the oscillations caused by a bouncing button and tells the application if
// the button(s) are debounced. This algorithm is robust against noise if the
// amount of allowable debouncing states is adequate. Below is an example of how
// the button debouncer would work in practice in relation to a single button:
//
// Real Signal: 0011111111111110000000000000011111111111111111110000000000
// Bouncy Signal: 0010110111111111010000000000001010111011111111110101000000
// Debounced Sig: 0000000000000011000000000000000000000000000001110000000000
//
// The debouncing algorithm used in this library is based partly on Jack
// Ganssle's state button debouncer example shown in, "A Guide to Debouncing"
// Rev 4. http://www.ganssle.com/debouncing.htm
//
// Revisions can be found here:
// https://github.com/tcleg
//
// Copyright (C) 2014 Trent Cleghorn , <[email protected]>
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//*********************************************************************************
//*********************************************************************************
// Headers
//*********************************************************************************
#include "btn.h"
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "inc/hw_gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
//*********************************************************************************
// Functions
//*********************************************************************************
uint8_t Port1ReadBits(void)
{
return GPIOPinRead( BUTTONS_GPIO_BASE, ALL_BUTTONS );
}
void
ButtonDebounceInit(Debouncer *port, uint8_t pulledUpButtons)
{
//
// Enable the GPIO port to which the pushbuttons are connected.
//
ROM_SysCtlPeripheralEnable(BUTTONS_GPIO_PERIPH);
//
// Set each of the button GPIO pins as an input with a pull-up.
//
ROM_GPIODirModeSet(BUTTONS_GPIO_BASE, ALL_BUTTONS, GPIO_DIR_MODE_IN);
MAP_GPIOPadConfigSet(BUTTONS_GPIO_BASE, ALL_BUTTONS,
GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
uint8_t i;
port->index = 0;
port->debouncedState = 0x00;
port->changed = 0x00;
port->pullType = pulledUpButtons;
// Initialize the state array
for(i = 0; i < NUM_BUTTON_STATES; i++)
{
port->state[i] = 0x00;
}
}
// portStatus is the raw reading from the pushbuttons
void
ButtonProcess(Debouncer *port, uint8_t portStatus)
{
uint8_t i;
uint8_t lastDebouncedState = port->debouncedState;
// If a button is high and is pulled down or
// if a button is low and is pulled high, use a 1 bit
// to denote the button has changed state. Else, a 0 bit
// shows it is in a normal position.
// Then, save the port status info into the state array
port->state[port->index] = portStatus ^ port->pullType;
// Debounce the buttons
for(i = 0, port->debouncedState = 0xFF; i < NUM_BUTTON_STATES; i++)
{
port->debouncedState &= port->state[i];
}
// Check to make sure the index hasn't gone over the limit
port->index++;
if(port->index >= NUM_BUTTON_STATES)
{
port->index = 0;
}
// Calculate what changed.
// If the switch was high and is now low, 1 and 0 xORed with
// each other produces a 1. If the switch was low and is now
// high, 0 and 1 xORed with each other produces a 1. Otherwise,
// it is 0
port->changed = port->debouncedState ^ lastDebouncedState;
}
uint8_t
ButtonPressed(Debouncer *port, uint8_t GPIOButtonPins)
{
// If the button changed and it changed to a 1, then the
// user just pressed it.
return (port->changed & port->debouncedState) & GPIOButtonPins;
}
uint8_t
ButtonReleased(Debouncer *port, uint8_t GPIOButtonPins)
{
// If the button changed and it changed to a 0, then the
// user just released the button.
return (port->changed & (~port->debouncedState)) & GPIOButtonPins;
}
uint8_t
ButtonCurrent(Debouncer *port, uint8_t GPIOButtonPins)
{
// Current pressed or not pressed states of the buttons expressed
// as one 8 bit byte. A 0 bit denotes the button is not pressed,
// and a 1 bit denotes it is being pressed.
return port->debouncedState & GPIOButtonPins;
}