Craig Evans
/
ELEC2645_FSM_UpDown_Counter_Transition_Table
Gamepad2
main.cpp@3:e63504fba99a, 2020-01-24 (annotated)
- Committer:
- eencae
- Date:
- Fri Jan 24 13:46:01 2020 +0000
- Revision:
- 3:e63504fba99a
- Parent:
- 2:15b8db916ece
Gamepad2
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
eencae | 0:49ec0f45aa1c | 1 | /* |
eencae | 0:49ec0f45aa1c | 2 | |
eencae | 0:49ec0f45aa1c | 3 | 2645_FSM_UpDown_Counter_Transition_Table |
eencae | 0:49ec0f45aa1c | 4 | |
eencae | 2:15b8db916ece | 5 | Sample code from ELEC2645 |
eencae | 0:49ec0f45aa1c | 6 | |
eencae | 0:49ec0f45aa1c | 7 | Demonstrates how to implement a simple FSM up/down counter using a transition table |
eencae | 0:49ec0f45aa1c | 8 | |
eencae | 0:49ec0f45aa1c | 9 | (c) Craig A. Evans, University of Leeds, Jan 2016 |
eencae | 3:e63504fba99a | 10 | Updated Jan 2020 |
eencae | 0:49ec0f45aa1c | 11 | |
eencae | 0:49ec0f45aa1c | 12 | */ |
eencae | 0:49ec0f45aa1c | 13 | |
eencae | 0:49ec0f45aa1c | 14 | #include "mbed.h" |
eencae | 0:49ec0f45aa1c | 15 | |
eencae | 0:49ec0f45aa1c | 16 | // pre-processor directives |
eencae | 0:49ec0f45aa1c | 17 | |
eencae | 0:49ec0f45aa1c | 18 | // defines directions as 0/1. Note UPPERCASE |
eencae | 0:49ec0f45aa1c | 19 | #define UP 0 |
eencae | 0:49ec0f45aa1c | 20 | #define DOWN 1 |
eencae | 0:49ec0f45aa1c | 21 | |
eencae | 0:49ec0f45aa1c | 22 | // K64F on-board LEDs |
eencae | 3:e63504fba99a | 23 | BusOut k64f_leds(LED_RED, LED_GREEN, LED_BLUE); |
eencae | 2:15b8db916ece | 24 | |
eencae | 2:15b8db916ece | 25 | // Gamepad Button A |
eencae | 3:e63504fba99a | 26 | InterruptIn buttonA(PTC7); |
eencae | 2:15b8db916ece | 27 | |
eencae | 3:e63504fba99a | 28 | // LEDs on Gamepad (1 to 3) - active-low 0 = on and 1 = off |
eencae | 3:e63504fba99a | 29 | // BusOut arguments are LSB first |
eencae | 3:e63504fba99a | 30 | BusOut output(PTA2,PTC2,PTC3); |
eencae | 0:49ec0f45aa1c | 31 | |
eencae | 0:49ec0f45aa1c | 32 | // struct for state |
eencae | 0:49ec0f45aa1c | 33 | struct State { |
eencae | 0:49ec0f45aa1c | 34 | int output; // output value for current state |
eencae | 0:49ec0f45aa1c | 35 | float time; // wait time for state |
eencae | 0:49ec0f45aa1c | 36 | int next_state[2]; // next state (depending on direction 0 - UP, 1 - DOWN) |
eencae | 0:49ec0f45aa1c | 37 | }; |
eencae | 0:49ec0f45aa1c | 38 | |
eencae | 0:49ec0f45aa1c | 39 | // array of states in the FSM, each element is the output of the counter, wait time, next state(s) |
eencae | 1:9d9040c75f6b | 40 | State fsm[4] = { |
eencae | 3:e63504fba99a | 41 | {0b110,0.5,{1,2}}, |
eencae | 3:e63504fba99a | 42 | {0b101,0.5,{2,0}}, |
eencae | 3:e63504fba99a | 43 | {0b011,0.5,{0,1}}, |
eencae | 0:49ec0f45aa1c | 44 | }; |
eencae | 0:49ec0f45aa1c | 45 | |
eencae | 0:49ec0f45aa1c | 46 | // flag - must be volatile as changes within ISR |
eencae | 0:49ec0f45aa1c | 47 | // g_ prefix makes it easier to distinguish it as global |
eencae | 2:15b8db916ece | 48 | volatile int g_buttonA_flag = 0; |
eencae | 0:49ec0f45aa1c | 49 | |
eencae | 0:49ec0f45aa1c | 50 | // function prototypes |
eencae | 2:15b8db916ece | 51 | // Button A interrupt service routine |
eencae | 2:15b8db916ece | 52 | void buttonA_isr(); |
eencae | 0:49ec0f45aa1c | 53 | |
eencae | 0:49ec0f45aa1c | 54 | int main() |
eencae | 0:49ec0f45aa1c | 55 | { |
eencae | 3:e63504fba99a | 56 | k64f_leds = 0b111; // turn off K64F LEDs |
eencae | 0:49ec0f45aa1c | 57 | |
eencae | 2:15b8db916ece | 58 | // Button A is connected between the pin and 3.3 V, we therefore need to turn on the internal pull-down resister |
eencae | 3:e63504fba99a | 59 | buttonA.mode(PullUp); |
eencae | 3:e63504fba99a | 60 | // Setup interrupt on falling edge |
eencae | 3:e63504fba99a | 61 | buttonA.fall(&buttonA_isr); |
eencae | 0:49ec0f45aa1c | 62 | |
eencae | 0:49ec0f45aa1c | 63 | // set initial state |
eencae | 0:49ec0f45aa1c | 64 | int state = 0; |
eencae | 0:49ec0f45aa1c | 65 | // set initial direction |
eencae | 0:49ec0f45aa1c | 66 | int direction = UP; |
eencae | 0:49ec0f45aa1c | 67 | |
eencae | 0:49ec0f45aa1c | 68 | while(1) { // loop forever |
eencae | 0:49ec0f45aa1c | 69 | |
eencae | 0:49ec0f45aa1c | 70 | // check if flag i.e. interrupt has occured |
eencae | 2:15b8db916ece | 71 | if (g_buttonA_flag) { |
eencae | 2:15b8db916ece | 72 | g_buttonA_flag = 0; // if it has, clear the flag |
eencae | 0:49ec0f45aa1c | 73 | // swap direction when button has been pressed |
eencae | 0:49ec0f45aa1c | 74 | direction = ! direction; |
eencae | 0:49ec0f45aa1c | 75 | } |
eencae | 0:49ec0f45aa1c | 76 | |
eencae | 0:49ec0f45aa1c | 77 | // set output of current state (use dot syntax to access struct members) |
eencae | 0:49ec0f45aa1c | 78 | output = fsm[state].output; |
eencae | 0:49ec0f45aa1c | 79 | // implement required delay |
eencae | 0:49ec0f45aa1c | 80 | wait(fsm[state].time); |
eencae | 0:49ec0f45aa1c | 81 | // set the next state depending on direction |
eencae | 0:49ec0f45aa1c | 82 | state = fsm[state].next_state[direction]; |
eencae | 0:49ec0f45aa1c | 83 | |
eencae | 0:49ec0f45aa1c | 84 | } |
eencae | 0:49ec0f45aa1c | 85 | } |
eencae | 0:49ec0f45aa1c | 86 | |
eencae | 2:15b8db916ece | 87 | // Button A event-triggered interrupt |
eencae | 2:15b8db916ece | 88 | void buttonA_isr() |
eencae | 0:49ec0f45aa1c | 89 | { |
eencae | 2:15b8db916ece | 90 | g_buttonA_flag = 1; // set flag in ISR |
eencae | 0:49ec0f45aa1c | 91 | } |