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 #include "USBHost.h"
beaglescout007 0:3dac1f1bc9e0 2
beaglescout007 0:3dac1f1bc9e0 3 #define PORT_CONNECTION 0
beaglescout007 0:3dac1f1bc9e0 4 #define PORT_ENABLE 1
beaglescout007 0:3dac1f1bc9e0 5 #define PORT_SUSPEND 2
beaglescout007 0:3dac1f1bc9e0 6 #define PORT_OVER_CURRENT 3
beaglescout007 0:3dac1f1bc9e0 7 #define PORT_RESET 4
beaglescout007 0:3dac1f1bc9e0 8 #define PORT_POWER 8
beaglescout007 0:3dac1f1bc9e0 9 #define PORT_LOW_SPEED 9
beaglescout007 0:3dac1f1bc9e0 10
beaglescout007 0:3dac1f1bc9e0 11 #define C_PORT_CONNECTION 16
beaglescout007 0:3dac1f1bc9e0 12 #define C_PORT_ENABLE 17
beaglescout007 0:3dac1f1bc9e0 13 #define C_PORT_SUSPEND 18
beaglescout007 0:3dac1f1bc9e0 14 #define C_PORT_OVER_CURRENT 19
beaglescout007 0:3dac1f1bc9e0 15 #define C_PORT_RESET 20
beaglescout007 0:3dac1f1bc9e0 16
beaglescout007 0:3dac1f1bc9e0 17 bool USBHost::Hub(USBDeviceConnected* dev) {
beaglescout007 0:3dac1f1bc9e0 18 USB_INFO("New HUB: VID:%04x PID:%04x [dev: %p]", dev->getVid(), dev->getPid(), dev);
beaglescout007 0:3dac1f1bc9e0 19 HubDescriptor hubdesc;
beaglescout007 0:3dac1f1bc9e0 20 // get HUB descriptor
beaglescout007 0:3dac1f1bc9e0 21 int rc = controlRead(dev,
beaglescout007 0:3dac1f1bc9e0 22 USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
beaglescout007 0:3dac1f1bc9e0 23 GET_DESCRIPTOR,
beaglescout007 0:3dac1f1bc9e0 24 0x29 << 8, 0, reinterpret_cast<uint8_t*>(&hubdesc),
beaglescout007 0:3dac1f1bc9e0 25 sizeof(HubDescriptor));
beaglescout007 0:3dac1f1bc9e0 26 USB_TEST_ASSERT(rc == USB_TYPE_OK);
beaglescout007 0:3dac1f1bc9e0 27 if (rc != USB_TYPE_OK) {
beaglescout007 0:3dac1f1bc9e0 28 return false;
beaglescout007 0:3dac1f1bc9e0 29 }
beaglescout007 0:3dac1f1bc9e0 30 USB_DBG_HEX((uint8_t*)&hubdesc, sizeof(hubdesc));
beaglescout007 0:3dac1f1bc9e0 31
beaglescout007 0:3dac1f1bc9e0 32 uint32_t status;
beaglescout007 0:3dac1f1bc9e0 33 rc = controlRead( dev,
beaglescout007 0:3dac1f1bc9e0 34 0xa0, 0, 0, 0, reinterpret_cast<uint8_t*>(&status), 4);
beaglescout007 0:3dac1f1bc9e0 35 USB_TEST_ASSERT(rc == USB_TYPE_OK);
beaglescout007 0:3dac1f1bc9e0 36 if (rc != USB_TYPE_OK) {
beaglescout007 0:3dac1f1bc9e0 37 return false;
beaglescout007 0:3dac1f1bc9e0 38 }
beaglescout007 0:3dac1f1bc9e0 39 USB_DBG("HUB STATUS: %08X\n", status);
beaglescout007 0:3dac1f1bc9e0 40
beaglescout007 0:3dac1f1bc9e0 41 for(int i = 1; i <= hubdesc.bNbrPorts; i++) {
beaglescout007 0:3dac1f1bc9e0 42 SetPortPower(dev, i); // power on
beaglescout007 0:3dac1f1bc9e0 43 wait_ms(hubdesc.bPwrOn2PwrGood*2);
beaglescout007 0:3dac1f1bc9e0 44 uint32_t status;
beaglescout007 0:3dac1f1bc9e0 45 GetPortStatus(dev, i, &status);
beaglescout007 0:3dac1f1bc9e0 46 USB_DBG("port: %d status: %08X\n", i, status);
beaglescout007 0:3dac1f1bc9e0 47 if (status & 0x010000) { // Connect Status Change, has changed
beaglescout007 0:3dac1f1bc9e0 48 USB_TEST_ASSERT(status & 0x000001);
beaglescout007 0:3dac1f1bc9e0 49 ClearPortFeature(dev, C_PORT_CONNECTION, i);
beaglescout007 0:3dac1f1bc9e0 50 int lowSpeed = 0;
beaglescout007 0:3dac1f1bc9e0 51 if (status & 0x0200) {
beaglescout007 0:3dac1f1bc9e0 52 lowSpeed = 1;
beaglescout007 0:3dac1f1bc9e0 53 }
beaglescout007 0:3dac1f1bc9e0 54 PortReset(dev, i);
beaglescout007 0:3dac1f1bc9e0 55 if (!addDevice(dev, i, lowSpeed)) {
beaglescout007 0:3dac1f1bc9e0 56 ClearPortPower(dev, i); // power off
beaglescout007 0:3dac1f1bc9e0 57 }
beaglescout007 0:3dac1f1bc9e0 58 } else {
beaglescout007 0:3dac1f1bc9e0 59 ClearPortPower(dev, i); // power off
beaglescout007 0:3dac1f1bc9e0 60 }
beaglescout007 0:3dac1f1bc9e0 61 }
beaglescout007 0:3dac1f1bc9e0 62 return false;
beaglescout007 0:3dac1f1bc9e0 63 }
beaglescout007 0:3dac1f1bc9e0 64
beaglescout007 0:3dac1f1bc9e0 65
beaglescout007 0:3dac1f1bc9e0 66 int USBHost::SetPortPower(USBDeviceConnected* dev, int port)
beaglescout007 0:3dac1f1bc9e0 67 {
beaglescout007 0:3dac1f1bc9e0 68 return SetPortFeature(dev, PORT_POWER, port);
beaglescout007 0:3dac1f1bc9e0 69 }
beaglescout007 0:3dac1f1bc9e0 70
beaglescout007 0:3dac1f1bc9e0 71 int USBHost::ClearPortPower(USBDeviceConnected* dev, int port)
beaglescout007 0:3dac1f1bc9e0 72 {
beaglescout007 0:3dac1f1bc9e0 73 return ClearPortFeature(dev, PORT_POWER, port);
beaglescout007 0:3dac1f1bc9e0 74 }
beaglescout007 0:3dac1f1bc9e0 75
beaglescout007 0:3dac1f1bc9e0 76 int USBHost::SetPortFeature(USBDeviceConnected* dev, int feature, int index)
beaglescout007 0:3dac1f1bc9e0 77 {
beaglescout007 0:3dac1f1bc9e0 78 return controlWrite(dev, 0x23, SET_FEATURE,feature,index,0,0);
beaglescout007 0:3dac1f1bc9e0 79 }
beaglescout007 0:3dac1f1bc9e0 80
beaglescout007 0:3dac1f1bc9e0 81 int USBHost::ClearPortFeature(USBDeviceConnected* dev, int feature, int index)
beaglescout007 0:3dac1f1bc9e0 82 {
beaglescout007 0:3dac1f1bc9e0 83 return controlWrite(dev, 0x23, CLEAR_FEATURE,feature,index,0,0);
beaglescout007 0:3dac1f1bc9e0 84 }
beaglescout007 0:3dac1f1bc9e0 85
beaglescout007 0:3dac1f1bc9e0 86 int USBHost::SetPortReset(USBDeviceConnected* dev, int port)
beaglescout007 0:3dac1f1bc9e0 87 {
beaglescout007 0:3dac1f1bc9e0 88 return SetPortFeature(dev, PORT_RESET, port);
beaglescout007 0:3dac1f1bc9e0 89 }
beaglescout007 0:3dac1f1bc9e0 90
beaglescout007 0:3dac1f1bc9e0 91 int USBHost::GetPortStatus(USBDeviceConnected* dev, int port, uint32_t* status)
beaglescout007 0:3dac1f1bc9e0 92 {
beaglescout007 0:3dac1f1bc9e0 93 return controlRead(dev, 0xa3, GET_STATUS, 0, port, (uint8_t*)status, 4);
beaglescout007 0:3dac1f1bc9e0 94 }
beaglescout007 0:3dac1f1bc9e0 95
beaglescout007 0:3dac1f1bc9e0 96 int USBHost::PortReset(USBDeviceConnected* dev, int port)
beaglescout007 0:3dac1f1bc9e0 97 {
beaglescout007 0:3dac1f1bc9e0 98 USB_DBG("%p port=%d\n", this, port);
beaglescout007 0:3dac1f1bc9e0 99 USB_TEST_ASSERT(port >= 1);
beaglescout007 0:3dac1f1bc9e0 100 SetPortReset(dev, port);
beaglescout007 0:3dac1f1bc9e0 101 // wait reset
beaglescout007 0:3dac1f1bc9e0 102 for(int i = 0; i < 100; i++) {
beaglescout007 0:3dac1f1bc9e0 103 uint32_t status;
beaglescout007 0:3dac1f1bc9e0 104 GetPortStatus(dev, port, &status);
beaglescout007 0:3dac1f1bc9e0 105 USB_DBG("RESET port: %d status: %08X\n", port, status);
beaglescout007 0:3dac1f1bc9e0 106 if (status & 0x100000) { // Reset change , Reset complete
beaglescout007 0:3dac1f1bc9e0 107 return USB_TYPE_OK;
beaglescout007 0:3dac1f1bc9e0 108 }
beaglescout007 0:3dac1f1bc9e0 109 wait_ms(5);
beaglescout007 0:3dac1f1bc9e0 110 }
beaglescout007 0:3dac1f1bc9e0 111 return USB_TYPE_ERROR;
beaglescout007 0:3dac1f1bc9e0 112 }
beaglescout007 0:3dac1f1bc9e0 113