A small emulator for the gigatron created for the STM32F746G-DISCO and an NES wii controller

Committer:
davidr99
Date:
Thu Mar 05 01:33:52 2020 +0000
Revision:
1:4c1f3d32fceb
Emulator all one project

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davidr99 1:4c1f3d32fceb 1 /*
davidr99 1:4c1f3d32fceb 2 * WiiClassicControllerReader. A program allowing the output of one or two
davidr99 1:4c1f3d32fceb 3 * Wii Classic Controllers to be read via I2C and decoded for use, using the mbed
davidr99 1:4c1f3d32fceb 4 * microcontroller and its associated libraries.
davidr99 1:4c1f3d32fceb 5 *
davidr99 1:4c1f3d32fceb 6 * Written by Alfredo Guerrero <alfredog83@gmail.com> for the mbedGC open-source
davidr99 1:4c1f3d32fceb 7 * game console <http://www.mbedgc.com>. Based on the original code for
davidr99 1:4c1f3d32fceb 8 * the WiiNunchuckReader written by Petras Saduikis <petras@petras.co.uk>.
davidr99 1:4c1f3d32fceb 9 *
davidr99 1:4c1f3d32fceb 10 * This file is part of WiiClassicControllerReader.
davidr99 1:4c1f3d32fceb 11 *
davidr99 1:4c1f3d32fceb 12 * WiiClassicControllerReader is free software: you can redistribute it and/or modify
davidr99 1:4c1f3d32fceb 13 * it under the terms of the GNU General Public License as published by
davidr99 1:4c1f3d32fceb 14 * the Free Software Foundation, either version 3 of the License, or
davidr99 1:4c1f3d32fceb 15 * (at your option) any later version.
davidr99 1:4c1f3d32fceb 16 *
davidr99 1:4c1f3d32fceb 17 * WiiClassicControllerReader is distributed in the hope that it will be useful,
davidr99 1:4c1f3d32fceb 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
davidr99 1:4c1f3d32fceb 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
davidr99 1:4c1f3d32fceb 20 * GNU General Public License for more details.
davidr99 1:4c1f3d32fceb 21 *
davidr99 1:4c1f3d32fceb 22 * You can find a copy of the GNU General Public License at <http://www.gnu.org/licenses/>.
davidr99 1:4c1f3d32fceb 23 */
davidr99 1:4c1f3d32fceb 24
davidr99 1:4c1f3d32fceb 25 #include "WiiClassicControllerReader.h"
davidr99 1:4c1f3d32fceb 26
davidr99 1:4c1f3d32fceb 27 // constructor
davidr99 1:4c1f3d32fceb 28 WiiClassicControllerReader::WiiClassicControllerReader(PinName sda, PinName scl) :
davidr99 1:4c1f3d32fceb 29 controllerPort(sda, scl),
davidr99 1:4c1f3d32fceb 30 ljoyX(0), ljoyY(0), rjoyX(0), rjoyY(0), buttonX(0), buttonY(0), buttonA(0),
davidr99 1:4c1f3d32fceb 31 buttonB(0), buttonZL(0), buttonZR(0), buttonLT(0), buttonRT(0), buttonLC(0),
davidr99 1:4c1f3d32fceb 32 buttonRC(0), buttonHOME(0), buttonSELECT(0), buttonSTART(0), buttonDU(0),
davidr99 1:4c1f3d32fceb 33 buttonDD(0), buttonDL(0), buttonDR(0), controllerInit(false)
davidr99 1:4c1f3d32fceb 34 {
davidr99 1:4c1f3d32fceb 35 }
davidr99 1:4c1f3d32fceb 36
davidr99 1:4c1f3d32fceb 37 void WiiClassicControllerReader::RequestRead()
davidr99 1:4c1f3d32fceb 38 {
davidr99 1:4c1f3d32fceb 39 // don't expect client to remember to send an init to the nunchuck
davidr99 1:4c1f3d32fceb 40 // so do it for them here
davidr99 1:4c1f3d32fceb 41 if (!controllerInit)
davidr99 1:4c1f3d32fceb 42 {
davidr99 1:4c1f3d32fceb 43 controllerInit = ControllerInit();
davidr99 1:4c1f3d32fceb 44 }
davidr99 1:4c1f3d32fceb 45
davidr99 1:4c1f3d32fceb 46 if (controllerInit) // don't start reading if init failed
davidr99 1:4c1f3d32fceb 47 {
davidr99 1:4c1f3d32fceb 48 if (ControllerRead())
davidr99 1:4c1f3d32fceb 49 {
davidr99 1:4c1f3d32fceb 50 // only decode successful reads
davidr99 1:4c1f3d32fceb 51 ControllerDecode();
davidr99 1:4c1f3d32fceb 52 }
davidr99 1:4c1f3d32fceb 53 }
davidr99 1:4c1f3d32fceb 54 }
davidr99 1:4c1f3d32fceb 55
davidr99 1:4c1f3d32fceb 56 bool WiiClassicControllerReader::ControllerInit()
davidr99 1:4c1f3d32fceb 57 {
davidr99 1:4c1f3d32fceb 58 bool success = false;
davidr99 1:4c1f3d32fceb 59
davidr99 1:4c1f3d32fceb 60 const BYTE cmd[] = {CONTROLLER_REGADDR, 0x00};
davidr99 1:4c1f3d32fceb 61 if (I2C_OK == controllerPort.write(CONTROLLER_ADDR, (const char*)cmd, sizeof(cmd))) success = true;
davidr99 1:4c1f3d32fceb 62
davidr99 1:4c1f3d32fceb 63 return success;
davidr99 1:4c1f3d32fceb 64 }
davidr99 1:4c1f3d32fceb 65
davidr99 1:4c1f3d32fceb 66 bool WiiClassicControllerReader::ControllerRead()
davidr99 1:4c1f3d32fceb 67 {
davidr99 1:4c1f3d32fceb 68 bool success = false;
davidr99 1:4c1f3d32fceb 69
davidr99 1:4c1f3d32fceb 70 // write the address we want to read from
davidr99 1:4c1f3d32fceb 71 const BYTE cmd[] = {0x00};
davidr99 1:4c1f3d32fceb 72 if (I2C_OK == controllerPort.write(CONTROLLER_ADDR, (const char*)cmd, sizeof(cmd)))
davidr99 1:4c1f3d32fceb 73 {
davidr99 1:4c1f3d32fceb 74 // the Wii Classic Controller is non-standard I2C
davidr99 1:4c1f3d32fceb 75 // and can't manage setting the read address and immediately supplying the data
davidr99 1:4c1f3d32fceb 76 // so wait a bit
davidr99 1:4c1f3d32fceb 77 wait(I2C_READ_DELAY);
davidr99 1:4c1f3d32fceb 78
davidr99 1:4c1f3d32fceb 79 if (I2C_OK == controllerPort.read(CONTROLLER_ADDR, readBuf, sizeof(readBuf))) success = true;
davidr99 1:4c1f3d32fceb 80 }
davidr99 1:4c1f3d32fceb 81
davidr99 1:4c1f3d32fceb 82 return success;
davidr99 1:4c1f3d32fceb 83 }
davidr99 1:4c1f3d32fceb 84
davidr99 1:4c1f3d32fceb 85 bool WiiClassicControllerReader::ControllerWriteCmd()
davidr99 1:4c1f3d32fceb 86 {
davidr99 1:4c1f3d32fceb 87 bool success = false;
davidr99 1:4c1f3d32fceb 88
davidr99 1:4c1f3d32fceb 89 // write the address we want to read from
davidr99 1:4c1f3d32fceb 90 const BYTE cmd[] = {0x00};
davidr99 1:4c1f3d32fceb 91 if (I2C_OK == controllerPort.write(CONTROLLER_ADDR, (const char*)cmd, sizeof(cmd)))
davidr99 1:4c1f3d32fceb 92 {
davidr99 1:4c1f3d32fceb 93 success = true;
davidr99 1:4c1f3d32fceb 94 }
davidr99 1:4c1f3d32fceb 95
davidr99 1:4c1f3d32fceb 96 return success;
davidr99 1:4c1f3d32fceb 97 }
davidr99 1:4c1f3d32fceb 98
davidr99 1:4c1f3d32fceb 99 bool WiiClassicControllerReader::ControllerReadCmd()
davidr99 1:4c1f3d32fceb 100 {
davidr99 1:4c1f3d32fceb 101 bool success = false;
davidr99 1:4c1f3d32fceb 102
davidr99 1:4c1f3d32fceb 103 if (I2C_OK == controllerPort.read(CONTROLLER_ADDR, readBuf, sizeof(readBuf)))
davidr99 1:4c1f3d32fceb 104 {
davidr99 1:4c1f3d32fceb 105 success = true;
davidr99 1:4c1f3d32fceb 106 }
davidr99 1:4c1f3d32fceb 107
davidr99 1:4c1f3d32fceb 108 return success;
davidr99 1:4c1f3d32fceb 109 }
davidr99 1:4c1f3d32fceb 110
davidr99 1:4c1f3d32fceb 111 void WiiClassicControllerReader::ControllerDecode()
davidr99 1:4c1f3d32fceb 112 {
davidr99 1:4c1f3d32fceb 113 ljoyX = (int)readBuf[0] & MASK_LX;
davidr99 1:4c1f3d32fceb 114 ljoyY = (int)readBuf[1] & MASK_LY;
davidr99 1:4c1f3d32fceb 115 rjoyY = (int)readBuf[2] & MASK_RY;
davidr99 1:4c1f3d32fceb 116 buttonRT = (int)readBuf[3] & MASK_RT;
davidr99 1:4c1f3d32fceb 117 buttonRC = (int)readBuf[4] & MASK_RC_DL;
davidr99 1:4c1f3d32fceb 118 buttonSTART = (int)readBuf[4] & MASK_BSTART_ZR;
davidr99 1:4c1f3d32fceb 119 buttonHOME = (int)readBuf[4] & MASK_BHOME_X;
davidr99 1:4c1f3d32fceb 120 buttonSELECT = (int)readBuf[4] & MASK_BSELECT_A;
davidr99 1:4c1f3d32fceb 121 buttonLC = (int)readBuf[4] & MASK_LC_Y;
davidr99 1:4c1f3d32fceb 122 buttonDD = (int)readBuf[4] & MASK_BDD_B;
davidr99 1:4c1f3d32fceb 123 buttonDR = (int)readBuf[4] & MASK_BDR_ZL;
davidr99 1:4c1f3d32fceb 124 buttonDU = (int)readBuf[5] & MASK_BDU;
davidr99 1:4c1f3d32fceb 125 buttonDL = (int)readBuf[5] & MASK_RC_DL;
davidr99 1:4c1f3d32fceb 126 buttonZR = (int)readBuf[5] & MASK_BSTART_ZR;
davidr99 1:4c1f3d32fceb 127 buttonX = (int)readBuf[5] & MASK_BHOME_X;
davidr99 1:4c1f3d32fceb 128 buttonA = (int)readBuf[5] & MASK_BSELECT_A;
davidr99 1:4c1f3d32fceb 129 buttonY = (int)readBuf[5] & MASK_LC_Y;
davidr99 1:4c1f3d32fceb 130 buttonB = (int)readBuf[5] & MASK_BDD_B;
davidr99 1:4c1f3d32fceb 131 buttonZL = (int)readBuf[5] & MASK_BDR_ZL;
davidr99 1:4c1f3d32fceb 132
davidr99 1:4c1f3d32fceb 133 // the RjoyX axis and LT values are really 5 bit values
davidr99 1:4c1f3d32fceb 134 // so shift the 2 bit values read from the controller
davidr99 1:4c1f3d32fceb 135 // 3 bits to the right
davidr99 1:4c1f3d32fceb 136 rjoyX = ( (int)readBuf[0] & MASK_RX34 ) << 3;
davidr99 1:4c1f3d32fceb 137 buttonLT = ( (int)readBuf[2] & MASK_LT34 ) << 3;
davidr99 1:4c1f3d32fceb 138
davidr99 1:4c1f3d32fceb 139 // and for each value add bit 2, bit 1, and bit 0
davidr99 1:4c1f3d32fceb 140 // as required
davidr99 1:4c1f3d32fceb 141 if (readBuf[2] & MASK_BDR_ZL) rjoyX += 1;
davidr99 1:4c1f3d32fceb 142 if (readBuf[1] & MASK_BDD_B) rjoyX += 2;
davidr99 1:4c1f3d32fceb 143 if (readBuf[1] & MASK_BDR_ZL) rjoyX += 4;
davidr99 1:4c1f3d32fceb 144 if (readBuf[3] & MASK_LC_Y) buttonLT += 1;
davidr99 1:4c1f3d32fceb 145 if (readBuf[3] & MASK_BDD_B) buttonLT += 2;
davidr99 1:4c1f3d32fceb 146 if (readBuf[3] & MASK_BDR_ZL) buttonLT += 4;
davidr99 1:4c1f3d32fceb 147
davidr99 1:4c1f3d32fceb 148 }