Craig Evans / Mbed 2 deprecated ELEC2645_FSM_UpDown_Counter

Dependencies:   mbed

Committer:
eencae
Date:
Fri Jan 24 13:30:25 2020 +0000
Revision:
2:2a0738a294df
Parent:
1:fb324de02b7f
Gamepad2

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 1:fb324de02b7f 5 Sample code from ELEC2645
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 2:2a0738a294df 10 Updated Jan 2020
eencae 0:c5278b91719f 11
eencae 0:c5278b91719f 12 */
eencae 0:c5278b91719f 13
eencae 0:c5278b91719f 14 #include "mbed.h"
eencae 0:c5278b91719f 15
eencae 0:c5278b91719f 16 // pre-processor directives
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 2:2a0738a294df 22 BusOut k64f_leds(LED_RED, LED_GREEN, LED_BLUE);
eencae 2:2a0738a294df 23
eencae 1:fb324de02b7f 24 // Gamepad Button A
eencae 2:2a0738a294df 25 InterruptIn buttonA(PTC7);
eencae 0:c5278b91719f 26
eencae 2:2a0738a294df 27 // LEDs on Gamepad (1 to 3) - active-low 0 = on and 1 = off
eencae 2:2a0738a294df 28 // BusOut arguments are LSB first
eencae 2:2a0738a294df 29 BusOut output(PTA2,PTC2,PTC3);
eencae 0:c5278b91719f 30
eencae 0:c5278b91719f 31 // array of states in the FSM, each element is the output of the counter
eencae 1:fb324de02b7f 32 // set the output in binary to make it easier, 0 is LED on, 1 is LED off
eencae 2:2a0738a294df 33 int fsm[3] = {0b011,0b101,0b110};
eencae 0:c5278b91719f 34
eencae 0:c5278b91719f 35 // flag - must be volatile as changes within ISR
eencae 0:c5278b91719f 36 // g_ prefix makes it easier to distinguish it as global
eencae 1:fb324de02b7f 37 volatile int g_buttonA_flag = 0;
eencae 0:c5278b91719f 38
eencae 2:2a0738a294df 39
eencae 1:fb324de02b7f 40 // Button A interrupt service routine
eencae 1:fb324de02b7f 41 void buttonA_isr();
eencae 0:c5278b91719f 42
eencae 0:c5278b91719f 43 int main()
eencae 0:c5278b91719f 44 {
eencae 2:2a0738a294df 45 k64f_leds = 0b111; // turn off K64F LEDs
eencae 2:2a0738a294df 46
eencae 1:fb324de02b7f 47 // Button A is connected between the pin and 3.3 V, we therefore need to turn on the internal pull-down resister
eencae 2:2a0738a294df 48 buttonA.mode(PullUp);
eencae 2:2a0738a294df 49 // Setup interrupt on falling edge
eencae 2:2a0738a294df 50 buttonA.fall(&buttonA_isr);
eencae 2:2a0738a294df 51
eencae 0:c5278b91719f 52 // set inital state
eencae 0:c5278b91719f 53 int state = 0;
eencae 0:c5278b91719f 54 // set initial direction
eencae 0:c5278b91719f 55 int direction = UP;
eencae 0:c5278b91719f 56
eencae 0:c5278b91719f 57 while(1) { // loop forever
eencae 2:2a0738a294df 58
eencae 0:c5278b91719f 59 // check if flag i.e. interrupt has occured
eencae 1:fb324de02b7f 60 if (g_buttonA_flag) {
eencae 1:fb324de02b7f 61 g_buttonA_flag = 0; // if it has, clear the flag
eencae 0:c5278b91719f 62
eencae 0:c5278b91719f 63 // swap direction when button has been pressed
eencae 0:c5278b91719f 64 // (could just use ! but want this to be explicit to aid understanding)
eencae 0:c5278b91719f 65 if (direction == UP) {
eencae 2:2a0738a294df 66 direction = DOWN;
eencae 2:2a0738a294df 67 } else {
eencae 0:c5278b91719f 68 direction = UP;
eencae 0:c5278b91719f 69 }
eencae 0:c5278b91719f 70 }
eencae 2:2a0738a294df 71
eencae 0:c5278b91719f 72 output = fsm[state]; // output current state
eencae 0:c5278b91719f 73
eencae 0:c5278b91719f 74 // check which state we are in and see which the next state should be next depending on direction
eencae 0:c5278b91719f 75 switch(state) {
eencae 0:c5278b91719f 76 case 0:
eencae 0:c5278b91719f 77 switch(direction) {
eencae 0:c5278b91719f 78 case UP:
eencae 0:c5278b91719f 79 state = 1;
eencae 0:c5278b91719f 80 break;
eencae 0:c5278b91719f 81 case DOWN:
eencae 2:2a0738a294df 82 state = 2;
eencae 0:c5278b91719f 83 break;
eencae 0:c5278b91719f 84 }
eencae 0:c5278b91719f 85 break;
eencae 0:c5278b91719f 86 case 1:
eencae 0:c5278b91719f 87 switch(direction) {
eencae 0:c5278b91719f 88 case UP:
eencae 0:c5278b91719f 89 state = 2;
eencae 0:c5278b91719f 90 break;
eencae 0:c5278b91719f 91 case DOWN:
eencae 0:c5278b91719f 92 state = 0;
eencae 0:c5278b91719f 93 break;
eencae 0:c5278b91719f 94 }
eencae 0:c5278b91719f 95 break;
eencae 0:c5278b91719f 96 case 2:
eencae 0:c5278b91719f 97 switch(direction) {
eencae 0:c5278b91719f 98 case UP:
eencae 2:2a0738a294df 99 state = 0;
eencae 0:c5278b91719f 100 break;
eencae 0:c5278b91719f 101 case DOWN:
eencae 0:c5278b91719f 102 state = 1;
eencae 0:c5278b91719f 103 break;
eencae 0:c5278b91719f 104 }
eencae 0:c5278b91719f 105 break;
eencae 0:c5278b91719f 106 default: // default case
eencae 1:fb324de02b7f 107 error("Invalid state!"); //invalid state - call error routine
eencae 0:c5278b91719f 108 // or could jump to starting state i.e. state = 0
eencae 0:c5278b91719f 109 break;
eencae 0:c5278b91719f 110 }
eencae 0:c5278b91719f 111
eencae 2:2a0738a294df 112 wait(0.5); // small delay
eencae 0:c5278b91719f 113
eencae 0:c5278b91719f 114
eencae 0:c5278b91719f 115 }
eencae 0:c5278b91719f 116 }
eencae 0:c5278b91719f 117
eencae 1:fb324de02b7f 118 // Button A event-triggered interrupt
eencae 1:fb324de02b7f 119 void buttonA_isr()
eencae 0:c5278b91719f 120 {
eencae 1:fb324de02b7f 121 g_buttonA_flag = 1; // set flag in ISR
eencae 0:c5278b91719f 122 }