A simple class for reading button presses from a Super Nintendo (SNES) controller. Requires access to the controller's latch, clock, and data pins.

ABOUT

A simple class for reading a Super Nintendo (SNES) controller's buttons.

HARDWARE

The library was developed using the Nordic mKIT and cheap controllers.

NOTE: This controller has a wide VCC tolerance and continues to operate even when the mKIT is running off of a coin cell battery.

            +-----------+           
            |           |           
            |    +-+    |           
            |    +-+--------+VCC    
            |           |           
            |    +-+    |           
            |    +-+--------+CLOCK  
            |           |           
            |    +-+    |           
            |    +-+--------+LATCH  
            |           |           
            |    +-+    |           
            |    +-+--------+DATA   
            |           |           
            +-----------+           
            |           |           
            |    +-+    |           
            |    +-+--------+N/C    
            |           |           
            |    +-+    |           
            |    +-+--------+N/C    
            |           |           
            |    +-+    |           
            X    +-+----+---+GND    
             X         X            
              ---------             
                                    
          Controller pinout         
(looking into the female connector) 

USAGE

After wiring up a controller:

Include the library

#include "SNESController.h"

Create a new object and specify the pins

SNESController snes(P0_20, P0_21, P0_22);

Read and decode the button presses

uint16_t state = snes.read();
if (snes.pressed(state, SNESController::SNES_BUTTON_RIGHT_ARROW)) {
    ...
}

Poll the controller periodically

Ticker ticker;
ticker.attach(periodicCallback, 0.05);

