I have ported my old project “pNesX” game console emulator to the nucleo.

Dependencies:   SDFileSystem mbed

Intro

I have ported my old project “pNesX” to the STM32 Nucleo. The pNesX is a NES emulator for the PlayStation that I have created 16 years ago!

Emulation part was almost without change, the sound part was newly added.

Parts

STM32 Nucleo F446RE
QVGA 2.2 TFT SPI (with the SD card slot)
Audio jack(TS or TRS)
USB Connector
Register 100k, 10k, 4.7k, 100
Capacitor 0.01uF, 2.2uF
Breadboard
Wires
Computer Speakers
USB GamePad

Wiring diagram

/media/uploads/beaglescout007/nucleo_ex06_emu.png

TFT J2Nucleo
VCC3V3
GNDGND
CSPB_5(D4)
ResetPA_10(D2) Pull Up(100k)
D/CPA_8(D7)
MOSIPA_7(D11)
SCKPA_5(D13)
LEDLED-100ohm-3V3
MISOPA_6(D12)
TFT J4Nucleo
SD_CSPA_9
SD_MOSIPB_15
SD_MISOPB_14
SD_SCKPB_13
AudioNucleo
TIPPA_4(A2)
USB con.Nucleo
GNDGND
+PA_12
-PA_11
5V5V

https://youtu.be/jL24IjT6LnI

Limitations

  • Since the rest of the RAM is about 50kbyte, maximum capacity of the game ROM is about 50kbyte.
  • The length of the file name up to 32 characters.
  • The number of files in the folder is up to 100.

Used Library

