Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp@2:2a0738a294df, 2020-01-24 (annotated)
- Committer:
- eencae
- Date:
- Fri Jan 24 13:30:25 2020 +0000
- Revision:
- 2:2a0738a294df
- Parent:
- 1:fb324de02b7f
Gamepad2
Who changed what in which revision?
| User | Revision | Line number | New 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 | } |