PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
button_semaphore.c
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 
30 #include "pic24_all.h"
31 
32 /** \file
33 Demonstrates the use of semaphore variable that is
34 set in an interrupt service routine and read by
35 the main loop. In this case, the semaphore indicates
36 that a button press & release IO event has been received.
37 The main loop toggles an LED when the semaphore
38 is set.
39 */
40 
41 /// LED1
42 #define CONFIG_LED1() CONFIG_RB14_AS_DIG_OUTPUT()
43 #define LED1 _LATB14 //led1 state
44 
45 /// Switch1 configuration
46 inline void CONFIG_SW1() {
47  CONFIG_RB13_AS_DIG_INPUT(); //use RB13 for switch input
48  ENABLE_RB13_PULLUP(); //enable the pullup
49  DELAY_US(1); // Wait for pullup
50 }
51 
52 #define SW1 _RB13 //switch value
53 #define SW1_PRESSED() (SW1==0) //switch test
54 #define SW1_RELEASED() (SW1==1) //switch test
55 
56 //semaphore variable
57 volatile uint8_t u8_pressAndRelease = 0; //initially cleared
58 
59 typedef enum {
60  STATE_RESET = 0,
61  STATE_WAIT_FOR_PRESS,
62  STATE_WAIT_FOR_RELEASE
63 } STATE;
64 
65 volatile STATE e_mystate = STATE_RESET;
66 
67 //Interrupt Service Routine for Timer3
68 void _ISRFAST _T3Interrupt (void) {
69  if (!u8_pressAndRelease) {
70  //semaphore is cleared, watch for another press & release
71  switch (e_mystate) {
72  case STATE_WAIT_FOR_PRESS:
73  if (SW1_PRESSED()) {
74  e_mystate = STATE_WAIT_FOR_RELEASE;
75  }
76  break;
77  case STATE_WAIT_FOR_RELEASE:
78  if (SW1_RELEASED()) {
79  //have received a complete Press & Release.
80  //Set the semaphore
81  u8_pressAndRelease = 1;
82  e_mystate = STATE_WAIT_FOR_PRESS;
83  }
84  break;
85  default:
86  e_mystate = STATE_WAIT_FOR_PRESS;
87  }
88  }
89 
90  _T3IF = 0; //clear the timer interrupt bit
91 }
92 
93 #define ISR_PERIOD 15 // in ms
94 void configTimer3(void) {
95  //ensure that Timer2,3 configured as separate timers.
96  T2CONbits.T32 = 0; // 32-bit mode off
97  //T3CON set like this for documentation purposes.
98  //could be replaced by T3CON = 0x0020
99  T3CON = T3_OFF |T3_IDLE_CON | T3_GATE_OFF
100  | T3_SOURCE_INT
101  | T3_PS_1_64 ; //results in T3CON= 0x0020
102  PR3 = msToU16Ticks (ISR_PERIOD, getTimerPrescale(T3CONbits)) - 1;
103  TMR3 = 0; //clear timer3 value
104  _T3IF = 0; //clear interrupt flag
105  _T3IP = 1; //choose a priority
106  _T3IE = 1; //enable the interrupt
107  T3CONbits.TON = 1; //turn on the timer
108 }
109 
110 
111 int main (void) {
112  configBasic(HELLO_MSG);
113  /** GPIO config ***************************/
114  CONFIG_SW1(); //configure switch
115  CONFIG_LED1(); //config the LED
116  /* Timer configuration */
117  configTimer3(); //use Timer3 to periodically sample the switch input
118 
119  /*****Toggle LED each time switch is pressed and released ******/
120 
121  while (1) {
122  //wait for press & release
123  if (!u8_pressAndRelease) {
124  doHeartbeat(); //ensure that we are alive
125  } else {
126  //semaphore received (IO event has occurred!)
127  //Toggle the LED, then clear the semaphore
128  LED1 = !LED1;
129  u8_pressAndRelease = 0;
130  }
131  }// end while (1)
132 
133  // End program
134  return 0;
135 }