Committer:
beaglescout007
Date:
Sun Apr 03 07:45:29 2016 +0000
Revision:
0:3dac1f1bc9e0
Release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
beaglescout007 0:3dac1f1bc9e0 1 /* mbed USBHost Library
beaglescout007 0:3dac1f1bc9e0 2 * Copyright (c) 2006-2013 ARM Limited
beaglescout007 0:3dac1f1bc9e0 3 *
beaglescout007 0:3dac1f1bc9e0 4 * Licensed under the Apache License, Version 2.0 (the "License");
beaglescout007 0:3dac1f1bc9e0 5 * you may not use this file except in compliance with the License.
beaglescout007 0:3dac1f1bc9e0 6 * You may obtain a copy of the License at
beaglescout007 0:3dac1f1bc9e0 7 *
beaglescout007 0:3dac1f1bc9e0 8 * http://www.apache.org/licenses/LICENSE-2.0
beaglescout007 0:3dac1f1bc9e0 9 *
beaglescout007 0:3dac1f1bc9e0 10 * Unless required by applicable law or agreed to in writing, software
beaglescout007 0:3dac1f1bc9e0 11 * distributed under the License is distributed on an "AS IS" BASIS,
beaglescout007 0:3dac1f1bc9e0 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
beaglescout007 0:3dac1f1bc9e0 13 * See the License for the specific language governing permissions and
beaglescout007 0:3dac1f1bc9e0 14 * limitations under the License.
beaglescout007 0:3dac1f1bc9e0 15 */
beaglescout007 0:3dac1f1bc9e0 16
beaglescout007 0:3dac1f1bc9e0 17 #pragma once
beaglescout007 0:3dac1f1bc9e0 18 #include "mbed.h"
beaglescout007 0:3dac1f1bc9e0 19 #include "USBHALHost.h"
beaglescout007 0:3dac1f1bc9e0 20 #include "USBDeviceConnected.h"
beaglescout007 0:3dac1f1bc9e0 21 #include "IUSBEnumerator.h"
beaglescout007 0:3dac1f1bc9e0 22 #include "USBHostConf.h"
beaglescout007 0:3dac1f1bc9e0 23 #include "dbg.h"
beaglescout007 0:3dac1f1bc9e0 24 #include "myvector.h"
beaglescout007 0:3dac1f1bc9e0 25
beaglescout007 0:3dac1f1bc9e0 26 /**
beaglescout007 0:3dac1f1bc9e0 27 * USBHost class
beaglescout007 0:3dac1f1bc9e0 28 * This class is a singleton. All drivers have a reference on the static USBHost instance
beaglescout007 0:3dac1f1bc9e0 29 */
beaglescout007 0:3dac1f1bc9e0 30 class USBHost : public USBHALHost {
beaglescout007 0:3dac1f1bc9e0 31 public:
beaglescout007 0:3dac1f1bc9e0 32 /**
beaglescout007 0:3dac1f1bc9e0 33 * Static method to create or retrieve the single USBHost instance
beaglescout007 0:3dac1f1bc9e0 34 */
beaglescout007 0:3dac1f1bc9e0 35 static USBHost* getHostInst();
beaglescout007 0:3dac1f1bc9e0 36
beaglescout007 0:3dac1f1bc9e0 37 /**
beaglescout007 0:3dac1f1bc9e0 38 * Control read: setup stage, data stage and status stage
beaglescout007 0:3dac1f1bc9e0 39 *
beaglescout007 0:3dac1f1bc9e0 40 * @param dev the control read will be done for this device
beaglescout007 0:3dac1f1bc9e0 41 * @param requestType request type
beaglescout007 0:3dac1f1bc9e0 42 * @param request request
beaglescout007 0:3dac1f1bc9e0 43 * @param value value
beaglescout007 0:3dac1f1bc9e0 44 * @param index index
beaglescout007 0:3dac1f1bc9e0 45 * @param buf pointer on a buffer where will be store the data received
beaglescout007 0:3dac1f1bc9e0 46 * @param len length of the transfer
beaglescout007 0:3dac1f1bc9e0 47 *
beaglescout007 0:3dac1f1bc9e0 48 * @returns status of the control read
beaglescout007 0:3dac1f1bc9e0 49 */
beaglescout007 0:3dac1f1bc9e0 50 USB_TYPE controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len);
beaglescout007 0:3dac1f1bc9e0 51
beaglescout007 0:3dac1f1bc9e0 52 /**
beaglescout007 0:3dac1f1bc9e0 53 * Control write: setup stage, data stage and status stage
beaglescout007 0:3dac1f1bc9e0 54 *
beaglescout007 0:3dac1f1bc9e0 55 * @param dev the control write will be done for this device
beaglescout007 0:3dac1f1bc9e0 56 * @param requestType request type
beaglescout007 0:3dac1f1bc9e0 57 * @param request request
beaglescout007 0:3dac1f1bc9e0 58 * @param value value
beaglescout007 0:3dac1f1bc9e0 59 * @param index index
beaglescout007 0:3dac1f1bc9e0 60 * @param buf pointer on a buffer which will be written
beaglescout007 0:3dac1f1bc9e0 61 * @param len length of the transfer
beaglescout007 0:3dac1f1bc9e0 62 *
beaglescout007 0:3dac1f1bc9e0 63 * @returns status of the control write
beaglescout007 0:3dac1f1bc9e0 64 */
beaglescout007 0:3dac1f1bc9e0 65 USB_TYPE controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len);
beaglescout007 0:3dac1f1bc9e0 66
beaglescout007 0:3dac1f1bc9e0 67 /**
beaglescout007 0:3dac1f1bc9e0 68 * Bulk read
beaglescout007 0:3dac1f1bc9e0 69 *
beaglescout007 0:3dac1f1bc9e0 70 * @param dev the bulk transfer will be done for this device
beaglescout007 0:3dac1f1bc9e0 71 * @param ep USBEndpoint which will be used to read a packet
beaglescout007 0:3dac1f1bc9e0 72 * @param buf pointer on a buffer where will be store the data received
beaglescout007 0:3dac1f1bc9e0 73 * @param len length of the transfer
beaglescout007 0:3dac1f1bc9e0 74 * @param blocking if true, the read is blocking (wait for completion)
beaglescout007 0:3dac1f1bc9e0 75 *
beaglescout007 0:3dac1f1bc9e0 76 * @returns status of the bulk read
beaglescout007 0:3dac1f1bc9e0 77 */
beaglescout007 0:3dac1f1bc9e0 78 USB_TYPE bulkRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
beaglescout007 0:3dac1f1bc9e0 79
beaglescout007 0:3dac1f1bc9e0 80 /**
beaglescout007 0:3dac1f1bc9e0 81 * Bulk write
beaglescout007 0:3dac1f1bc9e0 82 *
beaglescout007 0:3dac1f1bc9e0 83 * @param dev the bulk transfer will be done for this device
beaglescout007 0:3dac1f1bc9e0 84 * @param ep USBEndpoint which will be used to write a packet
beaglescout007 0:3dac1f1bc9e0 85 * @param buf pointer on a buffer which will be written
beaglescout007 0:3dac1f1bc9e0 86 * @param len length of the transfer
beaglescout007 0:3dac1f1bc9e0 87 * @param blocking if true, the write is blocking (wait for completion)
beaglescout007 0:3dac1f1bc9e0 88 *
beaglescout007 0:3dac1f1bc9e0 89 * @returns status of the bulk write
beaglescout007 0:3dac1f1bc9e0 90 */
beaglescout007 0:3dac1f1bc9e0 91 USB_TYPE bulkWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
beaglescout007 0:3dac1f1bc9e0 92
beaglescout007 0:3dac1f1bc9e0 93 /**
beaglescout007 0:3dac1f1bc9e0 94 * Interrupt read
beaglescout007 0:3dac1f1bc9e0 95 *
beaglescout007 0:3dac1f1bc9e0 96 * @param dev the interrupt transfer will be done for this device
beaglescout007 0:3dac1f1bc9e0 97 * @param ep USBEndpoint which will be used to write a packet
beaglescout007 0:3dac1f1bc9e0 98 * @param buf pointer on a buffer which will be written
beaglescout007 0:3dac1f1bc9e0 99 * @param len length of the transfer
beaglescout007 0:3dac1f1bc9e0 100 * @param blocking if true, the read is blocking (wait for completion)
beaglescout007 0:3dac1f1bc9e0 101 *
beaglescout007 0:3dac1f1bc9e0 102 * @returns status of the interrupt read
beaglescout007 0:3dac1f1bc9e0 103 */
beaglescout007 0:3dac1f1bc9e0 104 USB_TYPE interruptRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
beaglescout007 0:3dac1f1bc9e0 105
beaglescout007 0:3dac1f1bc9e0 106 /**
beaglescout007 0:3dac1f1bc9e0 107 * Interrupt write
beaglescout007 0:3dac1f1bc9e0 108 *
beaglescout007 0:3dac1f1bc9e0 109 * @param dev the interrupt transfer will be done for this device
beaglescout007 0:3dac1f1bc9e0 110 * @param ep USBEndpoint which will be used to write a packet
beaglescout007 0:3dac1f1bc9e0 111 * @param buf pointer on a buffer which will be written
beaglescout007 0:3dac1f1bc9e0 112 * @param len length of the transfer
beaglescout007 0:3dac1f1bc9e0 113 * @param blocking if true, the write is blocking (wait for completion)
beaglescout007 0:3dac1f1bc9e0 114 *
beaglescout007 0:3dac1f1bc9e0 115 * @returns status of the interrupt write
beaglescout007 0:3dac1f1bc9e0 116 */
beaglescout007 0:3dac1f1bc9e0 117 USB_TYPE interruptWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
beaglescout007 0:3dac1f1bc9e0 118
beaglescout007 0:3dac1f1bc9e0 119 /**
beaglescout007 0:3dac1f1bc9e0 120 * Isochronous read
beaglescout007 0:3dac1f1bc9e0 121 *
beaglescout007 0:3dac1f1bc9e0 122 * @param dev the isochronous transfer will be done for this device
beaglescout007 0:3dac1f1bc9e0 123 * @param ep USBEndpoint which will be used to write a packet
beaglescout007 0:3dac1f1bc9e0 124 * @param buf pointer on a buffer which will be written
beaglescout007 0:3dac1f1bc9e0 125 * @param len length of the transfer
beaglescout007 0:3dac1f1bc9e0 126 * @param blocking if true, the read is blocking (wait for completion)
beaglescout007 0:3dac1f1bc9e0 127 *
beaglescout007 0:3dac1f1bc9e0 128 * @returns status of the interrupt read
beaglescout007 0:3dac1f1bc9e0 129 */
beaglescout007 0:3dac1f1bc9e0 130 USB_TYPE isochronousRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking = true);
beaglescout007 0:3dac1f1bc9e0 131
beaglescout007 0:3dac1f1bc9e0 132 /**
beaglescout007 0:3dac1f1bc9e0 133 * Enumerate a device.
beaglescout007 0:3dac1f1bc9e0 134 *
beaglescout007 0:3dac1f1bc9e0 135 * @param dev device which will be enumerated
beaglescout007 0:3dac1f1bc9e0 136 *
beaglescout007 0:3dac1f1bc9e0 137 * @returns status of the enumeration
beaglescout007 0:3dac1f1bc9e0 138 */
beaglescout007 0:3dac1f1bc9e0 139 USB_TYPE enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator);
beaglescout007 0:3dac1f1bc9e0 140
beaglescout007 0:3dac1f1bc9e0 141 /**
beaglescout007 0:3dac1f1bc9e0 142 * Get a device
beaglescout007 0:3dac1f1bc9e0 143 *
beaglescout007 0:3dac1f1bc9e0 144 * @param index index of the device which will be returned
beaglescout007 0:3dac1f1bc9e0 145 *
beaglescout007 0:3dac1f1bc9e0 146 * @returns pointer on the "index" device
beaglescout007 0:3dac1f1bc9e0 147 */
beaglescout007 0:3dac1f1bc9e0 148 USBDeviceConnected * getDevice(uint8_t index) {
beaglescout007 0:3dac1f1bc9e0 149 return index < DeviceLists.size() ? DeviceLists[index] : NULL;
beaglescout007 0:3dac1f1bc9e0 150 }
beaglescout007 0:3dac1f1bc9e0 151
beaglescout007 0:3dac1f1bc9e0 152 /**
beaglescout007 0:3dac1f1bc9e0 153 * register a driver into the host associated with a callback function called when the device is disconnected
beaglescout007 0:3dac1f1bc9e0 154 *
beaglescout007 0:3dac1f1bc9e0 155 * @param dev device
beaglescout007 0:3dac1f1bc9e0 156 * @param intf interface number
beaglescout007 0:3dac1f1bc9e0 157 * @param tptr pointer to the object to call the member function on
beaglescout007 0:3dac1f1bc9e0 158 * @param mptr pointer to the member function to be called
beaglescout007 0:3dac1f1bc9e0 159 */
beaglescout007 0:3dac1f1bc9e0 160 template<typename T>
beaglescout007 0:3dac1f1bc9e0 161 void registerDriver(USBDeviceConnected * dev, uint8_t intf, T* tptr, void (T::*mptr)(void)) {
beaglescout007 0:3dac1f1bc9e0 162 }
beaglescout007 0:3dac1f1bc9e0 163
beaglescout007 0:3dac1f1bc9e0 164 // KL46Z-USBHost extensions
beaglescout007 0:3dac1f1bc9e0 165 int interruptReadNB(USBEndpoint* ep, uint8_t* data, int size);
beaglescout007 0:3dac1f1bc9e0 166 int bulkReadNB(USBEndpoint*ep, uint8_t* data, int size);
beaglescout007 0:3dac1f1bc9e0 167 int isochronousReadNB(USBEndpoint*ep, uint8_t* data, int size);
beaglescout007 0:3dac1f1bc9e0 168
beaglescout007 0:3dac1f1bc9e0 169 /**
beaglescout007 0:3dac1f1bc9e0 170 * non-blocking processing
beaglescout007 0:3dac1f1bc9e0 171 */
beaglescout007 0:3dac1f1bc9e0 172 static void poll();
beaglescout007 0:3dac1f1bc9e0 173
beaglescout007 0:3dac1f1bc9e0 174 private:
beaglescout007 0:3dac1f1bc9e0 175 USBHost();
beaglescout007 0:3dac1f1bc9e0 176 static USBHost* inst;
beaglescout007 0:3dac1f1bc9e0 177 virtual bool addDevice(USBDeviceConnected* parent, int port, bool lowSpeed);
beaglescout007 0:3dac1f1bc9e0 178 void root_enumeration(USBDeviceConnected* dev);
beaglescout007 0:3dac1f1bc9e0 179 void parseConfDescr(USBDeviceConnected* dev, uint8_t* conf_descr, uint32_t len, IUSBEnumerator* pEnumerator);
beaglescout007 0:3dac1f1bc9e0 180 myvector<USBDeviceConnected*>DeviceLists;
beaglescout007 0:3dac1f1bc9e0 181 void task();
beaglescout007 0:3dac1f1bc9e0 182 EndpointQueue ep_queue;
beaglescout007 0:3dac1f1bc9e0 183
beaglescout007 0:3dac1f1bc9e0 184 // USB HUB
beaglescout007 0:3dac1f1bc9e0 185 bool Hub(USBDeviceConnected* dev);
beaglescout007 0:3dac1f1bc9e0 186 int SetPortPower(USBDeviceConnected* dev, int port);
beaglescout007 0:3dac1f1bc9e0 187 int ClearPortPower(USBDeviceConnected* dev, int port);
beaglescout007 0:3dac1f1bc9e0 188 int PortReset(USBDeviceConnected* dev, int port);
beaglescout007 0:3dac1f1bc9e0 189 int SetPortFeature(USBDeviceConnected* dev, int feature, int index);
beaglescout007 0:3dac1f1bc9e0 190 int ClearPortFeature(USBDeviceConnected* dev, int feature, int index);
beaglescout007 0:3dac1f1bc9e0 191 int SetPortReset(USBDeviceConnected* dev, int port);
beaglescout007 0:3dac1f1bc9e0 192 int GetPortStatus(USBDeviceConnected* dev, int port, uint32_t* status);
beaglescout007 0:3dac1f1bc9e0 193 };
beaglescout007 0:3dac1f1bc9e0 194
beaglescout007 0:3dac1f1bc9e0 195