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

USBHost/USBHostTypes.h

Committer:
beaglescout007
Date:
2016-04-03
Revision:
0:3dac1f1bc9e0

File content as of revision 0:3dac1f1bc9e0:

/* mbed USBHost Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef USB_INC_H
#define USB_INC_H

#include "mbed.h"
#include "toolchain.h"

enum USB_TYPE {
    USB_TYPE_OK = 0,

    // completion code
    USB_TYPE_CRC_ERROR = 1,
    USB_TYPE_BIT_STUFFING_ERROR = 2,
    USB_TYPE_DATA_TOGGLE_MISMATCH_ERROR = 3,
    USB_TYPE_STALL_ERROR = 4,
    USB_TYPE_DEVICE_NOT_RESPONDING_ERROR = 5,
    USB_TYPE_PID_CHECK_FAILURE_ERROR = 6,
    USB_TYPE_UNEXPECTED_PID_ERROR = 7,
    USB_TYPE_DATA_OVERRUN_ERROR = 8,
    USB_TYPE_DATA_UNDERRUN_ERROR = 9,
    USB_TYPE_RESERVED = 9,
    USB_TYPE_RESERVED_ = 10,
    USB_TYPE_BUFFER_OVERRUN_ERROR = 12,
    USB_TYPE_BUFFER_UNDERRUN_ERROR = 13,

    // general usb state
    USB_TYPE_DISCONNECTED = 14,
    USB_TYPE_FREE = 15,
    USB_TYPE_IDLE = 16,
    USB_TYPE_PROCESSING = 17,

    USB_TYPE_ERROR = 18,
};


enum ENDPOINT_DIRECTION {
    OUT = 1,
    IN
};

enum ENDPOINT_TYPE {
    CONTROL_ENDPOINT = 0,
    ISOCHRONOUS_ENDPOINT,
    BULK_ENDPOINT,
    INTERRUPT_ENDPOINT
};

#define AUDIO_CLASS     0x01
#define CDC_CLASS       0x02
#define HID_CLASS       0x03
#define MSD_CLASS       0x08
#define HUB_CLASS       0x09
#define SERIAL_CLASS    0x0A

#define  DEVICE_DESCRIPTOR                     (1)
#define  CONFIGURATION_DESCRIPTOR              (2)
#define  INTERFACE_DESCRIPTOR                  (4)
#define  ENDPOINT_DESCRIPTOR                   (5)
#define  HID_DESCRIPTOR                        (33)

//  ----------- Control RequestType Fields  ----------- 
#define  USB_DEVICE_TO_HOST         0x80
#define  USB_HOST_TO_DEVICE         0x00
#define  USB_REQUEST_TYPE_CLASS     0x20
#define  USB_REQUEST_TYPE_STANDARD  0x00
#define  USB_RECIPIENT_DEVICE       0x00
#define  USB_RECIPIENT_INTERFACE    0x01
#define  USB_RECIPIENT_ENDPOINT     0x02

// -------------- USB Standard Requests  -------------- 
#define  GET_STATUS                 0x00
#define  SET_FEATURE                0x03
#define  SET_ADDRESS                0x05
#define  GET_DESCRIPTOR             0x06
#define  SET_CONFIGURATION          0x09
#define  SET_INTERFACE              0x0b
#define  CLEAR_FEATURE              0x01

// -------------- USB Descriptor Length  -------------- 
#define DEVICE_DESCRIPTOR_LENGTH            0x12
#define CONFIGURATION_DESCRIPTOR_LENGTH     0x09

// PID
#define DATA0 0x03
#define DATA1 0x0b
#define ACK   0x02
#define STALL 0x0e
#define NAK   0x0a

#pragma pack(push,1)
typedef struct {
    uint8_t bLength;            
    uint8_t bDescriptorType;    
    uint16_t bcdUSB;            
    uint8_t bDeviceClass;       
    uint8_t bDeviceSubClass;    
    uint8_t bDeviceProtocol;    
    uint8_t bMaxPacketSize;     
    uint16_t idVendor;          
    uint16_t idProduct;         
    uint16_t bcdDevice;         
    uint8_t iManufacturer;      
    uint8_t iProduct;           
    uint8_t iSerialNumber;      
    uint8_t bNumConfigurations; 
} PACKED DeviceDescriptor;

typedef struct {
    uint8_t bLength;               
    uint8_t bDescriptorType;       
    uint16_t wTotalLength;         
    uint8_t bNumInterfaces;        
    uint8_t bConfigurationValue;   
    uint8_t iConfiguration;        
    uint8_t bmAttributes;          
    uint8_t bMaxPower;             
} PACKED ConfigurationDescriptor; 

typedef struct {
    uint8_t bLength;                 
    uint8_t bDescriptorType;   
    uint8_t bInterfaceNumber;  
    uint8_t bAlternateSetting; 
    uint8_t bNumEndpoints;     
    uint8_t bInterfaceClass;   
    uint8_t bInterfaceSubClass;
    uint8_t bInterfaceProtocol;
    uint8_t iInterface;        
} InterfaceDescriptor; 

typedef struct {
    uint8_t bLength;          
    uint8_t bDescriptorType;  
    uint8_t bEndpointAddress; 
    uint8_t bmAttributes;     
    uint16_t wMaxPacketSize;  
    uint8_t bInterval;        
} EndpointDescriptor;

typedef struct {
    uint8_t bDescLength;      
    uint8_t bDescriptorType;  
    uint8_t bNbrPorts;        
    uint16_t wHubCharacteristics;
    uint8_t bPwrOn2PwrGood;   
    uint8_t bHubContrCurrent; 
    uint8_t DeviceRemovable;  
    uint8_t PortPweCtrlMak;   
} HubDescriptor;              
#pragma pack(pop)

#endif