Sample code from ELEC2645 Week 16 Lab Demonstrates how to implement a simple FSM up/down counter

Dependencies:   mbed

Committer:
eencae
Date:
Thu Jan 07 10:00:24 2016 +0000
Revision:
0:c5278b91719f
Child:
1:fb324de02b7f
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eencae 0:c5278b91719f 1 /*
eencae 0:c5278b91719f 2
eencae 0:c5278b91719f 3 2645_FSM_UpDown_Counter
eencae 0:c5278b91719f 4
eencae 0:c5278b91719f 5 Sample code from ELEC2645 Week 16 Lab
eencae 0:c5278b91719f 6
eencae 0:c5278b91719f 7 Demonstrates how to implement a simple FSM up/down counter
eencae 0:c5278b91719f 8
eencae 0:c5278b91719f 9 (c) Craig A. Evans, University of Leeds, Jan 2016
eencae 0:c5278b91719f 10
eencae 0:c5278b91719f 11 */
eencae 0:c5278b91719f 12
eencae 0:c5278b91719f 13 #include "mbed.h"
eencae 0:c5278b91719f 14
eencae 0:c5278b91719f 15 // pre-processor directives
eencae 0:c5278b91719f 16
eencae 0:c5278b91719f 17 // defines directions as 0/1. Note UPPERCASE
eencae 0:c5278b91719f 18 #define UP 0
eencae 0:c5278b91719f 19 #define DOWN 1
eencae 0:c5278b91719f 20
eencae 0:c5278b91719f 21 // K64F on-board LEDs
eencae 0:c5278b91719f 22 DigitalOut r_led(LED_RED);
eencae 0:c5278b91719f 23 DigitalOut g_led(LED_GREEN);
eencae 0:c5278b91719f 24 DigitalOut b_led(LED_BLUE);
eencae 0:c5278b91719f 25 // K64F on-board switches
eencae 0:c5278b91719f 26 InterruptIn sw2(SW2);
eencae 0:c5278b91719f 27 InterruptIn sw3(SW3);
eencae 0:c5278b91719f 28
eencae 0:c5278b91719f 29 // LEDs to display counter output
eencae 0:c5278b91719f 30 // connect up external LEDs to these pins with appropriate current-limiting resistor
eencae 0:c5278b91719f 31 BusOut output(PTB2,PTB3,PTB10,PTB11);
eencae 0:c5278b91719f 32
eencae 0:c5278b91719f 33 // array of states in the FSM, each element is the output of the counter
eencae 0:c5278b91719f 34 int fsm[4] = {1,2,4,8};
eencae 0:c5278b91719f 35
eencae 0:c5278b91719f 36 // flag - must be volatile as changes within ISR
eencae 0:c5278b91719f 37 // g_ prefix makes it easier to distinguish it as global
eencae 0:c5278b91719f 38 volatile int g_sw2_flag = 0;
eencae 0:c5278b91719f 39
eencae 0:c5278b91719f 40 // function prototypes
eencae 0:c5278b91719f 41 // error function hangs flashing an LED
eencae 0:c5278b91719f 42 void error();
eencae 0:c5278b91719f 43 // set-up the on-board LEDs and switches
eencae 0:c5278b91719f 44 void init_K64F();
eencae 0:c5278b91719f 45 // SW2 interrupt service routine
eencae 0:c5278b91719f 46 void sw2_isr();
eencae 0:c5278b91719f 47
eencae 0:c5278b91719f 48 int main()
eencae 0:c5278b91719f 49 {
eencae 0:c5278b91719f 50 // initialise on-board LED and switches
eencae 0:c5278b91719f 51 init_K64F();
eencae 0:c5278b91719f 52
eencae 0:c5278b91719f 53 // SW2 has a pull-up resistor, so the pin will be at 3.3 V by default
eencae 0:c5278b91719f 54 // and fall to 0 V when pressed. We therefore need to look for a falling edge
eencae 0:c5278b91719f 55 // on the pin to fire the interrupt
eencae 0:c5278b91719f 56 sw2.fall(&sw2_isr);
eencae 0:c5278b91719f 57
eencae 0:c5278b91719f 58 // set inital state
eencae 0:c5278b91719f 59 int state = 0;
eencae 0:c5278b91719f 60 // set initial direction
eencae 0:c5278b91719f 61 int direction = UP;
eencae 0:c5278b91719f 62
eencae 0:c5278b91719f 63 while(1) { // loop forever
eencae 0:c5278b91719f 64
eencae 0:c5278b91719f 65 // check if flag i.e. interrupt has occured
eencae 0:c5278b91719f 66 if (g_sw2_flag) {
eencae 0:c5278b91719f 67 g_sw2_flag = 0; // if it has, clear the flag
eencae 0:c5278b91719f 68
eencae 0:c5278b91719f 69 // swap direction when button has been pressed
eencae 0:c5278b91719f 70 // (could just use ! but want this to be explicit to aid understanding)
eencae 0:c5278b91719f 71 if (direction == UP) {
eencae 0:c5278b91719f 72 direction = DOWN;
eencae 0:c5278b91719f 73 }
eencae 0:c5278b91719f 74 else {
eencae 0:c5278b91719f 75 direction = UP;
eencae 0:c5278b91719f 76 }
eencae 0:c5278b91719f 77 }
eencae 0:c5278b91719f 78
eencae 0:c5278b91719f 79 output = fsm[state]; // output current state
eencae 0:c5278b91719f 80
eencae 0:c5278b91719f 81 // check which state we are in and see which the next state should be next depending on direction
eencae 0:c5278b91719f 82 switch(state) {
eencae 0:c5278b91719f 83 case 0:
eencae 0:c5278b91719f 84 switch(direction) {
eencae 0:c5278b91719f 85 case UP:
eencae 0:c5278b91719f 86 state = 1;
eencae 0:c5278b91719f 87 break;
eencae 0:c5278b91719f 88 case DOWN:
eencae 0:c5278b91719f 89 state = 3;
eencae 0:c5278b91719f 90 break;
eencae 0:c5278b91719f 91 }
eencae 0:c5278b91719f 92 break;
eencae 0:c5278b91719f 93 case 1:
eencae 0:c5278b91719f 94 switch(direction) {
eencae 0:c5278b91719f 95 case UP:
eencae 0:c5278b91719f 96 state = 2;
eencae 0:c5278b91719f 97 break;
eencae 0:c5278b91719f 98 case DOWN:
eencae 0:c5278b91719f 99 state = 0;
eencae 0:c5278b91719f 100 break;
eencae 0:c5278b91719f 101 }
eencae 0:c5278b91719f 102 break;
eencae 0:c5278b91719f 103 case 2:
eencae 0:c5278b91719f 104 switch(direction) {
eencae 0:c5278b91719f 105 case UP:
eencae 0:c5278b91719f 106 state = 3;
eencae 0:c5278b91719f 107 break;
eencae 0:c5278b91719f 108 case DOWN:
eencae 0:c5278b91719f 109 state = 1;
eencae 0:c5278b91719f 110 break;
eencae 0:c5278b91719f 111 }
eencae 0:c5278b91719f 112 break;
eencae 0:c5278b91719f 113 case 3:
eencae 0:c5278b91719f 114 switch(direction) {
eencae 0:c5278b91719f 115 case UP:
eencae 0:c5278b91719f 116 state = 0;
eencae 0:c5278b91719f 117 break;
eencae 0:c5278b91719f 118 case DOWN:
eencae 0:c5278b91719f 119 state = 2;
eencae 0:c5278b91719f 120 break;
eencae 0:c5278b91719f 121 }
eencae 0:c5278b91719f 122 break;
eencae 0:c5278b91719f 123 default: // default case
eencae 0:c5278b91719f 124 error(); //invalid state - call error routine
eencae 0:c5278b91719f 125 // or could jump to starting state i.e. state = 0
eencae 0:c5278b91719f 126 break;
eencae 0:c5278b91719f 127 }
eencae 0:c5278b91719f 128
eencae 0:c5278b91719f 129 wait(0.2); // small delay
eencae 0:c5278b91719f 130
eencae 0:c5278b91719f 131
eencae 0:c5278b91719f 132 }
eencae 0:c5278b91719f 133 }
eencae 0:c5278b91719f 134
eencae 0:c5278b91719f 135 void init_K64F()
eencae 0:c5278b91719f 136 {
eencae 0:c5278b91719f 137 // on-board LEDs are active-low, so set pin high to turn them off.
eencae 0:c5278b91719f 138 r_led = 1;
eencae 0:c5278b91719f 139 g_led = 1;
eencae 0:c5278b91719f 140 b_led = 1;
eencae 0:c5278b91719f 141
eencae 0:c5278b91719f 142 // since the on-board switches have external pull-ups, we should disable the internal pull-down
eencae 0:c5278b91719f 143 // resistors that are enabled by default using InterruptIn
eencae 0:c5278b91719f 144 sw2.mode(PullNone);
eencae 0:c5278b91719f 145 sw3.mode(PullNone);
eencae 0:c5278b91719f 146
eencae 0:c5278b91719f 147 }
eencae 0:c5278b91719f 148
eencae 0:c5278b91719f 149 void error()
eencae 0:c5278b91719f 150 {
eencae 0:c5278b91719f 151 while(1) { // if error, hang while flashing error message
eencae 0:c5278b91719f 152 r_led = 0;
eencae 0:c5278b91719f 153 wait(0.2);
eencae 0:c5278b91719f 154 r_led = 1;
eencae 0:c5278b91719f 155 wait(0.2);
eencae 0:c5278b91719f 156 }
eencae 0:c5278b91719f 157 }
eencae 0:c5278b91719f 158
eencae 0:c5278b91719f 159 // SW2 event-triggered interrupt
eencae 0:c5278b91719f 160 void sw2_isr()
eencae 0:c5278b91719f 161 {
eencae 0:c5278b91719f 162 g_sw2_flag = 1; // set flag in ISR
eencae 0:c5278b91719f 163 }