Committer:
foolsday
Date:
Wed Jan 14 20:00:17 2015 +0000
Revision:
0:7deb78c1c738
A simple class for reading button presses from a Super Nintendo (SNES) controller. Requires access to a controller's latch, clock, and data pins.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
foolsday 0:7deb78c1c738 1 /* SNES Controller library
foolsday 0:7deb78c1c738 2 * Copyright (c) 2015 Daniel Veilleux
foolsday 0:7deb78c1c738 3 *
foolsday 0:7deb78c1c738 4 * Licensed under the Apache License, Version 2.0 (the "License");
foolsday 0:7deb78c1c738 5 * you may not use this file except in compliance with the License.
foolsday 0:7deb78c1c738 6 * You may obtain a copy of the License at
foolsday 0:7deb78c1c738 7 *
foolsday 0:7deb78c1c738 8 * http://www.apache.org/licenses/LICENSE-2.0
foolsday 0:7deb78c1c738 9 *
foolsday 0:7deb78c1c738 10 * Unless required by applicable law or agreed to in writing, software
foolsday 0:7deb78c1c738 11 * distributed under the License is distributed on an "AS IS" BASIS,
foolsday 0:7deb78c1c738 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
foolsday 0:7deb78c1c738 13 * See the License for the specific language governing permissions and
foolsday 0:7deb78c1c738 14 * limitations under the License.
foolsday 0:7deb78c1c738 15 */
foolsday 0:7deb78c1c738 16
foolsday 0:7deb78c1c738 17
foolsday 0:7deb78c1c738 18 #ifndef __SNES_CONTROLLER_H__
foolsday 0:7deb78c1c738 19 #define __SNES_CONTROLLER_H__
foolsday 0:7deb78c1c738 20
foolsday 0:7deb78c1c738 21 #include "mbed.h"
foolsday 0:7deb78c1c738 22
foolsday 0:7deb78c1c738 23
foolsday 0:7deb78c1c738 24 /**
foolsday 0:7deb78c1c738 25 * @class SNESController
foolsday 0:7deb78c1c738 26 * @brief Reads the state of an SNES controller and decodes the button presses.
foolsday 0:7deb78c1c738 27 */
foolsday 0:7deb78c1c738 28 class SNESController {
foolsday 0:7deb78c1c738 29 public:
foolsday 0:7deb78c1c738 30
foolsday 0:7deb78c1c738 31 /**
foolsday 0:7deb78c1c738 32 * @enum SNESButton_t
foolsday 0:7deb78c1c738 33 * @brief The masks of the individual buttons as read from the controller
foolsday 0:7deb78c1c738 34 */
foolsday 0:7deb78c1c738 35 enum SNESButton_t
foolsday 0:7deb78c1c738 36 {
foolsday 0:7deb78c1c738 37 SNES_BUTTON_B = 0x0001,
foolsday 0:7deb78c1c738 38 SNES_BUTTON_Y = 0x0002,
foolsday 0:7deb78c1c738 39 SNES_BUTTON_SEL = 0x0004,
foolsday 0:7deb78c1c738 40 SNES_BUTTON_START = 0x0008,
foolsday 0:7deb78c1c738 41 SNES_BUTTON_UP_ARROW = 0x0010,
foolsday 0:7deb78c1c738 42 SNES_BUTTON_DOWN_ARROW = 0x0020,
foolsday 0:7deb78c1c738 43 SNES_BUTTON_LEFT_ARROW = 0x0040,
foolsday 0:7deb78c1c738 44 SNES_BUTTON_RIGHT_ARROW = 0x0080,
foolsday 0:7deb78c1c738 45 SNES_BUTTON_A = 0x0100,
foolsday 0:7deb78c1c738 46 SNES_BUTTON_X = 0x0200,
foolsday 0:7deb78c1c738 47 SNES_BUTTON_L = 0x0400,
foolsday 0:7deb78c1c738 48 SNES_BUTTON_R = 0x0800
foolsday 0:7deb78c1c738 49 };
foolsday 0:7deb78c1c738 50
foolsday 0:7deb78c1c738 51
foolsday 0:7deb78c1c738 52 /**
foolsday 0:7deb78c1c738 53 * @brief Constructs a new object for reading button presses
foolsday 0:7deb78c1c738 54 *
foolsday 0:7deb78c1c738 55 * @param latch
foolsday 0:7deb78c1c738 56 * A PinName specifying the latch pin (pin #3)
foolsday 0:7deb78c1c738 57 * @param clock
foolsday 0:7deb78c1c738 58 * A PinName specifying the clock pin (pin #2)
foolsday 0:7deb78c1c738 59 * @param data
foolsday 0:7deb78c1c738 60 * A PinName specifying the data pin (pin #4)
foolsday 0:7deb78c1c738 61 *
foolsday 0:7deb78c1c738 62 */
foolsday 0:7deb78c1c738 63 SNESController(PinName latch, PinName clock, PinName data):
foolsday 0:7deb78c1c738 64 latchPin(latch),
foolsday 0:7deb78c1c738 65 clockPin(clock),
foolsday 0:7deb78c1c738 66 dataPin(data) {
foolsday 0:7deb78c1c738 67 latchPin = 0;
foolsday 0:7deb78c1c738 68 clockPin = 1;
foolsday 0:7deb78c1c738 69 }
foolsday 0:7deb78c1c738 70
foolsday 0:7deb78c1c738 71
foolsday 0:7deb78c1c738 72 /**
foolsday 0:7deb78c1c738 73 * @brief Reads the current state of the controller and returns a button mask
foolsday 0:7deb78c1c738 74 *
foolsday 0:7deb78c1c738 75 * @return
foolsday 0:7deb78c1c738 76 * A 16-bit mask containing the states of all of the buttons.
foolsday 0:7deb78c1c738 77 * Pressed buttons will have their bits set to 1.
foolsday 0:7deb78c1c738 78 */
foolsday 0:7deb78c1c738 79 uint16_t read(void)
foolsday 0:7deb78c1c738 80 {
foolsday 0:7deb78c1c738 81 uint32_t mask;
foolsday 0:7deb78c1c738 82 uint16_t buttons = 0;
foolsday 0:7deb78c1c738 83
foolsday 0:7deb78c1c738 84 latchPin = 1;
foolsday 0:7deb78c1c738 85 wait_us(12);
foolsday 0:7deb78c1c738 86 latchPin = 0;
foolsday 0:7deb78c1c738 87
foolsday 0:7deb78c1c738 88 wait_us(6);
foolsday 0:7deb78c1c738 89
foolsday 0:7deb78c1c738 90 for (mask = 0x0001; mask < 0x10000; mask <<= 1)
foolsday 0:7deb78c1c738 91 {
foolsday 0:7deb78c1c738 92 clockPin = 0;
foolsday 0:7deb78c1c738 93 wait_us(6);
foolsday 0:7deb78c1c738 94
foolsday 0:7deb78c1c738 95 // Data is active low.
foolsday 0:7deb78c1c738 96 if (!dataPin)
foolsday 0:7deb78c1c738 97 {
foolsday 0:7deb78c1c738 98 buttons |= mask;
foolsday 0:7deb78c1c738 99 }
foolsday 0:7deb78c1c738 100
foolsday 0:7deb78c1c738 101 clockPin = 1;
foolsday 0:7deb78c1c738 102 wait_us(6);
foolsday 0:7deb78c1c738 103 }
foolsday 0:7deb78c1c738 104
foolsday 0:7deb78c1c738 105 return buttons;
foolsday 0:7deb78c1c738 106 }
foolsday 0:7deb78c1c738 107
foolsday 0:7deb78c1c738 108
foolsday 0:7deb78c1c738 109 /**
foolsday 0:7deb78c1c738 110 * @brief Returns true if the specified button is pressed in the given buttonMask
foolsday 0:7deb78c1c738 111 *
foolsday 0:7deb78c1c738 112 * @return
foolsday 0:7deb78c1c738 113 * True if the specified button is pressed in the mask
foolsday 0:7deb78c1c738 114 */
foolsday 0:7deb78c1c738 115 __inline bool pressed(uint16_t buttonMask, SNESButton_t button)
foolsday 0:7deb78c1c738 116 {
foolsday 0:7deb78c1c738 117 return (buttonMask & button);
foolsday 0:7deb78c1c738 118 }
foolsday 0:7deb78c1c738 119
foolsday 0:7deb78c1c738 120
foolsday 0:7deb78c1c738 121 private:
foolsday 0:7deb78c1c738 122 DigitalOut latchPin;
foolsday 0:7deb78c1c738 123 DigitalOut clockPin;
foolsday 0:7deb78c1c738 124 DigitalIn dataPin;
foolsday 0:7deb78c1c738 125 };
foolsday 0:7deb78c1c738 126
foolsday 0:7deb78c1c738 127 #endif /* #ifndef __SNES_CONTROLLER_H__*/