├── README.md ├── README.txt ├── csud ├── .gitattributes ├── .gitignore ├── LICENSE ├── arguments ├── configuration │ ├── makefile.in │ └── rpi.in ├── include │ ├── configuration.h │ ├── device │ │ ├── hid │ │ │ ├── hid.h │ │ │ ├── keyboard.h │ │ │ ├── mouse.h │ │ │ └── report.h │ │ └── hub.h │ ├── hcd │ │ ├── dwc │ │ │ └── designware20.h │ │ └── hcd.h │ ├── platform │ │ ├── arm │ │ │ ├── armv6.h │ │ │ └── broadcom2835.h │ │ ├── none │ │ │ └── byteorder.h │ │ └── platform.h │ ├── types.h │ └── usbd │ │ ├── descriptors.h │ │ ├── device.h │ │ ├── devicerequest.h │ │ ├── pipe.h │ │ └── usbd.h ├── makefile ├── old │ ├── LICENSE │ ├── arguments │ ├── configuration │ │ ├── makefile.in │ │ └── rpi.in │ ├── include │ │ ├── configuration.h │ │ ├── device │ │ │ ├── hid │ │ │ │ ├── hid.h │ │ │ │ ├── keyboard.h │ │ │ │ ├── mouse.h │ │ │ │ └── report.h │ │ │ └── hub.h │ │ ├── hcd │ │ │ ├── dwc │ │ │ │ └── designware20.h │ │ │ └── hcd.h │ │ ├── platform │ │ │ ├── arm │ │ │ │ ├── armv6.h │ │ │ │ └── broadcom2835.h │ │ │ ├── none │ │ │ │ └── byteorder.h │ │ │ └── platform.h │ │ ├── types.h │ │ └── usbd │ │ │ ├── descriptors.h │ │ │ ├── device.h │ │ │ ├── devicerequest.h │ │ │ ├── pipe.h │ │ │ └── usbd.h │ ├── makefile │ ├── readme │ └── source │ │ ├── configuration.c │ │ ├── device │ │ ├── hid │ │ │ ├── hid.c │ │ │ ├── keyboard.c │ │ │ ├── makefile.in │ │ │ └── mouse.c │ │ ├── hub.c │ │ └── makefile.in │ │ ├── hcd │ │ ├── dwc │ │ │ ├── designware20.c │ │ │ ├── makefile.in │ │ │ └── roothub.c │ │ └── makefile.in │ │ ├── makefile.in │ │ ├── platform │ │ ├── arm │ │ │ ├── armv6.c │ │ │ ├── broadcom2835.c │ │ │ └── makefile.in │ │ ├── makefile.in │ │ └── platform.c │ │ └── usbd │ │ ├── makefile.in │ │ └── usbd.c ├── readme └── source │ ├── configuration.c │ ├── device │ ├── hid │ │ ├── hid.c │ │ ├── keyboard.c │ │ ├── makefile.in │ │ └── mouse.c │ ├── hub.c │ └── makefile.in │ ├── hcd │ ├── dwc │ │ ├── designware20.c │ │ ├── makefile.in │ │ └── roothub.c │ └── makefile.in │ ├── makefile.in │ ├── platform │ ├── arm │ │ ├── armv6.c │ │ ├── broadcom2835.c │ │ └── makefile.in │ ├── makefile.in │ └── platform.c │ └── usbd │ ├── makefile.in │ └── usbd.c ├── include ├── 6510.h ├── C64.h ├── C64Data.h ├── font.h ├── framebuffer.h ├── gpio.h ├── graphics.h ├── keyboard.h ├── mailbox.h ├── math.h ├── mmio.h ├── stat.h ├── stdio.h ├── string.h ├── terminal.h └── timer.h ├── libcsud.a ├── makefile ├── memorymap └── source ├── C64.c ├── C64Data.c ├── framebuffer.c ├── gpio.c ├── graphics.c ├── keyboard.c ├── mailbox.c ├── main.c ├── math.c ├── start.s ├── stdio.c ├── string.c ├── terminal.c └── timer.c /README.md: -------------------------------------------------------------------------------- 1 | Commodore-Pi 2 | ============ 3 | 4 | A native Commodore 64 emulator and operating system for the Raspberry Pi 5 | 6 | See the project page at: http://www.commodorepi.co.nr/ 7 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | This project can be built using the Yargato GNU toolchain. 2 | 3 | Project coordinator: scott.hutter@gmail.com 4 | 5 | 6 | Version history: 7 | ================ 8 | v0.01 - September 25, 2013 9 | Initial release. Code is very slow on the Rpi, and therefore difficult to 10 | test. Speed and optimization is the primary focus. 11 | 12 | v0.02 - Sept 27,2013 13 | Add cache code to startup. Runs slightly faster. 14 | 15 | Credits: 16 | ======== 17 | CSUD - the USB library for the Rpi was developed by Alex Chadderz. 18 | Comeback64 - Unsure of original author. Let me know if you do so I can provide the proper credits. -------------------------------------------------------------------------------- /csud/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /csud/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.o 3 | *.a 4 | -------------------------------------------------------------------------------- /csud/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Alex Chadwick 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /csud/arguments: -------------------------------------------------------------------------------- 1 | CSUD makefile arguments: 2 | 3 | CONFIG=(DEBUG|FINAL) 4 | DEBUG builds check more things, are more verbose, not optimise, etc. 5 | FINAL builds are faster, quieter, optimised. (default) 6 | TYPE=(STANDALONE|LOWLEVEL|DRIVER) 7 | STANDALONE builds have no external dependencies. 8 | LOWLEVEL builds have few external dependencies. (default) 9 | DRIVER builds have many external dependencies. 10 | TARGET=(RPI|NONE) 11 | RPI builds for the Raspberry Pi. Libs: ARM_V6, BCM2835, DWC. 12 | NONE builds for no system in particular. Libs: None. (default) 13 | GNU=* 14 | Specifies the cross compiler to use e.g. 'arm-none-eabi-'. Default is blank. 15 | BUILD=* 16 | Specifies the build directory. Default is 'build/'. 17 | SOURCE=* 18 | Specifies the source directory. Default is 'source/'. 19 | CONFIGDIR=* 20 | Specifies the configuration directory. Default is 'configuration/'. 21 | LIBNAME=* 22 | Specifies the target library name. Default is 'libcsud.a'. 23 | INCDIR=* 24 | Specifies the include directory. Default is 'include/'. Note, this is for 25 | the project headers, not system ones. 26 | LIB_HID=(0|1) 27 | Enables or disables the HID driver. Default specified in 28 | configuration/makefile.in. 29 | LIB_KBD=(0|1) 30 | Enables or disables the Keyboard driver. Default specified in 31 | configuration/makefile.in. 32 | LIB_HUB=(0|1) 33 | Enables or disables the Hub driver. Default specified in 34 | configuration/makefile.in. 35 | LIB_ARM_V6=(0|1) 36 | Enables or disables the ARMv6 platform code. Default is TARGET dependant. 37 | LIB_BCM2835=(0|1) 38 | Enables or disables the Broadcom2835 platform code. Default is TARGET 39 | dependant. 40 | LIB_DWC=(0|1) 41 | Enables or disables the DesignWare Core hcd. Default is TARGET dependant. -------------------------------------------------------------------------------- /csud/configuration/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(CONFIGDIR) 2 | 3 | ifeq ("$(CONFIG)", "DEBUG") 4 | CFLAGS += -DDEBUG 5 | else ifeq ("$(CONFIG)", "FINAL") 6 | CFLAGS += -DFINAL 7 | CFLAGS += -O2 8 | CFLAGS += -Wno-strict-aliasing 9 | else 10 | CFLAGS += -DCONFIG_ERROR 11 | endif 12 | 13 | ifeq ("$(TYPE)", "STANDALONE") 14 | CFLAGS += -DTYPE_STANDALONE 15 | else ifeq ("$(TYPE)", "LOWLEVEL") 16 | CFLAGS += -DTYPE_LOWLEVEL 17 | else ifeq ("$(TYPE)", "DRIVER") 18 | CFLAGS += -DTYPE_DRIVER 19 | else 20 | CFLAGS += -DTYPE_ERROR 21 | endif 22 | 23 | ifeq ("$(TARGET)", "RPI") 24 | include $(DIR)rpi.in 25 | else ifeq ("$(TARGET)", "NONE") 26 | CFLAGS += -DTARGET_NONE 27 | else 28 | CFLAGS += -DTARGET_ERROR 29 | endif 30 | 31 | LIB_HID ?= 1 32 | LIB_KBD ?= 1 33 | LIB_HUB ?= 1 34 | LIB_MOUSE ?= 1 35 | -------------------------------------------------------------------------------- /csud/configuration/rpi.in: -------------------------------------------------------------------------------- 1 | LIB_ARM_V6 ?= 1 2 | LIB_BCM2835 ?= 1 3 | LIB_DWC ?= 1 4 | CFLAGS += -DTARGET_RPI 5 | CFLAGS += -Wa,-march=armv6 6 | CFLAGS += -Wa,-mcpu=arm1176jzf-s -------------------------------------------------------------------------------- /csud/include/configuration.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * configuration.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * configuration.h contains definitions for all optional components 9 | * The makefile defines three main categories of definitions: 10 | * CONFIG: Whether or not this is a DEBUG driver 11 | * TARGET: The target system 12 | * TYPE: What sort of driver to compile (e.g. standalone) 13 | *****************************************************************************/ 14 | 15 | // Check we have a CONFIG. Valid choices are DEBUG and FINAL. If neither of 16 | // of these are specified, CONFIG_ERROR will be. If not, the haven't used the 17 | // makefile. 18 | #if defined DEBUG 19 | #elif defined FINAL 20 | #elif defined CONFIG_ERROR 21 | # error Please specify the CONFIG as either DEBUG or FINAL (default) 22 | #else 23 | # error Please ensure you compile the driver with the makefile provided 24 | #endif 25 | 26 | // Check we have a target. This should either be RPI or NONE. If neither of 27 | // these is specified, TARGET_ERROR will be. If not, the haven't used the 28 | // makefile. 29 | #if defined TARGET_RPI 30 | // Compiling for the Raspberry Pi (model B). 31 | // This is an ARM1176JZF-S, running ARMv6. 32 | // The chip is a Broadcom 2835 with a Designware OTG Core, mapped to 33 | // physical address 0x20980000 34 | # define ARM 35 | # define ARM_V6 36 | # define ENDIAN_LITTLE 37 | # define BROADCOM_2835 38 | # define HCD_DESIGNWARE_20 39 | # define HCD_DESIGNWARE_BASE ((void*)0x20980000) 40 | #elif defined TARGET_NONE 41 | // Compiling for no target architecture. This will rapidly run into errors. 42 | #elif defined TARGET_ERROR 43 | # error Please specify the TARGET as either RPI or NONE (default) 44 | #else 45 | # error Please ensure you compile the driver with the makefile provided 46 | #endif 47 | 48 | 49 | #if defined TYPE_STANDALONE 50 | // Disables all logging 51 | # define NO_LOG 52 | // Disables external memory management 53 | # define MEM_INTERNAL_MANAGER 54 | // Disables external memory reservation 55 | # define MEM_NO_RESERVE 56 | #elif defined TYPE_LOWLEVEL 57 | // Disables external memory management 58 | # define MEM_INTERNAL_MANAGER 59 | # define MEM_NO_RESERVE 60 | #elif defined TYPE_DRIVER 61 | #elif defined TYPE_ERROR 62 | # error Please specify the TYPE as either STANDALONE, LOWLEVEL (default) or DRIVER 63 | #else 64 | # error Please ensure you compile the driver with the makefile provided 65 | #endif -------------------------------------------------------------------------------- /csud/include/device/hid/hid.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * device/hid/hid.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * device/hid/hid.h contains definitions relating to generic human interface 9 | * devices. Information about the hid reports is in device/hid/report.h. 10 | ******************************************************************************/ 11 | #include 12 | #include 13 | 14 | /** 15 | \brief The human interface device descriptor information. 16 | 17 | The hid descriptor structure defined in the USB HID 1.11 manual in 6.2.1. 18 | */ 19 | struct HidDescriptor { 20 | u8 DescriptorLength; // +0x0 21 | enum DescriptorType DescriptorType : 8; // +0x1 22 | u16 HidVersion; // (bcd version) +0x2 23 | enum HidCountry { 24 | CountryNotSupported = 0, 25 | Arabic = 1, 26 | Belgian = 2, 27 | CanadianBilingual = 3, 28 | CanadianFrench = 4, 29 | CzechRepublic = 5, 30 | Danish = 6, 31 | Finnish = 7, 32 | French = 8, 33 | German = 9, 34 | Greek = 10, 35 | Hebrew = 11, 36 | Hungary = 12, 37 | International = 13, 38 | Italian = 14, 39 | Japan = 15, 40 | Korean = 16, 41 | LatinAmerican = 17, 42 | Dutch = 18, 43 | Norwegian = 19, 44 | Persian = 20, 45 | Poland= 21, 46 | Portuguese = 22, 47 | Russian = 23, 48 | Slovakian = 24, 49 | Spanish = 25, 50 | Swedish = 26, 51 | SwissFrench = 27, 52 | SwissGerman = 28, 53 | Switzerland = 29, 54 | Taiwan = 30, 55 | TurkishQ = 31, 56 | EnglishUk = 32, 57 | EnglishUs = 33, 58 | Yugoslavian = 34, 59 | TurkishF = 35, 60 | } Countrycode : 8; // +0x4 61 | u8 DescriptorCount; // +0x5 62 | struct { 63 | enum DescriptorType Type : 8; // +0x0 64 | u16 Length; // +0x1 65 | } OptionalDescriptors[]; // +0x6 (a number of optional descriptors up to DescriptorCount) 66 | }; 67 | 68 | /** 69 | \brief The possible types of hid reports. 70 | 71 | The possible hid reports defined in the USB HID 1.11 manual in 7.2.1. 72 | */ 73 | enum HidReportType { 74 | Input = 1, 75 | Output = 2, 76 | Feature = 3, 77 | }; 78 | 79 | /** The DeviceDriver field in UsbDriverDataHeader for hid devices. */ 80 | #define DeviceDriverHid 0x48494430 81 | 82 | /** 83 | \brief Hid specific data. 84 | 85 | The contents of the driver data field for hid devices. Chains to 86 | allow a stacked driver. 87 | */ 88 | struct HidDevice { 89 | struct UsbDriverDataHeader Header; 90 | struct HidDescriptor *Descriptor; 91 | struct HidParserResult *ParserResult; 92 | struct UsbDriverDataHeader *DriverData; 93 | 94 | // HID event handlers 95 | void (*HidDetached)(struct UsbDevice* device); 96 | void (*HidDeallocate)(struct UsbDevice* device); 97 | }; 98 | 99 | #define HidUsageAttachCount 10 100 | 101 | /** 102 | \brief Methods to attach an interface of particular hid desktop usage. 103 | 104 | The application desktop usage of the interface is the index into this array 105 | of methods. The array is populated by ConfigurationLoad(). 106 | */ 107 | extern Result (*HidUsageAttach[HidUsageAttachCount])(struct UsbDevice *device, u32 interfaceNumber); 108 | 109 | /** 110 | \brief Retrieves a hid report. 111 | 112 | Performs a hid get report request as defined in in the USB HID 1.11 manual 113 | in 7.2.1. 114 | */ 115 | Result HidGetReport(struct UsbDevice *device, enum HidReportType reportType, 116 | u8 reportId, u8 interface, u32 bufferLength, void* buffer); 117 | 118 | /** 119 | \brief Sends a hid report. 120 | 121 | Performs a hid set report request as defined in in the USB HID 1.11 manual 122 | in 7.2.2. 123 | */ 124 | Result HidSetReport(struct UsbDevice *device, enum HidReportType reportType, 125 | u8 reportId, u8 interface, u32 bufferLength, void* buffer); 126 | 127 | /** 128 | \brief Updates the device with the values of a report. 129 | 130 | Writes back the current values of a report in memory to the device. 131 | Implemented using HidSetReport, not interrupts. 132 | */ 133 | Result HidWriteDevice(struct UsbDevice *device, u8 report); 134 | 135 | /** 136 | \brief Updates a report with the values from the device. 137 | 138 | Reads the current values of a report from the device into memory. Implemented 139 | using HidGetReport not interrupts. 140 | */ 141 | Result HidReadDevice(struct UsbDevice *device, u8 report); 142 | 143 | /** 144 | \brief Enumerates a device as a HID device. 145 | 146 | Checks a device to see if it appears to be a HID device, and, if so, loads 147 | its hid and report descriptors to see what it can do. 148 | */ 149 | Result HidAttach(struct UsbDevice *device, u32 interfaceNumber); -------------------------------------------------------------------------------- /csud/include/device/hid/keyboard.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * device/hid/keyboard.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * device/hid/keyboard.h contains definitions relating to keyboards. 9 | ******************************************************************************/ 10 | #include 11 | #include 12 | 13 | /** 14 | \brief The current state of keyboard modifier keys. 15 | 16 | Encapsulates the current state of the keyboard modifier keys. Strucutre 17 | mimics the most common keyboard ordering. 18 | */ 19 | struct KeyboardModifiers { 20 | bool LeftControl : 1; // @0 21 | bool LeftShift : 1; // @1 22 | bool LeftAlt : 1; // @2 23 | bool LeftGui : 1; // the 'windows' key @3 24 | bool RightControl : 1; // @4 25 | bool RightShift : 1; // @5 26 | bool RightAlt : 1; // 'alt gr' @6 27 | bool RightGui : 1; // @7 28 | }; 29 | 30 | /** 31 | \brief The current state of keyboard leds. 32 | 33 | Encapsulates the current state of the keyboard leds. Strucutre mimics the 34 | most common lights and ordering. Not all keyboards may support all lights. 35 | */ 36 | struct KeyboardLeds { 37 | bool NumberLock : 1; 38 | bool CapsLock : 1; 39 | bool ScrollLock : 1; 40 | bool Compose : 1; 41 | bool Kana : 1; 42 | bool Power : 1; 43 | bool Mute : 1; 44 | bool Shift : 1; 45 | }; 46 | 47 | /** The DeviceDriver field in UsbDriverDataHeader for keyboard devices. */ 48 | #define DeviceDriverKeyboard 0x4B424430 49 | /** The maximum number of keys a keyboard can report at once. Should be 50 | multiple of 2. */ 51 | #define KeyboardMaxKeys 6 52 | 53 | /** 54 | \brief Keyboard specific data. 55 | 56 | The contents of the driver data field for keyboard devices. Placed in 57 | HidDevice, as this driver is built atop that. 58 | */ 59 | struct KeyboardDevice { 60 | /** Standard driver data header. */ 61 | struct UsbDriverDataHeader Header; 62 | /** Internal - Index in keyboard arrays. */ 63 | u32 Index; 64 | /** Number of keys currently held down. */ 65 | u32 KeyCount; 66 | /** Keys currently held down. */ 67 | u16 Keys[KeyboardMaxKeys]; 68 | /** Modifier keys currently held down. */ 69 | struct KeyboardModifiers Modifiers; 70 | /** Which LEDs this keyboard supports. */ 71 | struct KeyboardLeds LedSupport; 72 | /** Which fields in the LED report are for what LEDs. */ 73 | struct HidParserField *LedFields[8]; 74 | /** Which fields in the Input report are for what modifiers and keys. */ 75 | struct HidParserField *KeyFields[8 + 1]; 76 | /** The LED report. */ 77 | struct HidParserReport *LedReport; 78 | /** The input report. */ 79 | struct HidParserReport *KeyReport; 80 | }; 81 | 82 | /** 83 | \brief Enumerates a device as a keyboard. 84 | 85 | Checks a device already checked by HidAttach to see if it appears to be a 86 | keyboard, and, if so, builds up necessary information to enable the 87 | keyboard methods. 88 | */ 89 | Result KeyboardAttach(struct UsbDevice *device, u32 interface); 90 | 91 | /** 92 | \brief Returns the number of keyboards connected to the system. 93 | */ 94 | u32 KeyboardCount(); 95 | 96 | /** 97 | \brief Sets the keyboard LEDs to the state given in leds. 98 | 99 | Sets the keyboard LEDs to the state given in leds. Unimplemented LEDs are 100 | ignored silently. 101 | */ 102 | Result KeyboardSetLeds(u32 keyboardAddress, struct KeyboardLeds leds); 103 | 104 | /** 105 | \brief Gets a list of available keyboard LEDs. 106 | 107 | Reads the availablility of keyboard LEDs from the report descriptor. LEDs 108 | that are present are set to 1, and those than are not are set to 0. 109 | */ 110 | struct KeyboardLeds KeyboardGetLedSupport(u32 keyboardAddress); 111 | 112 | /** 113 | \brief Checks a given keyboard. 114 | 115 | Reads back the report from a given keyboard and parses it into the internal 116 | fields. These can be accessed with KeyboardGet... methods 117 | */ 118 | Result KeyboardPoll(u32 keyboardAddress); 119 | 120 | /** 121 | \brief Reads the modifier keys from a keyboard. 122 | 123 | Reads back the state of the modifier keys from the last sucessfully 124 | received report. Zeros out by default. 125 | */ 126 | struct KeyboardModifiers KeyboardGetModifiers(u32 keyboardAddress); 127 | 128 | /** 129 | \brief Returns the number of keys currently held down. 130 | 131 | Reads back the number of keys that were held down in the last report. If 132 | the keyboard reaches its key limit, this reports the last sensible report 133 | received. 134 | */ 135 | u32 KeyboardGetKeyDownCount(u32 keyboardAddress); 136 | 137 | /** 138 | \brief Returns whether or not a particular key is held down. 139 | 140 | Reads back whether or not a key was held on the last successfully received 141 | report. 142 | */ 143 | bool KeyboadGetKeyIsDown(u32 keyboardAddress, u16 key); 144 | 145 | /** 146 | \brief Returns the nth key that is held down. 147 | 148 | Reads back the number of the nth key that was held down in the last 149 | successfully received report. 150 | */ 151 | u16 KeyboardGetKeyDown(u32 keyboardAddress, u32 index); 152 | 153 | /** 154 | \brief Returns the device address of the nth connected keyboard. 155 | 156 | Keyboards that are connected are stored in an array, and this method 157 | retrieves the nth item from that array. Returns 0 on error. 158 | */ 159 | u32 KeyboardGetAddress(u32 index); -------------------------------------------------------------------------------- /csud/include/device/hid/mouse.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * device/hid/mouse.h 3 | * by Steve White 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * device/hid/mouse.h contains definitions relating to mouses. 9 | ******************************************************************************/ 10 | #include 11 | #include 12 | 13 | /** The DeviceDriver field in UsbDriverDataHeader for mouse devices. */ 14 | #define DeviceDriverMouse 0x4B424431 15 | /** The maximum number of keys a mouse can report at once. Should be 16 | multiple of 2. */ 17 | #define MouseMaxKeys 6 18 | 19 | enum MouseDeviceButton { 20 | MouseDeviceButtonLeft, 21 | MouseDeviceButtonRight, 22 | MouseDeviceButtonMiddle, 23 | MouseDeviceButtonSide, 24 | MouseDeviceButtonExtra, 25 | }; 26 | 27 | /** 28 | \brief Mouse specific data. 29 | 30 | The contents of the driver data field for mouse devices. Placed in 31 | HidDevice, as this driver is bult atop that. 32 | */ 33 | struct MouseDevice { 34 | /** Standard driver data header. */ 35 | struct UsbDriverDataHeader Header; 36 | /** Internal - Index in mouse arrays. */ 37 | u32 Index; 38 | 39 | u8 buttonState; 40 | s16 mouseX; 41 | s16 mouseY; 42 | s16 wheel; 43 | 44 | /** The input report. */ 45 | struct HidParserReport *MouseReport; 46 | }; 47 | 48 | /** 49 | \brief Enumerates a device as a mouse. 50 | 51 | Checks a device already checked by HidAttach to see if it appears to be a 52 | mouse, and, if so, bulds up necessary information to enable the 53 | mouse methods. 54 | */ 55 | Result MouseAttach(struct UsbDevice *device, u32 interface); 56 | 57 | /** 58 | \brief Returns the number of mouses connected to the system. 59 | */ 60 | u32 MouseCount(); 61 | 62 | /** 63 | \brief Checks a given mouse. 64 | 65 | Reads back the report from a given mouse and parses it into the internal 66 | fields. These can be accessed with MouseGet... methods 67 | */ 68 | Result MousePoll(u32 mouseAddress); 69 | 70 | /** 71 | \brief Returns the device address of the nth connected mouse. 72 | 73 | Mouses that are connected are stored in an array, and this method 74 | retrieves the nth item from that array. Returns 0 on error. 75 | */ 76 | u32 MouseGetAddress(u32 index); 77 | 78 | /** 79 | \brief Returns the current X coordinate of the mouse 80 | */ 81 | s16 MouseGetPositionX(u32 mouseAddress); 82 | 83 | /** 84 | \brief Returns the current Y coordinate of the mouse 85 | */ 86 | s16 MouseGetPositionY(u32 mouseAddress); 87 | 88 | /** 89 | \brief Returns the current wheel value of the mouse 90 | */ 91 | s16 MouseGetWheel(u32 mouseAddress); 92 | 93 | /** 94 | \brief Returns the current X and Y coordinates of the mouse 95 | 96 | X is in the high 16 bits, Y is in the low 16 bits 97 | */ 98 | u32 MouseGetPosition(u32 mouseAddress); 99 | 100 | /** 101 | \brief Returns the current button state of the mouse 102 | 103 | First bit : Left button 104 | Second bit: Right button 105 | Third bit : Middle button 106 | Fourth bit: Side button 107 | Fifth bit : Extra button 108 | */ 109 | u8 MouseGetButtons(u32 mouseAddress); 110 | 111 | /** 112 | \brief Returns whether or not a particular mouse button is pressed. 113 | 114 | Reads back whether or not a mouse button was pressed on the last 115 | successfully received report. 116 | */ 117 | bool MouseGetButtonIsPressed(u32 mouseAddress, enum MouseDeviceButton button); 118 | -------------------------------------------------------------------------------- /csud/include/device/hub.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * device/hub.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * device/hub.h contains definitions relating to the USB hub device. 9 | ******************************************************************************/ 10 | #include 11 | #include 12 | #include 13 | 14 | /** 15 | \brief The hub descriptor information. 16 | 17 | The hub descriptor structure defined in the USB2.0 manual section 18 | 11.23.2.1. 19 | */ 20 | struct HubDescriptor { 21 | u8 DescriptorLength; // +0x0 22 | enum DescriptorType DescriptorType : 8; // +0x1 23 | u8 PortCount; // +0x2 24 | struct { 25 | enum HubPortControl { 26 | Global = 0, 27 | Individual = 1, 28 | } PowerSwitchingMode : 2; // @0 29 | bool Compound : 1; // @2 30 | enum HubPortControl OverCurrentProtection : 2; // @3 31 | unsigned ThinkTime : 2; // in +1*8FS units @5 32 | bool Indicators : 1; // @7 33 | unsigned _reserved8_15 : 8; // @8 34 | } Attributes; // +0x3 35 | u8 PowerGoodDelay; // +0x5 36 | u8 MaximumHubPower; // +0x6 37 | u8 Data[]; // +0x7 the data consists of n bytes describing port detatchability, followed by n bytes for compatiblity. n = roundup(ports/8). 38 | } __attribute__ ((__packed__)); 39 | 40 | /** 41 | \brief Encapsulates the current status of a hub. 42 | 43 | The hub status structure defined in 11.24.2.6 of the USB2.0 44 | standard. 45 | */ 46 | struct HubStatus { 47 | bool LocalPower : 1; // @0 48 | bool OverCurrent : 1; // @1 49 | unsigned _reserved2_15 : 14; // @2 50 | }; 51 | 52 | /** 53 | \brief Encapsulates the change in current status of a hub. 54 | 55 | The hub status change structure defined in 11.24.2.6 of the USB2.0 56 | standard. 57 | */ 58 | struct HubStatusChange { 59 | bool LocalPowerChanged : 1; // @0 60 | bool OverCurrentChanged : 1; // @1 61 | unsigned _reserved2_15 : 14; // @2 62 | }; 63 | 64 | /** 65 | \brief Encapsulates the full status of a hub. 66 | 67 | The hub status structure defined in 11.24.2.6 of the USB2.0 standard. 68 | */ 69 | struct HubFullStatus { 70 | struct HubStatus Status; 71 | struct HubStatusChange Change; 72 | }; 73 | /** 74 | \brief Encapsulates the current status of a hub port. 75 | 76 | The hub port status structure defined in 11.24.2.7.1 of the USB2.0 77 | standard. 78 | */ 79 | struct HubPortStatus { 80 | bool Connected : 1; // @0 81 | bool Enabled : 1; // @1 82 | bool Suspended : 1; // @2 83 | bool OverCurrent : 1; // @3 84 | bool Reset : 1; // @4 85 | unsigned _reserved5_7 : 3; // @5 86 | bool Power : 1; // @8 87 | bool LowSpeedAttatched : 1; // @9 88 | bool HighSpeedAttatched : 1; // @10 89 | bool TestMode : 1; // @11 90 | bool IndicatorControl : 1; // @12 91 | unsigned _reserved13_15 : 3; // @13 92 | }; 93 | 94 | /** 95 | \brief Encapsulates the change in current status of a hub port. 96 | 97 | The hub port status change structure defined in 11.24.2.7.2 of the USB2.0 98 | standard. 99 | */ 100 | struct HubPortStatusChange { 101 | bool ConnectedChanged : 1; // @0 102 | bool EnabledChanged : 1; // @1 103 | bool SuspendedChanged : 1; // @2 104 | bool OverCurrentChanged : 1; // @3 105 | bool ResetChanged : 1; // @4 106 | unsigned _reserved5_15 : 11; // @5 107 | }; 108 | 109 | /** 110 | \brief Encapsulates the full status of a hub port. 111 | 112 | The hub port status structure defined in 11.24.2.7 of the USB2.0 standard. 113 | */ 114 | struct HubPortFullStatus { 115 | struct HubPortStatus Status; 116 | struct HubPortStatusChange Change; 117 | }; 118 | 119 | /** 120 | \brief A feature of a hub port. 121 | 122 | The feautres of a hub port that can be altered. 123 | */ 124 | enum HubPortFeature { 125 | FeatureConnection = 0, 126 | FeatureEnable = 1, 127 | FeatureSuspend = 2, 128 | FeatureOverCurrent = 3, 129 | FeatureReset = 4, 130 | FeaturePower = 8, 131 | FeatureLowSpeed = 9, 132 | FeatureHighSpeed = 10, 133 | FeatureConnectionChange = 16, 134 | FeatureEnableChange = 17, 135 | FeatureSuspendChange = 18, 136 | FeatureOverCurrentChange = 19, 137 | FeatureResetChange = 20, 138 | }; 139 | 140 | /** The DeviceDriver field in UsbDriverDataHeader for hubs. */ 141 | #define DeviceDriverHub 0x48554230 142 | 143 | /** 144 | \brief Hub specific data. 145 | 146 | The contents of the driver data field for hubs. 147 | */ 148 | struct HubDevice { 149 | struct UsbDriverDataHeader Header; 150 | struct HubFullStatus Status; 151 | struct HubDescriptor *Descriptor; 152 | u32 MaxChildren; 153 | struct HubPortFullStatus PortStatus[MaxChildrenPerDevice]; 154 | struct UsbDevice *Children[MaxChildrenPerDevice]; 155 | }; 156 | 157 | /** 158 | \brief A feature of a hub. 159 | 160 | The feautres of a hub that can be altered. 161 | */ 162 | enum HubFeature { 163 | FeatureHubPower = 0, 164 | FeatureHubOverCurrent = 1, 165 | }; 166 | 167 | 168 | /** 169 | \brief Performs all necesary hub related initialisation. 170 | 171 | Loads a hub device and enumerates its children. 172 | */ 173 | Result HubAttach(struct UsbDevice *device, u32 interfaceNumber); 174 | 175 | /** 176 | \brief Resets a port on a hub. 177 | 178 | Resets a port on a hub. No validation. 179 | */ 180 | Result HubPortReset(struct UsbDevice *device, u8 port); 181 | 182 | /** 183 | \brief Checks the connection status of a port. 184 | 185 | Checks for a change in the connection status of a port. If it has changed 186 | performs necessary actions such as enumerating a new device or deallocating 187 | an old one. 188 | */ 189 | Result HubCheckConnection(struct UsbDevice *device, u8 port); 190 | 191 | /** 192 | \brief Checks all hubs for new devices. 193 | 194 | Recursively checks the hub tree for new devices being attached, and for old 195 | devices being removed. 196 | */ 197 | void HubRecursiveCheck(struct UsbDevice *device); -------------------------------------------------------------------------------- /csud/include/hcd/dwc/designware20.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlar54/Commodore-Pi/41aa2a1e4a802a9f9dfca3e2a913926cdb0c1870/csud/include/hcd/dwc/designware20.h -------------------------------------------------------------------------------- /csud/include/hcd/hcd.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * hcd/hcd.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * hcd/hcd.h contains definitions relating to the host controller driver of 9 | * the USB implementation. 10 | ******************************************************************************/ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /** 18 | \brief Intialises the host controller driver for this hardware. 19 | 20 | Initialises the core on whatever hardware is in use. 21 | */ 22 | Result HcdInitialise(); 23 | 24 | /** 25 | \brief Starts the host controller driver working. 26 | 27 | Starts the host controller driver working. It should start processing 28 | communications and be ready for commands. 29 | */ 30 | Result HcdStart(); 31 | 32 | /** 33 | \brief Stops the host controller driver working. 34 | 35 | Stops the host controller driver working. This should close all connections 36 | and return the Hcd to a state such that a subsequent call to StopHcd would 37 | restart everything. This could be to update parameters, fix a fault, etc. 38 | */ 39 | Result HcdStop(); 40 | 41 | /** 42 | \brief Uninitialises the host controller driver. 43 | 44 | Unitialises the host controller driver. This should be called when the 45 | driver is to be complete removed. It should power off any hardware, and 46 | and return the driver to a point such that a subsequent call to 47 | InitialiseHcd would restart it. 48 | */ 49 | Result HcdDeinitialise(); 50 | 51 | /** 52 | \brief Sends a control message to a device. 53 | 54 | Sends a control message to a device. Handles all necessary channel creation 55 | and other processing. The sequence of a control transfer is defined in the 56 | USB 2.0 manual section 5.5. The host sends a setup packet (request) then 57 | zero or more data packets are sent or received (to buffer, max length 58 | bufferLength) and finally a status message is sent to conclude the 59 | transaction. Packets larger than pipe.MaxSize are split. For low speed 60 | devices pipe.MaxSize must be Bits8, and Bits64 for high speed. Low and full 61 | speed transactions are always split. 62 | */ 63 | Result HcdSumbitControlMessage(struct UsbDevice *device, 64 | struct UsbPipeAddress pipe, void* buffer, u32 bufferLength, 65 | struct UsbDeviceRequest *request); 66 | 67 | #include "dwc/designware20.h" 68 | -------------------------------------------------------------------------------- /csud/include/platform/arm/armv6.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * platform/arm/armv6.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * platform/arm/armv6.h contains definitions for arm version 6 processors. 9 | ******************************************************************************/ 10 | #include 11 | #include 12 | -------------------------------------------------------------------------------- /csud/include/platform/arm/broadcom2835.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * platform/arm/broadcom2835.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * platform/arm/broadcom2835.h contains definitions pertaining to the 9 | * broadcom2835 chip, used in the Raspberry Pi. 10 | ******************************************************************************/ 11 | 12 | #include 13 | 14 | /** The null address. */ 15 | #define NULL ((void*)0) 16 | #ifdef MEM_INTERNAL_MANAGER 17 | // When asked to use internal memory management, we use the default. 18 | #define MEM_INTERNAL_MANAGER_DEFAULT 19 | #endif -------------------------------------------------------------------------------- /csud/include/platform/none/byteorder.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * platform/none/byteorder.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * platform/none/byteorder.h contains generic definitions for changing the 9 | * byte order of halfs to match the processor. 10 | ******************************************************************************/ 11 | #include 12 | #include 13 | 14 | #if defined ENDIAN_BIG 15 | /** 16 | Converts a number from the machine's byte order to big endian or back. 17 | */ 18 | #define EndianBigWord(x) x 19 | /** 20 | Converts a number from the machine's byte order to little endian or back. 21 | */ 22 | #define EndianLittleWord(x) ({ u32 t = x; (t >> 24) & 0xff | (t >> 8) & 0xff00 | (t << 8) & 0xff00 | (t << 24) & 0xff000000; }) 23 | /** 24 | Converts a number from the machine's byte order to big endian or back. 25 | */ 26 | #define EndianBigHalf(x) x 27 | /** 28 | Converts a number from the machine's byte order to little endian or back. 29 | */ 30 | #define EndianLittleHalf(x) ({ u16 t = x; (t >> 8) & 0xff | (t << 8) & 0xff00; }) 31 | #elif defined ENDIAN_LITTLE 32 | /** 33 | Converts a number from the machine's byte order to big endian or back. 34 | */ 35 | #define EndianBigWord(x) ({ u32 t = x; (t >> 24) & 0xff | (t >> 8) & 0xff00 | (t << 8) & 0xff0000 | (t << 24) & 0xff000000; }) 36 | /** 37 | Converts a number from the machine's byte order to little endian or back. 38 | */ 39 | #define EndianLittleWord(x) x 40 | /** 41 | Converts a number from the machine's byte order to big endian or back. 42 | */ 43 | #define EndianBigHalf(x) ({ u16 t = x; (t >> 8) & 0xff | (t << 8) & 0xff00; }) 44 | /** 45 | Converts a number from the machine's byte order to little endian or back. 46 | */ 47 | #define EndianLittleHalf(x) x 48 | #else 49 | #error Endianness not specified. 50 | #endif -------------------------------------------------------------------------------- /csud/include/platform/platform.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * platform/platform.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * platform/platform.h contains definitions pertaining to the platform that 9 | * the system will run on. 10 | ******************************************************************************/ 11 | 12 | #ifndef _PLATFORM_H 13 | #define _PLATFORM_H 14 | 15 | #include 16 | #include 17 | 18 | /** 19 | \brief Allocates memory of specified length. 20 | 21 | Allocates memory of length at least length to the driver and returns the 22 | address. If MEM_INTERNAL_MANAGER is defined, then all platforms must 23 | provide an implementation which calls MemoryReserve. Can return NULL on 24 | error. 25 | */ 26 | void* MemoryAllocate(u32 length); 27 | /** 28 | \brief Deallocates memory of specified address, previously allocated by 29 | MemoryAllocate. 30 | 31 | Deallocates memory of the specified address that was previously allocated 32 | by MemoryAllocate. If MEM_INTERNAL_MANAGER is defined, then all platforms 33 | must provide an implementation. Calling with an address not received from 34 | MemoryAllocate produces undefined results. 35 | */ 36 | void MemoryDeallocate(void* address); 37 | /** 38 | \brief Notifies the system of memory usage. 39 | 40 | Notifies the parent system of an unavoidable memory usage. This is 41 | typically used for memory mapped IO systems, in which certain addresses 42 | have special meaning. It is up to the parent system to implement whatever 43 | must be done. The return value should be a virtual address that maps to 44 | the requested physical address, or NULL on error. If MEM_NO_RESERVE is 45 | defined, a dummy implementation is created. 46 | */ 47 | void* MemoryReserve(u32 length, void* physicalAddress); 48 | /** 49 | \brief Copies chunks of memory. 50 | 51 | Copies length bytes from source to destinatoin. If either source or 52 | destination are null, should not copy anything. 53 | */ 54 | void MemoryCopy(void* destination, void* source, u32 length); 55 | 56 | #ifdef NO_LOG 57 | #define LOG(x) 58 | #define LOGL(x, len) 59 | #define LOGF(x, ...) 60 | #define LOGFL(x, len, ...) 61 | #else 62 | /** 63 | \brief Notifies the user of progress. 64 | 65 | Notifies the parent system of progress loading the driver. Messages may be 66 | displayed to a semi-technically competant user. 67 | */ 68 | void LogPrint(char* message, u32 messageLength); 69 | /** 70 | \brief Notifies the user of progress. 71 | 72 | Prints our a formatted string. Uses all the formtting options in printf. 73 | Implemented in platform.c, by calling LogPrint. Messages truncated to 160 74 | characters. 75 | */ 76 | void LogPrintF(char* format, u32 formatLength, ...); 77 | 78 | #define LOG(x) (LogPrint(x, sizeof(x))) 79 | #define LOGL(x, len) (LogPrint(x, len)) 80 | #define LOGF(x, ...) (LogPrintF(x, sizeof(x), __VA_ARGS__)) 81 | #define LOGFL(x, len, ...) (LogPrintF(x, len, __VA_ARGS__)) 82 | #endif 83 | #ifdef DEBUG 84 | #define LOG_DEBUG(x) LOG(x) 85 | #define LOG_DEBUGL(x, len) LOGL(x, len) 86 | #define LOG_DEBUGF(x, ...) LOGF(x, __VA_ARGS__) 87 | #define LOG_DEBUGFL(x, len, ...) LOGFL(x, len, __VA_ARGS__) 88 | #else 89 | #define LOG_DEBUG(x) 90 | #define LOG_DEBUGL(x, len) 91 | #define LOG_DEBUGF(x, ...) 92 | #define LOG_DEBUGFL(x, len, ...) 93 | #endif 94 | 95 | /** 96 | \brief Turns on the USB host controller. 97 | 98 | Notifies the parent system that the USB contorller now requires power. 99 | */ 100 | Result PowerOnUsb(); 101 | /** 102 | \brief Turns on the USB host controller. 103 | 104 | Notifies the parent system that the USB contorller no longer requires power. 105 | */ 106 | void PowerOffUsb(); 107 | 108 | /** 109 | \brief Delays for delay microseconds. 110 | 111 | Delays for a number of microseconds. 112 | */ 113 | void MicroDelay(u32 delay); 114 | 115 | 116 | #ifdef ARM 117 | # ifdef ARM_V6 118 | # include "arm/armv6.h" 119 | # ifdef BROADCOM_2835 120 | # include "arm/broadcom2835.h" 121 | # endif // BROADCOM_2835 122 | # else 123 | # error Unrecognised ARM Version 124 | # endif // ARM_V6 125 | #else 126 | #error Unrecognised Processor Family 127 | #endif // ARM 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /csud/include/types.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * types.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * types.h contains definitions of standardised types used ubiquitously. 9 | ******************************************************************************/ 10 | #ifndef _TYPES_H 11 | #define _TYPES_H 12 | 13 | /** Unsigned 8 bit type */ 14 | typedef unsigned char u8; 15 | /** Unsigned 16 bit type */ 16 | typedef unsigned short u16; 17 | /** Unsigned 32 bit type */ 18 | typedef unsigned int u32; 19 | /** Unsigned 64 bit type */ 20 | typedef unsigned long long u64; 21 | /** Signed 8 bit type */ 22 | typedef signed char s8; 23 | /** Signed 16 bit type */ 24 | typedef signed short s16; 25 | /** Signed 32 bit type */ 26 | typedef signed int s32; 27 | /** Signed 64 bit type */ 28 | typedef signed long long s64; 29 | 30 | /** One bit truth value */ 31 | typedef enum { 32 | false = 0, 33 | true = 1, 34 | } bool; 35 | 36 | /** 37 | \brief Result of a method call. 38 | 39 | Negative results are errors. 40 | OK is for a general success. 41 | ErrorGeneral is an undisclosed failure. 42 | ErrorArgument is a bad input. 43 | ErrorRetry is a temporary issue that may disappear, the method should be rerun 44 | without modification (the caller is expected to limit number of retries as 45 | required). 46 | ErrorDevice is a more permenant hardware error (a reset procedure should be 47 | enacted before retrying). 48 | ErrorIncompatible is a device driver that will not support the detected 49 | device. 50 | ErrorCompiler is a problem with the configuration of the compiler generating 51 | unusable code. 52 | ErrorMemory is used when the memory is exhausted. 53 | ErrorTimeout is used when a maximum delay is reached when waiting and an 54 | operation is unfinished. This does not necessarily mean the operationg 55 | will not finish, just that it is unreasonably slow. 56 | ErrorDisconnected is used when a device is disconnected in transfer. 57 | */ 58 | typedef enum { 59 | OK = 0, 60 | ErrorGeneral = -1, 61 | ErrorArgument = -2, 62 | ErrorRetry = -3, 63 | ErrorDevice = -4, 64 | ErrorIncompatible = -5, 65 | ErrorCompiler = -6, 66 | ErrorMemory = -7, 67 | ErrorTimeout = -8, 68 | ErrorDisconnected = -9, 69 | } Result; 70 | 71 | /** 72 | \brief Direction of USB communication. 73 | 74 | Many and various parts of the USB standard use this 1 bit field to indicate 75 | in which direction information flows. 76 | */ 77 | typedef enum { 78 | HostToDevice = 0, 79 | Out = 0, 80 | DeviceToHost = 1, 81 | In = 1, 82 | } UsbDirection; 83 | 84 | /** 85 | \brief Speed of USB communication. 86 | 87 | Many and various parts of the USB standard use this 2 bit field to indicate 88 | in which direction information flows. 89 | */ 90 | typedef enum { 91 | High = 0, 92 | Full = 1, 93 | Low = 2, 94 | } UsbSpeed; 95 | 96 | static inline char* SpeedToChar(UsbSpeed speed) { 97 | if (speed == High) return "480 Mb/s"; 98 | else if (speed == Low) return "1.5 Mb/s"; 99 | else if (speed == Full) return "12 Mb/s"; 100 | else return "Unknown Mb/s"; 101 | } 102 | 103 | /** 104 | \brief Transfer type in USB communication. 105 | 106 | Many and various parts of the USB standard use this 2 bit field to indicate 107 | in what type of transaction to use. 108 | */ 109 | typedef enum { 110 | Control = 0, 111 | Isochronous = 1, 112 | Bulk = 2, 113 | Interrupt = 3, 114 | } UsbTransfer; 115 | 116 | /** 117 | \brief Transfer size in USB communication. 118 | 119 | Many and various parts of the USB standard use this 2 bit field to indicate 120 | in what size of transaction to use. 121 | */ 122 | typedef enum { 123 | Bits8, 124 | Bits16, 125 | Bits32, 126 | Bits64, 127 | } UsbPacketSize; 128 | 129 | static inline UsbPacketSize SizeFromNumber(u32 size) { 130 | if (size <= 8) return Bits8; 131 | else if (size <= 16) return Bits16; 132 | else if (size <= 32) return Bits32; 133 | else return Bits64; 134 | } 135 | static inline u32 SizeToNumber(UsbPacketSize size) { 136 | if (size == Bits8) return 8; 137 | else if (size == Bits16) return 16; 138 | else if (size == Bits32) return 32; 139 | else return 64; 140 | } 141 | 142 | /** 143 | \brief Returns the minimum of two inputs. 144 | 145 | Returns the minimum of two inputs, ensuring only one evaluation of each. To 146 | do so, the type must be supplied. 147 | */ 148 | #define Min(x, y, type) ({ type __x = (x); type __y = (y); __x < __y ? __x : __y; }) 149 | /** 150 | \brief Returns the maximum of two inputs. 151 | 152 | Returns the maximum of two inputs, ensuring only one evaluation of each. To 153 | do so, the type must be supplied. 154 | */ 155 | #define Max(x, y, type) ({ type __x = (x); type __y = (y); __x < __y ? __y : __x; }) 156 | 157 | #endif // _TYPES_H -------------------------------------------------------------------------------- /csud/include/usbd/descriptors.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * usbd/descriptors.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * usbd/descriptors.h contains structures defined in the USB standard that 9 | * describe various aspects of USB. 10 | ******************************************************************************/ 11 | #ifndef _USBD_DESCRIPTORS_H 12 | #define _USBD_DESCRIPTORS_H 13 | 14 | #include 15 | 16 | /** 17 | \brief The descriptor type field from the header of USB descriptors. 18 | 19 | The descriptor type in the header of all USB descriptor sturctures defined 20 | in the USB 2.0 manual in 9.6. 21 | */ 22 | enum DescriptorType { 23 | Device = 1, 24 | Configuration = 2, 25 | String = 3, 26 | Interface = 4, 27 | Endpoint = 5, 28 | DeviceQualifier = 6, 29 | OtherSpeedConfiguration = 7, 30 | InterfacePower = 8, 31 | Hid = 33, 32 | HidReport = 34, 33 | HidPhysical = 35, 34 | Hub = 41, 35 | }; 36 | 37 | /** 38 | \brief The header of USB descriptor information. 39 | 40 | The header of all USB descriptor sturctures defined in the USB 2.0 manual 41 | in 9.6. 42 | */ 43 | struct UsbDescriptorHeader { 44 | u8 DescriptorLength; // +0x0 45 | enum DescriptorType DescriptorType : 8; // +0x1 46 | }; 47 | 48 | /** 49 | \brief The device descriptor information. 50 | 51 | The device descriptor sturcture defined in the USB 2.0 manual in 9.6.1. 52 | */ 53 | struct UsbDeviceDescriptor { 54 | u8 DescriptorLength; // +0x0 55 | enum DescriptorType DescriptorType : 8; // +0x1 56 | u16 UsbVersion; // (in BCD 0x210 = USB2.10) +0x2 57 | enum DeviceClass { 58 | DeviceClassInInterface = 0x00, 59 | DeviceClassCommunications = 0x2, 60 | DeviceClassHub = 0x9, 61 | DeviceClassDiagnostic = 0xdc, 62 | DeviceClassMiscellaneous = 0xef, 63 | DeviceClassVendorSpecific = 0xff, 64 | } Class : 8; // +0x4 65 | u8 SubClass; // +0x5 66 | u8 Protocol; // +0x6 67 | u8 MaxPacketSize0; // +0x7 68 | u16 VendorId; // +0x8 69 | u16 ProductId; // +0xa 70 | u16 Version; // +0xc 71 | u8 Manufacturer; // +0xe 72 | u8 Product; // +0xf 73 | u8 SerialNumber; // +0x10 74 | u8 ConfigurationCount; // +0x11 75 | } __attribute__ ((__packed__)); 76 | 77 | /** 78 | \brief The device qualifier descriptor information. 79 | 80 | The device descriptor qualifier sturcture defined in the USB 2.0 manual in 81 | 9.6.2. 82 | */ 83 | struct UsbDeviceQualifierDescriptor { 84 | u8 DescriptorLength; // +0x0 85 | enum DescriptorType DescriptorType : 8; // +0x1 86 | u16 UsbVersion; // (in BCD 0x210 = USB2.10) +0x2 87 | enum DeviceClass Class : 8; // +0x4 88 | u8 SubClass; // +0x5 89 | u8 Protocol; // +0x6 90 | u8 MaxPacketSize0; // +0x7 91 | u8 ConfigurationCount; // +0x8 92 | u8 _reserved9; // +0x9 93 | } __attribute__ ((__packed__)); 94 | 95 | /** 96 | \brief The configuration descriptor information. 97 | 98 | The configuration descriptor structure defined in the USB2.0 manual section 99 | 9.6.3. 100 | */ 101 | struct UsbConfigurationDescriptor { 102 | u8 DescriptorLength; // +0x0 103 | enum DescriptorType DescriptorType : 8; // +0x1 104 | u16 TotalLength; // +0x2 105 | u8 InterfaceCount; // +0x4 106 | u8 ConfigurationValue; // +0x5 107 | u8 StringIndex; // +0x6 108 | struct { 109 | unsigned _reserved0_4 : 5; // @0 110 | bool RemoteWakeup : 1; // @5 111 | bool SelfPowered : 1; // @6 112 | unsigned _reserved7 : 1; // @7 113 | } Attributes; // +0x7 114 | u8 MaximumPower; // +0x8 115 | } __attribute__ ((__packed__)); 116 | 117 | /** 118 | \breif The other speed configuration descriptor. 119 | 120 | The other speed configuration descriptor defined in the USB2.0 manual section 121 | 9.6.4. 122 | */ 123 | struct UsbOtherSpeedConfigurationDescriptor { 124 | u8 DescriptorLength; // +0x0 125 | enum DescriptorType DescriptorType : 8; // +0x1 126 | u16 TotalLength; // +0x2 127 | u8 InterfaceCount; // +0x4 128 | u8 ConfigurationValue; // +0x5 129 | u8 StringIndex; // +0x6 130 | struct { 131 | unsigned _reserved0_4 : 5; // @0 132 | bool RemoteWakeup : 1; // @5 133 | bool SelfPowered : 1; // @6 134 | enum { 135 | Valid = 1, 136 | } _reserved7 : 1; // @7 137 | } Attributes; // +0x7 138 | u8 MaximumPower; // +0x8 139 | } __attribute__ ((__packed__)); 140 | 141 | /** 142 | \brief The interface descriptor information. 143 | 144 | The interface descriptor structure defined in the USB2.0 manual section 145 | 9.6.5. 146 | */ 147 | struct UsbInterfaceDescriptor { 148 | u8 DescriptorLength; // +0x0 149 | enum DescriptorType DescriptorType : 8; // +0x1 150 | u8 Number; // +0x2 151 | u8 AlternateSetting; // +0x3 152 | u8 EndpointCount; // +0x4 153 | enum InterfaceClass { 154 | InterfaceClassReserved = 0x0, 155 | InterfaceClassAudio = 0x1, 156 | InterfaceClassCommunications = 0x2, 157 | InterfaceClassHid = 0x3, 158 | InterfaceClassPhysical = 0x5, 159 | InterfaceClassImage = 0x6, 160 | InterfaceClassPrinter = 0x7, 161 | InterfaceClassMassStorage = 0x8, 162 | InterfaceClassHub = 0x9, 163 | InterfaceClassCdcData = 0xa, 164 | InterfaceClassSmartCard = 0xb, 165 | InterfaceClassContentSecurity = 0xd, 166 | InterfaceClassVideo = 0xe, 167 | InterfaceClassPersonalHealthcare = 0xf, 168 | InterfaceClassAudioVideo = 0x10, 169 | InterfaceClassDiagnosticDevice = 0xdc, 170 | InterfaceClassWirelessController = 0xe0, 171 | InterfaceClassMiscellaneous = 0xef, 172 | InterfaceClassApplicationSpecific = 0xfe, 173 | InterfaceClassVendorSpecific = 0xff, 174 | } Class : 8; // +x05 175 | u8 SubClass; 176 | u8 Protocol; 177 | u8 StringIndex; 178 | } __attribute__ ((__packed__)); 179 | 180 | /** 181 | \brief The endpoint descriptor information. 182 | 183 | The endpoint descriptor structure defined in the USB2.0 manual section 184 | 9.6.6. 185 | */ 186 | struct UsbEndpointDescriptor { 187 | u8 DescriptorLength; // +0x0 188 | enum DescriptorType DescriptorType : 8; // +0x1 189 | struct { 190 | unsigned Number : 4; // @0 191 | unsigned _reserved4_6 : 3; // @4 192 | UsbDirection Direction : 1; // @7 193 | } EndpointAddress; // +0x2 194 | struct { 195 | UsbTransfer Type : 2; // @0 196 | enum { 197 | NoSynchronisation = 0, 198 | Asynchronous = 1, 199 | Adaptive = 2, 200 | Synchrouns = 3, 201 | } Synchronisation : 2; // @2 202 | enum { 203 | Data = 0, 204 | Feeback = 1, 205 | ImplicitFeebackData = 2, 206 | } Usage : 2; // @4 207 | unsigned _reserved6_7 : 2; // @6 208 | } Attributes; // +0x3 209 | struct { 210 | unsigned MaxSize : 11; // @0 211 | enum { 212 | None = 0, 213 | Extra1 = 1, 214 | Extra2 = 2, 215 | } Transactions : 2; // @11 216 | unsigned _reserved13_15 : 3; // @13 217 | } Packet; // +0x4 218 | u8 Interval; // +0x6 219 | } __attribute__ ((__packed__)); 220 | 221 | /** 222 | \brief The string descriptor information. 223 | 224 | The string descriptor structure defined in the USB2.0 manual section 225 | 9.6.7. 226 | */ 227 | struct UsbStringDescriptor { 228 | u8 DescriptorLength; // +0x0 229 | enum DescriptorType DescriptorType : 8; // +0x1 230 | u16 Data[]; // +0x2 amount varies 231 | } __attribute__ ((__packed__)); 232 | 233 | #endif // _USBD_DESCRIPTORS_H -------------------------------------------------------------------------------- /csud/include/usbd/device.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * usbd/device.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * usbd/device.h contains a definition of a device structure used for 9 | * storing devices and the device tree. 10 | ******************************************************************************/ 11 | #ifndef _DEVICE_H 12 | #define _DEVICE_H 13 | 14 | #include 15 | #include 16 | 17 | /** 18 | \brief The maximum number of children a device could have, by implication, this is 19 | the maximum number of ports a hub supports. 20 | 21 | This is theoretically 255, as 8 bits are used to transfer the port count in 22 | a hub descriptor. Practically, no hub has more than 10, so we instead allow 23 | that many. Increasing this number will waste space, but will not have 24 | adverse consequences up to 255. Decreasing this number will save a little 25 | space in the HubDevice structure, at the risk of removing support for an 26 | otherwise valid hub. 27 | */ 28 | #define MaxChildrenPerDevice 10 29 | /** 30 | \brief The maximum number of interfaces a device configuration could have. 31 | 32 | This is theoretically 255 as one byte is used to transfer the interface 33 | count in a configuration descriptor. In practice this is unlikely, so we 34 | allow an arbitrary 8. Increasing this number wastes (a lot) of space in 35 | every device structure, but should not have other consequences up to 255. 36 | Decreasing this number reduces the overheads of the UsbDevice structure, at 37 | the cost of possibly rejecting support for an otherwise supportable device. 38 | */ 39 | #define MaxInterfacesPerDevice 8 40 | /** 41 | \brief The maximum number of endpoints a device could have (per interface). 42 | 43 | This is theoretically 16, as four bits are used to transfer the endpoint 44 | number in certain device requests. This is possible in practice, so we 45 | allow that many. Decreasing this number reduces the space in each device 46 | structure considerably, while possible removing support for otherwise valid 47 | devices. This number should not be greater than 16. 48 | */ 49 | #define MaxEndpointsPerDevice 16 50 | 51 | /** 52 | \brief Status of a USB device. 53 | 54 | Stores the status of a USB device. Statuses as defined in 9.1 of the USB2.0 55 | manual. 56 | */ 57 | enum UsbDeviceStatus { 58 | Attached = 0, 59 | Powered = 1, 60 | Default = 2, 61 | Addressed = 3, 62 | Configured = 4, 63 | }; 64 | 65 | 66 | /** 67 | \brief Status of a USB transfer. 68 | 69 | Stores the status of the last transfer a USB device did. 70 | */ 71 | enum UsbTransferError { 72 | NoError = 0, 73 | Stall = 1 << 1, 74 | BufferError = 1 << 2, 75 | Babble = 1 << 3, 76 | NoAcknowledge = 1 << 4, 77 | CrcError = 1 << 5, 78 | BitError = 1 << 6, 79 | ConnectionError = 1 << 7, 80 | AhbError = 1 << 8, 81 | NotYetError = 1 << 9, 82 | Processing = 1 << 31 83 | }; 84 | 85 | /** 86 | \brief Start of a device specific data field. 87 | 88 | The first two words of driver data in a UsbDevice. The DeviceDriver field 89 | is a code which uniquely identifies the driver that set the driver data 90 | field (i.e. the lowest driver in the stack above the USB driver). The 91 | DataSize is the size in bytes of the device specific data field. 92 | */ 93 | struct UsbDriverDataHeader { 94 | u32 DeviceDriver; 95 | u32 DataSize; 96 | }; 97 | 98 | /** 99 | \brief Structure to store the details of a USB device that has been 100 | detectd. 101 | 102 | Stores the details about a connected USB device. This is not directly part 103 | of the USB standard, and is instead a mechanism used to control the device 104 | tree. 105 | */ 106 | struct UsbDevice { 107 | u32 Number; 108 | 109 | UsbSpeed Speed; 110 | enum UsbDeviceStatus Status; 111 | volatile u8 ConfigurationIndex; 112 | u8 PortNumber; 113 | volatile enum UsbTransferError Error __attribute__((aligned(4))); 114 | 115 | // Generic device handlers 116 | /** Handler for detaching the device. The device driver should not issue further requests to the device. */ 117 | void (*DeviceDetached)(struct UsbDevice *device) __attribute__((aligned(4))); 118 | /** Handler for deallocation of the device. All memory in use by the device driver should be deallocated. */ 119 | void (*DeviceDeallocate)(struct UsbDevice *device); 120 | /** Handler for checking for changes to the USB device tree. Only hubs need handle with this. */ 121 | void (*DeviceCheckForChange)(struct UsbDevice *device); 122 | /** Handler for removing a child device from this device. Only hubs need handle with this. */ 123 | void (*DeviceChildDetached)(struct UsbDevice *device, struct UsbDevice *child); 124 | /** Handler for reseting a child device of this device. Only hubs need handle with this. */ 125 | Result (*DeviceChildReset)(struct UsbDevice *device, struct UsbDevice *child); 126 | /** Handler for reseting a child device of this device. Only hubs need handle with this. */ 127 | Result (*DeviceCheckConnection)(struct UsbDevice *device, struct UsbDevice *child); 128 | 129 | volatile struct UsbDeviceDescriptor Descriptor __attribute__((aligned(4))); 130 | volatile struct UsbConfigurationDescriptor Configuration __attribute__((aligned(4))); 131 | volatile struct UsbInterfaceDescriptor Interfaces[MaxInterfacesPerDevice] __attribute__((aligned(4))); 132 | volatile struct UsbEndpointDescriptor Endpoints[MaxInterfacesPerDevice][MaxEndpointsPerDevice] __attribute__((aligned(4))); 133 | struct UsbDevice *Parent __attribute__((aligned(4))); 134 | volatile void *FullConfiguration; 135 | volatile struct UsbDriverDataHeader *DriverData; 136 | volatile u32 LastTransfer; 137 | }; 138 | 139 | #define InterfaceClassAttachCount 16 140 | 141 | /** 142 | \brief Methods to attach a particular interface for a particular class. 143 | 144 | The class of the interface is the index into this array of methods. The 145 | array is populated by ConfigurationLoad(). 146 | */ 147 | extern Result (*InterfaceClassAttach[InterfaceClassAttachCount])(struct UsbDevice *device, u32 interfaceNumber); 148 | 149 | #endif // _DEVICE_H -------------------------------------------------------------------------------- /csud/include/usbd/devicerequest.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * usbd/devicerequest.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * usbd/devicerequest.h contains a definition of the standard device 9 | * request structure defined in USB2.0 10 | ******************************************************************************/ 11 | #ifndef _DEVICEREQUEST_H 12 | #define _DEVICEREQUEST_H 13 | 14 | #include 15 | 16 | /** 17 | \brief An encapsulated device request. 18 | 19 | A device request is a standard mechanism defined in USB2.0 manual section 20 | 9.3 by which negotiations with devices occur. The request have a number of 21 | parameters, and so are best implemented with a structure. As per usual, 22 | since this structure is arbitrary, we shall match Linux in the hopes of 23 | achieving some compatibility. 24 | */ 25 | struct UsbDeviceRequest { 26 | u8 Type; // +0x0 27 | enum UsbDeviceRequestRequest { 28 | // USB requests 29 | GetStatus = 0, 30 | ClearFeature = 1, 31 | SetFeature = 3, 32 | SetAddress = 5, 33 | GetDescriptor = 6, 34 | SetDescriptor = 7, 35 | GetConfiguration = 8, 36 | SetConfiguration = 9, 37 | GetInterface = 10, 38 | SetInterface = 11, 39 | SynchFrame = 12, 40 | // HID requests 41 | GetReport = 1, 42 | GetIdle = 2, 43 | GetProtocol = 3, 44 | SetReport = 9, 45 | SetIdle = 10, 46 | SetProtocol = 11, 47 | } Request : 8; // +0x1 48 | u16 Value; // +0x2 49 | u16 Index; // +0x4 50 | u16 Length; // +0x6 51 | }; 52 | 53 | #endif // _DEVICEREQUEST_H -------------------------------------------------------------------------------- /csud/include/usbd/pipe.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * usbd/pipe.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * usbd/pipe.h contains definitions relating to the USB pipe structure, 9 | * defined as part of the USB protocol. The precise details of this data 10 | * structure are an implementation detail, matching Linux in this case to 11 | * aid compatibility. 12 | ******************************************************************************/ 13 | #ifndef _USBD_PIPE_H 14 | #define _USBD_PIPE_H 15 | 16 | #include 17 | 18 | /** 19 | \brief Our implementation of the USB pipe defined in 10.5.1. 20 | 21 | The UsbPipeAddress holds the address of a pipe. The USB standard defines 22 | these as a software mechanism for communication between the USB driver and the 23 | host controller driver. We shall not have a concept of creating or destroying 24 | pipes, as this is needless clutter, and simply just indicate the pipe by its 25 | physical properties. In other words, we identify the pipe by its physical 26 | consequences on the USB. This is similar to Linux, and vastly reduces 27 | complication, at the expense of requiring a little more sophistication on the 28 | sender's behalf. 29 | */ 30 | struct UsbPipeAddress { 31 | UsbPacketSize MaxSize : 2; // @0 32 | UsbSpeed Speed : 2; // @2 33 | unsigned EndPoint : 4; // @4 34 | unsigned Device : 8; // @8 35 | UsbTransfer Type : 2; // @16 36 | UsbDirection Direction : 1; // @18 37 | unsigned _reserved19_31 : 13; // @19 38 | }; 39 | 40 | #endif // _USBD_PIPE_H -------------------------------------------------------------------------------- /csud/include/usbd/usbd.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * usbd/usbd.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * usbd/usbd.h contains definitions relating to the generic USB driver. USB 9 | * is designed such that this driver's interface would be virtually the same 10 | * across all systems, and in fact its implementation varies little either. 11 | ******************************************************************************/ 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /** 18 | \brief Performs all necessary operationg to start the USB driver. 19 | 20 | Initialises the USB driver by performing necessary interfactions with the 21 | host controller driver, and enumerating the device tree. 22 | */ 23 | Result UsbInitialise(); 24 | 25 | /** 26 | \brief Gets the descriptor for a given device. 27 | 28 | Gets the descriptor for a given device, using the index and language id 29 | specified. The returned value is not longer than length. 30 | */ 31 | Result UsbGetDescriptor(struct UsbDevice *device, enum DescriptorType type, 32 | u8 index, u16 langId, void* buffer, u32 length, u32 minimumLength, u8 recipient); 33 | 34 | /** 35 | \brief Sends a control message synchronously to a given device. 36 | 37 | Sends a contorl message synchronously to a given device, then waits for 38 | completion. If the timeout is reached returns ErrorTimeout. This puts 39 | device into an inconsistent state, so best not to use it until processing 40 | is unset. 41 | */ 42 | Result UsbControlMessage(struct UsbDevice *device, 43 | struct UsbPipeAddress pipe, void* buffer, u32 bufferLength, 44 | struct UsbDeviceRequest *request, u32 timeout); 45 | 46 | /** 47 | \brief Allocates memory to a new device. 48 | 49 | Sets the value in the parameter device to the address of a new device 50 | allocated on the heap, which then has appropriate default values. 51 | */ 52 | Result UsbAllocateDevice(struct UsbDevice **device); 53 | 54 | /* 55 | \brief Deallocates the memory and resources of a USB device. 56 | 57 | Recursively deallocates the device and all children. Deallocates any class 58 | specific data, as well as the device structure itself and releases the 59 | device number. 60 | */ 61 | void UsbDeallocateDevice(struct UsbDevice *device); 62 | 63 | /** 64 | \brief Recursively enumerates a new device. 65 | 66 | Recursively enumerates a new device that has been allocated. This assigns 67 | an address, determines what the device is, and, if it is a hub, will 68 | configure the device recursively look for new devices. If not, it will 69 | configure the device with the default configuration. 70 | */ 71 | Result UsbAttachDevice(struct UsbDevice *device); 72 | 73 | /** 74 | \brief Returns a description for a device. 75 | 76 | Returns a description for a device. This is not read from the device, this 77 | is just generated given by the driver. 78 | */ 79 | const char* UsbGetDescription(struct UsbDevice *device); 80 | 81 | /** 82 | \brief Returns a pointer to the root hub device. 83 | 84 | On a Universal Serial Bus, there exists a root hub. This if often a virtual 85 | device, and typically represents a one port hub, which is the physical 86 | universal serial bus for this computer. It is always address 1. It is 87 | present to allow uniform software manipulation of the universal serial bus 88 | itself. 89 | */ 90 | struct UsbDevice *UsbGetRootHub(); 91 | 92 | /** 93 | \brief Scans the entire USB tree for changes. 94 | 95 | Recursively calls HubCheckConnection on all ports on all hubs connected to 96 | the root hub. 97 | */ 98 | void UsbCheckForChange(); -------------------------------------------------------------------------------- /csud/makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # makefile 3 | # by Alex Chadwick 4 | # 5 | # A makefile script for generation of CSUD. 6 | ############################################################################### 7 | 8 | # Default parameters 9 | TYPE ?= LOWLEVEL 10 | TARGET ?= NONE 11 | CONFIG ?= FINAL 12 | 13 | # The intermediate directory for compiled object files. 14 | BUILD ?= build/ 15 | 16 | # The directory in which source files are stored. 17 | SOURCE ?= source/ 18 | 19 | # The directory in which configuration files are stored. 20 | CONFIGDIR ?= configuration/ 21 | 22 | # The name of the output file to generate. 23 | LIBNAME ?= libcsud.a 24 | 25 | # The include directory 26 | INCDIR ?= include/ 27 | 28 | all: 29 | # @echo CUSD - Chadderz Simple USB Driver 30 | # @echo by Alex Chadwick 31 | # @echo Usage: make driver CONFIG=config TYPE=type TARGET=target GNU=gnu 32 | # @echo Parameters: 33 | # @echo config - DEBUG or FINAL (default) 34 | # @echo alters amount of messages, checks, and the speed. 35 | # @echo type - STANDALONE, LOWLEVEL (default), or DRIVER 36 | # @echo alters how complete the driver is STANDALONE for no external 37 | # @echo dependencies LOWLEVEL for only key dependencies, DRIVER for 38 | # @echo typical levels. 39 | # @echo target - RPI, NONE (default) 40 | # @echo alters the target system. NONE for dummy driver, RPI for 41 | # @echo the RaspberryPi 42 | # @echo gnu - A gnu compiler prefix (arm-none-eabi-) or empty (default). 43 | # @echo The compiler chain to use (for cross compiling). 44 | # @echo See arguments for more. 45 | 46 | # The flags to pass to GCC for compiling. 47 | # -std=c99: Use c99 standard. 48 | # -fpack-struct: Do not insert unnecessary padding in structures to make them faster. 49 | # -Wno-packet-bitfield-compat: Do not warn about structures which would complie differently on older gcc. 50 | # -fshort-wchar: Treat wchar as a 16 bit value. 51 | # -Wall: Print lots of compiler warnings 52 | CFLAGS += -std=c99 -fpack-struct -Wno-packed-bitfield-compat -fshort-wchar -Wall 53 | CFLAGS += $(patsubst %,-I%,$(INCDIRS)) 54 | 55 | include $(CONFIGDIR)makefile.in 56 | include $(SOURCE)makefile.in 57 | 58 | # Rule to make everything. 59 | driver: $(LIBNAME) 60 | 61 | # Rule to make the driver file. 62 | $(LIBNAME) : $(patsubst %/,%, $(BUILD)) $(OBJECTS) 63 | rm -f $(LIBNAME) 64 | arm-none-eabi-ar rc $(LIBNAME) $(OBJECTS) 65 | 66 | # Rule to make the c object files. 67 | GCC := arm-none-eabi-gcc $(CFLAGS) -c -I$(INCDIR) 68 | 69 | $(BUILD): 70 | mkdir $(patsubst %/,%, $(BUILD)) 71 | 72 | # Rule to clean files. 73 | clean : 74 | rm -f $(BUILD)* 75 | rm -f $(LIBNAME) 76 | 77 | .PHONY: clean driver all 78 | -------------------------------------------------------------------------------- /csud/old/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Alex Chadwick 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /csud/old/arguments: -------------------------------------------------------------------------------- 1 | CSUD makefile arguments: 2 | 3 | CONFIG=(DEBUG|FINAL) 4 | DEBUG builds check more things, are more verbose, not optimise, etc. 5 | FINAL builds are faster, quieter, optimised. (default) 6 | TYPE=(STANDALONE|LOWLEVEL|DRIVER) 7 | STANDALONE builds have no external dependencies. 8 | LOWLEVEL builds have few external dependencies. (default) 9 | DRIVER builds have many external dependencies. 10 | TARGET=(RPI|NONE) 11 | RPI builds for the Raspberry Pi. Libs: ARM_V6, BCM2835, DWC. 12 | NONE builds for no system in particular. Libs: None. (default) 13 | GNU=* 14 | Specifies the cross compiler to use e.g. 'arm-none-eabi-'. Default is blank. 15 | BUILD=* 16 | Specifies the build directory. Default is 'build/'. 17 | SOURCE=* 18 | Specifies the source directory. Default is 'source/'. 19 | CONFIGDIR=* 20 | Specifies the configuration directory. Default is 'configuration/'. 21 | LIBNAME=* 22 | Specifies the target library name. Default is 'libcsud.a'. 23 | INCDIR=* 24 | Specifies the include directory. Default is 'include/'. Note, this is for 25 | the project headers, not system ones. 26 | LIB_HID=(0|1) 27 | Enables or disables the HID driver. Default specified in 28 | configuration/makefile.in. 29 | LIB_KBD=(0|1) 30 | Enables or disables the Keyboard driver. Default specified in 31 | configuration/makefile.in. 32 | LIB_HUB=(0|1) 33 | Enables or disables the Hub driver. Default specified in 34 | configuration/makefile.in. 35 | LIB_ARM_V6=(0|1) 36 | Enables or disables the ARMv6 platform code. Default is TARGET dependant. 37 | LIB_BCM2835=(0|1) 38 | Enables or disables the Broadcom2835 platform code. Default is TARGET 39 | dependant. 40 | LIB_DWC=(0|1) 41 | Enables or disables the DesignWare Core hcd. Default is TARGET dependant. -------------------------------------------------------------------------------- /csud/old/configuration/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(CONFIGDIR) 2 | 3 | ifeq ("$(CONFIG)", "DEBUG") 4 | CFLAGS += -DDEBUG 5 | else ifeq ("$(CONFIG)", "FINAL") 6 | CFLAGS += -DFINAL 7 | CFLAGS += -O2 8 | CFLAGS += -Wno-strict-aliasing 9 | else 10 | CFLAGS += -DCONFIG_ERROR 11 | endif 12 | 13 | ifeq ("$(TYPE)", "STANDALONE") 14 | CFLAGS += -DTYPE_STANDALONE 15 | else ifeq ("$(TYPE)", "LOWLEVEL") 16 | CFLAGS += -DTYPE_LOWLEVEL 17 | else ifeq ("$(TYPE)", "DRIVER") 18 | CFLAGS += -DTYPE_DRIVER 19 | else 20 | CFLAGS += -DTYPE_ERROR 21 | endif 22 | 23 | ifeq ("$(TARGET)", "RPI") 24 | include $(DIR)rpi.in 25 | else ifeq ("$(TARGET)", "NONE") 26 | CFLAGS += -DTARGET_NONE 27 | else 28 | CFLAGS += -DTARGET_ERROR 29 | endif 30 | 31 | LIB_HID ?= 1 32 | LIB_KBD ?= 1 33 | LIB_HUB ?= 1 34 | LIB_MOUSE ?= 1 35 | -------------------------------------------------------------------------------- /csud/old/configuration/rpi.in: -------------------------------------------------------------------------------- 1 | LIB_ARM_V6 ?= 1 2 | LIB_BCM2835 ?= 1 3 | LIB_DWC ?= 1 4 | CFLAGS += -DTARGET_RPI 5 | CFLAGS += -Wa,-march=armv6 6 | CFLAGS += -Wa,-mcpu=arm1176jzf-s -------------------------------------------------------------------------------- /csud/old/include/configuration.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * configuration.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * configuration.h contains definitions for all optional components 9 | * The makefile defines three main categories of definitions: 10 | * CONFIG: Whether or not this is a DEBUG driver 11 | * TARGET: The target system 12 | * TYPE: What sort of driver to compile (e.g. standalone) 13 | *****************************************************************************/ 14 | 15 | // Check we have a CONFIG. Valid choices are DEBUG and FINAL. If neither of 16 | // of these are specified, CONFIG_ERROR will be. If not, the haven't used the 17 | // makefile. 18 | #if defined DEBUG 19 | #elif defined FINAL 20 | #elif defined CONFIG_ERROR 21 | # error Please specify the CONFIG as either DEBUG or FINAL (default) 22 | #else 23 | # error Please ensure you compile the driver with the makefile provided 24 | #endif 25 | 26 | // Check we have a target. This should either be RPI or NONE. If neither of 27 | // these is specified, TARGET_ERROR will be. If not, the haven't used the 28 | // makefile. 29 | #if defined TARGET_RPI 30 | // Compiling for the Raspberry Pi (model B). 31 | // This is an ARM1176JZF-S, running ARMv6. 32 | // The chip is a Broadcom 2835 with a Designware OTG Core, mapped to 33 | // physical address 0x20980000 34 | # define ARM 35 | # define ARM_V6 36 | # define ENDIAN_LITTLE 37 | # define BROADCOM_2835 38 | # define HCD_DESIGNWARE_20 39 | # define HCD_DESIGNWARE_BASE ((void*)0x20980000) 40 | #elif defined TARGET_NONE 41 | // Compiling for no target architecture. This will rapidly run into errors. 42 | #elif defined TARGET_ERROR 43 | # error Please specify the TARGET as either RPI or NONE (default) 44 | #else 45 | # error Please ensure you compile the driver with the makefile provided 46 | #endif 47 | 48 | 49 | #if defined TYPE_STANDALONE 50 | // Disables all logging 51 | # define NO_LOG 52 | // Disables external memory management 53 | # define MEM_INTERNAL_MANAGER 54 | // Disables external memory reservation 55 | # define MEM_NO_RESERVE 56 | #elif defined TYPE_LOWLEVEL 57 | // Disables external memory management 58 | # define MEM_INTERNAL_MANAGER 59 | # define MEM_NO_RESERVE 60 | #elif defined TYPE_DRIVER 61 | #elif defined TYPE_ERROR 62 | # error Please specify the TYPE as either STANDALONE, LOWLEVEL (default) or DRIVER 63 | #else 64 | # error Please ensure you compile the driver with the makefile provided 65 | #endif -------------------------------------------------------------------------------- /csud/old/include/device/hid/hid.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * device/hid/hid.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * device/hid/hid.h contains definitions relating to generic human interface 9 | * devices. Information about the hid reports is in device/hid/report.h. 10 | ******************************************************************************/ 11 | #include 12 | #include 13 | 14 | /** 15 | \brief The human interface device descriptor information. 16 | 17 | The hid descriptor structure defined in the USB HID 1.11 manual in 6.2.1. 18 | */ 19 | struct HidDescriptor { 20 | u8 DescriptorLength; // +0x0 21 | enum DescriptorType DescriptorType : 8; // +0x1 22 | u16 HidVersion; // (bcd version) +0x2 23 | enum HidCountry { 24 | CountryNotSupported = 0, 25 | Arabic = 1, 26 | Belgian = 2, 27 | CanadianBilingual = 3, 28 | CanadianFrench = 4, 29 | CzechRepublic = 5, 30 | Danish = 6, 31 | Finnish = 7, 32 | French = 8, 33 | German = 9, 34 | Greek = 10, 35 | Hebrew = 11, 36 | Hungary = 12, 37 | International = 13, 38 | Italian = 14, 39 | Japan = 15, 40 | Korean = 16, 41 | LatinAmerican = 17, 42 | Dutch = 18, 43 | Norwegian = 19, 44 | Persian = 20, 45 | Poland= 21, 46 | Portuguese = 22, 47 | Russian = 23, 48 | Slovakian = 24, 49 | Spanish = 25, 50 | Swedish = 26, 51 | SwissFrench = 27, 52 | SwissGerman = 28, 53 | Switzerland = 29, 54 | Taiwan = 30, 55 | TurkishQ = 31, 56 | EnglishUk = 32, 57 | EnglishUs = 33, 58 | Yugoslavian = 34, 59 | TurkishF = 35, 60 | } Countrycode : 8; // +0x4 61 | u8 DescriptorCount; // +0x5 62 | struct { 63 | enum DescriptorType Type : 8; // +0x0 64 | u16 Length; // +0x1 65 | } OptionalDescriptors[]; // +0x6 (a number of optional descriptors up to DescriptorCount) 66 | }; 67 | 68 | /** 69 | \brief The possible types of hid reports. 70 | 71 | The possible hid reports defined in the USB HID 1.11 manual in 7.2.1. 72 | */ 73 | enum HidReportType { 74 | Input = 1, 75 | Output = 2, 76 | Feature = 3, 77 | }; 78 | 79 | /** The DeviceDriver field in UsbDriverDataHeader for hid devices. */ 80 | #define DeviceDriverHid 0x48494430 81 | 82 | /** 83 | \brief Hid specific data. 84 | 85 | The contents of the driver data field for hid devices. Chains to 86 | allow a stacked driver. 87 | */ 88 | struct HidDevice { 89 | struct UsbDriverDataHeader Header; 90 | struct HidDescriptor *Descriptor; 91 | struct HidParserResult *ParserResult; 92 | struct UsbDriverDataHeader *DriverData; 93 | 94 | // HID event handlers 95 | void (*HidDetached)(struct UsbDevice* device); 96 | void (*HidDeallocate)(struct UsbDevice* device); 97 | }; 98 | 99 | #define HidUsageAttachCount 10 100 | 101 | /** 102 | \brief Methods to attach an interface of particular hid desktop usage. 103 | 104 | The application desktop usage of the interface is the index into this array 105 | of methods. The array is populated by ConfigurationLoad(). 106 | */ 107 | extern Result (*HidUsageAttach[HidUsageAttachCount])(struct UsbDevice *device, u32 interfaceNumber); 108 | 109 | /** 110 | \brief Retrieves a hid report. 111 | 112 | Performs a hid get report request as defined in in the USB HID 1.11 manual 113 | in 7.2.1. 114 | */ 115 | Result HidGetReport(struct UsbDevice *device, enum HidReportType reportType, 116 | u8 reportId, u8 interface, u32 bufferLength, void* buffer); 117 | 118 | /** 119 | \brief Sends a hid report. 120 | 121 | Performs a hid set report request as defined in in the USB HID 1.11 manual 122 | in 7.2.2. 123 | */ 124 | Result HidSetReport(struct UsbDevice *device, enum HidReportType reportType, 125 | u8 reportId, u8 interface, u32 bufferLength, void* buffer); 126 | 127 | /** 128 | \brief Updates the device with the values of a report. 129 | 130 | Writes back the current values of a report in memory to the device. 131 | Implemented using HidSetReport, not interrupts. 132 | */ 133 | Result HidWriteDevice(struct UsbDevice *device, u8 report); 134 | 135 | /** 136 | \brief Updates a report with the values from the device. 137 | 138 | Reads the current values of a report from the device into memory. Implemented 139 | using HidGetReport not interrupts. 140 | */ 141 | Result HidReadDevice(struct UsbDevice *device, u8 report); 142 | 143 | /** 144 | \brief Enumerates a device as a HID device. 145 | 146 | Checks a device to see if it appears to be a HID device, and, if so, loads 147 | its hid and report descriptors to see what it can do. 148 | */ 149 | Result HidAttach(struct UsbDevice *device, u32 interfaceNumber); -------------------------------------------------------------------------------- /csud/old/include/device/hid/keyboard.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * device/hid/keyboard.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * device/hid/keyboard.h contains definitions relating to keyboards. 9 | ******************************************************************************/ 10 | #include 11 | #include 12 | 13 | /** 14 | \brief The current state of keyboard modifier keys. 15 | 16 | Encapsulates the current state of the keyboard modifier keys. Strucutre 17 | mimics the most common keyboard ordering. 18 | */ 19 | struct KeyboardModifiers { 20 | bool LeftControl : 1; // @0 21 | bool LeftShift : 1; // @1 22 | bool LeftAlt : 1; // @2 23 | bool LeftGui : 1; // the 'windows' key @3 24 | bool RightControl : 1; // @4 25 | bool RightShift : 1; // @5 26 | bool RightAlt : 1; // 'alt gr' @6 27 | bool RightGui : 1; // @7 28 | }; 29 | 30 | /** 31 | \brief The current state of keyboard leds. 32 | 33 | Encapsulates the current state of the keyboard leds. Strucutre mimics the 34 | most common lights and ordering. Not all keyboards may support all lights. 35 | */ 36 | struct KeyboardLeds { 37 | bool NumberLock : 1; 38 | bool CapsLock : 1; 39 | bool ScrollLock : 1; 40 | bool Compose : 1; 41 | bool Kana : 1; 42 | bool Power : 1; 43 | bool Mute : 1; 44 | bool Shift : 1; 45 | }; 46 | 47 | /** The DeviceDriver field in UsbDriverDataHeader for keyboard devices. */ 48 | #define DeviceDriverKeyboard 0x4B424430 49 | /** The maximum number of keys a keyboard can report at once. Should be 50 | multiple of 2. */ 51 | #define KeyboardMaxKeys 6 52 | 53 | /** 54 | \brief Keyboard specific data. 55 | 56 | The contents of the driver data field for keyboard devices. Placed in 57 | HidDevice, as this driver is built atop that. 58 | */ 59 | struct KeyboardDevice { 60 | /** Standard driver data header. */ 61 | struct UsbDriverDataHeader Header; 62 | /** Internal - Index in keyboard arrays. */ 63 | u32 Index; 64 | /** Number of keys currently held down. */ 65 | u32 KeyCount; 66 | /** Keys currently held down. */ 67 | u16 Keys[KeyboardMaxKeys]; 68 | /** Modifier keys currently held down. */ 69 | struct KeyboardModifiers Modifiers; 70 | /** Which LEDs this keyboard supports. */ 71 | struct KeyboardLeds LedSupport; 72 | /** Which fields in the LED report are for what LEDs. */ 73 | struct HidParserField *LedFields[8]; 74 | /** Which fields in the Input report are for what modifiers and keys. */ 75 | struct HidParserField *KeyFields[8 + 1]; 76 | /** The LED report. */ 77 | struct HidParserReport *LedReport; 78 | /** The input report. */ 79 | struct HidParserReport *KeyReport; 80 | }; 81 | 82 | /** 83 | \brief Enumerates a device as a keyboard. 84 | 85 | Checks a device already checked by HidAttach to see if it appears to be a 86 | keyboard, and, if so, builds up necessary information to enable the 87 | keyboard methods. 88 | */ 89 | Result KeyboardAttach(struct UsbDevice *device, u32 interface); 90 | 91 | /** 92 | \brief Returns the number of keyboards connected to the system. 93 | */ 94 | u32 KeyboardCount(); 95 | 96 | /** 97 | \brief Sets the keyboard LEDs to the state given in leds. 98 | 99 | Sets the keyboard LEDs to the state given in leds. Unimplemented LEDs are 100 | ignored silently. 101 | */ 102 | Result KeyboardSetLeds(u32 keyboardAddress, struct KeyboardLeds leds); 103 | 104 | /** 105 | \brief Gets a list of available keyboard LEDs. 106 | 107 | Reads the availablility of keyboard LEDs from the report descriptor. LEDs 108 | that are present are set to 1, and those than are not are set to 0. 109 | */ 110 | struct KeyboardLeds KeyboardGetLedSupport(u32 keyboardAddress); 111 | 112 | /** 113 | \brief Checks a given keyboard. 114 | 115 | Reads back the report from a given keyboard and parses it into the internal 116 | fields. These can be accessed with KeyboardGet... methods 117 | */ 118 | Result KeyboardPoll(u32 keyboardAddress); 119 | 120 | /** 121 | \brief Reads the modifier keys from a keyboard. 122 | 123 | Reads back the state of the modifier keys from the last sucessfully 124 | received report. Zeros out by default. 125 | */ 126 | struct KeyboardModifiers KeyboardGetModifiers(u32 keyboardAddress); 127 | 128 | /** 129 | \brief Returns the number of keys currently held down. 130 | 131 | Reads back the number of keys that were held down in the last report. If 132 | the keyboard reaches its key limit, this reports the last sensible report 133 | received. 134 | */ 135 | u32 KeyboardGetKeyDownCount(u32 keyboardAddress); 136 | 137 | /** 138 | \brief Returns whether or not a particular key is held down. 139 | 140 | Reads back whether or not a key was held on the last successfully received 141 | report. 142 | */ 143 | bool KeyboadGetKeyIsDown(u32 keyboardAddress, u16 key); 144 | 145 | /** 146 | \brief Returns the nth key that is held down. 147 | 148 | Reads back the number of the nth key that was held down in the last 149 | successfully received report. 150 | */ 151 | u16 KeyboardGetKeyDown(u32 keyboardAddress, u32 index); 152 | 153 | /** 154 | \brief Returns the device address of the nth connected keyboard. 155 | 156 | Keyboards that are connected are stored in an array, and this method 157 | retrieves the nth item from that array. Returns 0 on error. 158 | */ 159 | u32 KeyboardGetAddress(u32 index); -------------------------------------------------------------------------------- /csud/old/include/device/hid/mouse.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * device/hid/mouse.h 3 | * by Steve White 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * device/hid/mouse.h contains definitions relating to mouses. 9 | ******************************************************************************/ 10 | #include 11 | #include 12 | 13 | /** The DeviceDriver field in UsbDriverDataHeader for mouse devices. */ 14 | #define DeviceDriverMouse 0x4B424431 15 | /** The maximum number of keys a mouse can report at once. Should be 16 | multiple of 2. */ 17 | #define MouseMaxKeys 6 18 | 19 | enum MouseDeviceButton { 20 | MouseDeviceButtonLeft, 21 | MouseDeviceButtonRight, 22 | MouseDeviceButtonMiddle, 23 | MouseDeviceButtonSide, 24 | MouseDeviceButtonExtra, 25 | }; 26 | 27 | /** 28 | \brief Mouse specific data. 29 | 30 | The contents of the driver data field for mouse devices. Placed in 31 | HidDevice, as this driver is bult atop that. 32 | */ 33 | struct MouseDevice { 34 | /** Standard driver data header. */ 35 | struct UsbDriverDataHeader Header; 36 | /** Internal - Index in mouse arrays. */ 37 | u32 Index; 38 | 39 | u8 buttonState; 40 | s16 mouseX; 41 | s16 mouseY; 42 | s16 wheel; 43 | 44 | /** The input report. */ 45 | struct HidParserReport *MouseReport; 46 | }; 47 | 48 | /** 49 | \brief Enumerates a device as a mouse. 50 | 51 | Checks a device already checked by HidAttach to see if it appears to be a 52 | mouse, and, if so, bulds up necessary information to enable the 53 | mouse methods. 54 | */ 55 | Result MouseAttach(struct UsbDevice *device, u32 interface); 56 | 57 | /** 58 | \brief Returns the number of mouses connected to the system. 59 | */ 60 | u32 MouseCount(); 61 | 62 | /** 63 | \brief Checks a given mouse. 64 | 65 | Reads back the report from a given mouse and parses it into the internal 66 | fields. These can be accessed with MouseGet... methods 67 | */ 68 | Result MousePoll(u32 mouseAddress); 69 | 70 | /** 71 | \brief Returns the device address of the nth connected mouse. 72 | 73 | Mouses that are connected are stored in an array, and this method 74 | retrieves the nth item from that array. Returns 0 on error. 75 | */ 76 | u32 MouseGetAddress(u32 index); 77 | 78 | /** 79 | \brief Returns the current X coordinate of the mouse 80 | */ 81 | s16 MouseGetPositionX(u32 mouseAddress); 82 | 83 | /** 84 | \brief Returns the current Y coordinate of the mouse 85 | */ 86 | s16 MouseGetPositionY(u32 mouseAddress); 87 | 88 | /** 89 | \brief Returns the current wheel value of the mouse 90 | */ 91 | s16 MouseGetWheel(u32 mouseAddress); 92 | 93 | /** 94 | \brief Returns the current X and Y coordinates of the mouse 95 | 96 | X is in the high 16 bits, Y is in the low 16 bits 97 | */ 98 | u32 MouseGetPosition(u32 mouseAddress); 99 | 100 | /** 101 | \brief Returns the current button state of the mouse 102 | 103 | First bit : Left button 104 | Second bit: Right button 105 | Third bit : Middle button 106 | Fourth bit: Side button 107 | Fifth bit : Extra button 108 | */ 109 | u8 MouseGetButtons(u32 mouseAddress); 110 | 111 | /** 112 | \brief Returns whether or not a particular mouse button is pressed. 113 | 114 | Reads back whether or not a mouse button was pressed on the last 115 | successfully received report. 116 | */ 117 | bool MouseGetButtonIsPressed(u32 mouseAddress, enum MouseDeviceButton button); 118 | -------------------------------------------------------------------------------- /csud/old/include/device/hub.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * device/hub.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * device/hub.h contains definitions relating to the USB hub device. 9 | ******************************************************************************/ 10 | #include 11 | #include 12 | #include 13 | 14 | /** 15 | \brief The hub descriptor information. 16 | 17 | The hub descriptor structure defined in the USB2.0 manual section 18 | 11.23.2.1. 19 | */ 20 | struct HubDescriptor { 21 | u8 DescriptorLength; // +0x0 22 | enum DescriptorType DescriptorType : 8; // +0x1 23 | u8 PortCount; // +0x2 24 | struct { 25 | enum HubPortControl { 26 | Global = 0, 27 | Individual = 1, 28 | } PowerSwitchingMode : 2; // @0 29 | bool Compound : 1; // @2 30 | enum HubPortControl OverCurrentProtection : 2; // @3 31 | unsigned ThinkTime : 2; // in +1*8FS units @5 32 | bool Indicators : 1; // @7 33 | unsigned _reserved8_15 : 8; // @8 34 | } Attributes; // +0x3 35 | u8 PowerGoodDelay; // +0x5 36 | u8 MaximumHubPower; // +0x6 37 | u8 Data[]; // +0x7 the data consists of n bytes describing port detatchability, followed by n bytes for compatiblity. n = roundup(ports/8). 38 | } __attribute__ ((__packed__)); 39 | 40 | /** 41 | \brief Encapsulates the current status of a hub. 42 | 43 | The hub status structure defined in 11.24.2.6 of the USB2.0 44 | standard. 45 | */ 46 | struct HubStatus { 47 | bool LocalPower : 1; // @0 48 | bool OverCurrent : 1; // @1 49 | unsigned _reserved2_15 : 14; // @2 50 | }; 51 | 52 | /** 53 | \brief Encapsulates the change in current status of a hub. 54 | 55 | The hub status change structure defined in 11.24.2.6 of the USB2.0 56 | standard. 57 | */ 58 | struct HubStatusChange { 59 | bool LocalPowerChanged : 1; // @0 60 | bool OverCurrentChanged : 1; // @1 61 | unsigned _reserved2_15 : 14; // @2 62 | }; 63 | 64 | /** 65 | \brief Encapsulates the full status of a hub. 66 | 67 | The hub status structure defined in 11.24.2.6 of the USB2.0 standard. 68 | */ 69 | struct HubFullStatus { 70 | struct HubStatus Status; 71 | struct HubStatusChange Change; 72 | }; 73 | /** 74 | \brief Encapsulates the current status of a hub port. 75 | 76 | The hub port status structure defined in 11.24.2.7.1 of the USB2.0 77 | standard. 78 | */ 79 | struct HubPortStatus { 80 | bool Connected : 1; // @0 81 | bool Enabled : 1; // @1 82 | bool Suspended : 1; // @2 83 | bool OverCurrent : 1; // @3 84 | bool Reset : 1; // @4 85 | unsigned _reserved5_7 : 3; // @5 86 | bool Power : 1; // @8 87 | bool LowSpeedAttatched : 1; // @9 88 | bool HighSpeedAttatched : 1; // @10 89 | bool TestMode : 1; // @11 90 | bool IndicatorControl : 1; // @12 91 | unsigned _reserved13_15 : 3; // @13 92 | }; 93 | 94 | /** 95 | \brief Encapsulates the change in current status of a hub port. 96 | 97 | The hub port status change structure defined in 11.24.2.7.2 of the USB2.0 98 | standard. 99 | */ 100 | struct HubPortStatusChange { 101 | bool ConnectedChanged : 1; // @0 102 | bool EnabledChanged : 1; // @1 103 | bool SuspendedChanged : 1; // @2 104 | bool OverCurrentChanged : 1; // @3 105 | bool ResetChanged : 1; // @4 106 | unsigned _reserved5_15 : 11; // @5 107 | }; 108 | 109 | /** 110 | \brief Encapsulates the full status of a hub port. 111 | 112 | The hub port status structure defined in 11.24.2.7 of the USB2.0 standard. 113 | */ 114 | struct HubPortFullStatus { 115 | struct HubPortStatus Status; 116 | struct HubPortStatusChange Change; 117 | }; 118 | 119 | /** 120 | \brief A feature of a hub port. 121 | 122 | The feautres of a hub port that can be altered. 123 | */ 124 | enum HubPortFeature { 125 | FeatureConnection = 0, 126 | FeatureEnable = 1, 127 | FeatureSuspend = 2, 128 | FeatureOverCurrent = 3, 129 | FeatureReset = 4, 130 | FeaturePower = 8, 131 | FeatureLowSpeed = 9, 132 | FeatureHighSpeed = 10, 133 | FeatureConnectionChange = 16, 134 | FeatureEnableChange = 17, 135 | FeatureSuspendChange = 18, 136 | FeatureOverCurrentChange = 19, 137 | FeatureResetChange = 20, 138 | }; 139 | 140 | /** The DeviceDriver field in UsbDriverDataHeader for hubs. */ 141 | #define DeviceDriverHub 0x48554230 142 | 143 | /** 144 | \brief Hub specific data. 145 | 146 | The contents of the driver data field for hubs. 147 | */ 148 | struct HubDevice { 149 | struct UsbDriverDataHeader Header; 150 | struct HubFullStatus Status; 151 | struct HubDescriptor *Descriptor; 152 | u32 MaxChildren; 153 | struct HubPortFullStatus PortStatus[MaxChildrenPerDevice]; 154 | struct UsbDevice *Children[MaxChildrenPerDevice]; 155 | }; 156 | 157 | /** 158 | \brief A feature of a hub. 159 | 160 | The feautres of a hub that can be altered. 161 | */ 162 | enum HubFeature { 163 | FeatureHubPower = 0, 164 | FeatureHubOverCurrent = 1, 165 | }; 166 | 167 | 168 | /** 169 | \brief Performs all necesary hub related initialisation. 170 | 171 | Loads a hub device and enumerates its children. 172 | */ 173 | Result HubAttach(struct UsbDevice *device, u32 interfaceNumber); 174 | 175 | /** 176 | \brief Resets a port on a hub. 177 | 178 | Resets a port on a hub. No validation. 179 | */ 180 | Result HubPortReset(struct UsbDevice *device, u8 port); 181 | 182 | /** 183 | \brief Checks the connection status of a port. 184 | 185 | Checks for a change in the connection status of a port. If it has changed 186 | performs necessary actions such as enumerating a new device or deallocating 187 | an old one. 188 | */ 189 | Result HubCheckConnection(struct UsbDevice *device, u8 port); 190 | 191 | /** 192 | \brief Checks all hubs for new devices. 193 | 194 | Recursively checks the hub tree for new devices being attached, and for old 195 | devices being removed. 196 | */ 197 | void HubRecursiveCheck(struct UsbDevice *device); -------------------------------------------------------------------------------- /csud/old/include/hcd/dwc/designware20.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlar54/Commodore-Pi/41aa2a1e4a802a9f9dfca3e2a913926cdb0c1870/csud/old/include/hcd/dwc/designware20.h -------------------------------------------------------------------------------- /csud/old/include/hcd/hcd.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * hcd/hcd.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * hcd/hcd.h contains definitions relating to the host controller driver of 9 | * the USB implementation. 10 | ******************************************************************************/ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /** 18 | \brief Intialises the host controller driver for this hardware. 19 | 20 | Initialises the core on whatever hardware is in use. 21 | */ 22 | Result HcdInitialise(); 23 | 24 | /** 25 | \brief Starts the host controller driver working. 26 | 27 | Starts the host controller driver working. It should start processing 28 | communications and be ready for commands. 29 | */ 30 | Result HcdStart(); 31 | 32 | /** 33 | \brief Stops the host controller driver working. 34 | 35 | Stops the host controller driver working. This should close all connections 36 | and return the Hcd to a state such that a subsequent call to StopHcd would 37 | restart everything. This could be to update parameters, fix a fault, etc. 38 | */ 39 | Result HcdStop(); 40 | 41 | /** 42 | \brief Uninitialises the host controller driver. 43 | 44 | Unitialises the host controller driver. This should be called when the 45 | driver is to be complete removed. It should power off any hardware, and 46 | and return the driver to a point such that a subsequent call to 47 | InitialiseHcd would restart it. 48 | */ 49 | Result HcdDeinitialise(); 50 | 51 | /** 52 | \brief Sends a control message to a device. 53 | 54 | Sends a control message to a device. Handles all necessary channel creation 55 | and other processing. The sequence of a control transfer is defined in the 56 | USB 2.0 manual section 5.5. The host sends a setup packet (request) then 57 | zero or more data packets are sent or received (to buffer, max length 58 | bufferLength) and finally a status message is sent to conclude the 59 | transaction. Packets larger than pipe.MaxSize are split. For low speed 60 | devices pipe.MaxSize must be Bits8, and Bits64 for high speed. Low and full 61 | speed transactions are always split. 62 | */ 63 | Result HcdSumbitControlMessage(struct UsbDevice *device, 64 | struct UsbPipeAddress pipe, void* buffer, u32 bufferLength, 65 | struct UsbDeviceRequest *request); 66 | 67 | #include "dwc/designware20.h" 68 | -------------------------------------------------------------------------------- /csud/old/include/platform/arm/armv6.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * platform/arm/armv6.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * platform/arm/armv6.h contains definitions for arm version 6 processors. 9 | ******************************************************************************/ 10 | #include 11 | #include 12 | -------------------------------------------------------------------------------- /csud/old/include/platform/arm/broadcom2835.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * platform/arm/broadcom2835.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * platform/arm/broadcom2835.h contains definitions pertaining to the 9 | * broadcom2835 chip, used in the Raspberry Pi. 10 | ******************************************************************************/ 11 | 12 | #include 13 | 14 | /** The null address. */ 15 | #define NULL ((void*)0) 16 | #ifdef MEM_INTERNAL_MANAGER 17 | // When asked to use internal memory management, we use the default. 18 | #define MEM_INTERNAL_MANAGER_DEFAULT 19 | #endif -------------------------------------------------------------------------------- /csud/old/include/platform/none/byteorder.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * platform/none/byteorder.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * platform/none/byteorder.h contains generic definitions for changing the 9 | * byte order of halfs to match the processor. 10 | ******************************************************************************/ 11 | #include 12 | #include 13 | 14 | #if defined ENDIAN_BIG 15 | /** 16 | Converts a number from the machine's byte order to big endian or back. 17 | */ 18 | #define EndianBigWord(x) x 19 | /** 20 | Converts a number from the machine's byte order to little endian or back. 21 | */ 22 | #define EndianLittleWord(x) ({ u32 t = x; (t >> 24) & 0xff | (t >> 8) & 0xff00 | (t << 8) & 0xff00 | (t << 24) & 0xff000000; }) 23 | /** 24 | Converts a number from the machine's byte order to big endian or back. 25 | */ 26 | #define EndianBigHalf(x) x 27 | /** 28 | Converts a number from the machine's byte order to little endian or back. 29 | */ 30 | #define EndianLittleHalf(x) ({ u16 t = x; (t >> 8) & 0xff | (t << 8) & 0xff00; }) 31 | #elif defined ENDIAN_LITTLE 32 | /** 33 | Converts a number from the machine's byte order to big endian or back. 34 | */ 35 | #define EndianBigWord(x) ({ u32 t = x; (t >> 24) & 0xff | (t >> 8) & 0xff00 | (t << 8) & 0xff0000 | (t << 24) & 0xff000000; }) 36 | /** 37 | Converts a number from the machine's byte order to little endian or back. 38 | */ 39 | #define EndianLittleWord(x) x 40 | /** 41 | Converts a number from the machine's byte order to big endian or back. 42 | */ 43 | #define EndianBigHalf(x) ({ u16 t = x; (t >> 8) & 0xff | (t << 8) & 0xff00; }) 44 | /** 45 | Converts a number from the machine's byte order to little endian or back. 46 | */ 47 | #define EndianLittleHalf(x) x 48 | #else 49 | #error Endianness not specified. 50 | #endif -------------------------------------------------------------------------------- /csud/old/include/platform/platform.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * platform/platform.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * platform/platform.h contains definitions pertaining to the platform that 9 | * the system will run on. 10 | ******************************************************************************/ 11 | 12 | #ifndef _PLATFORM_H 13 | #define _PLATFORM_H 14 | 15 | #include 16 | #include 17 | 18 | /** 19 | \brief Allocates memory of specified length. 20 | 21 | Allocates memory of length at least length to the driver and returns the 22 | address. If MEM_INTERNAL_MANAGER is defined, then all platforms must 23 | provide an implementation which calls MemoryReserve. Can return NULL on 24 | error. 25 | */ 26 | void* MemoryAllocate(u32 length); 27 | /** 28 | \brief Deallocates memory of specified address, previously allocated by 29 | MemoryAllocate. 30 | 31 | Deallocates memory of the specified address that was previously allocated 32 | by MemoryAllocate. If MEM_INTERNAL_MANAGER is defined, then all platforms 33 | must provide an implementation. Calling with an address not received from 34 | MemoryAllocate produces undefined results. 35 | */ 36 | void MemoryDeallocate(void* address); 37 | /** 38 | \brief Notifies the system of memory usage. 39 | 40 | Notifies the parent system of an unavoidable memory usage. This is 41 | typically used for memory mapped IO systems, in which certain addresses 42 | have special meaning. It is up to the parent system to implement whatever 43 | must be done. The return value should be a virtual address that maps to 44 | the requested physical address, or NULL on error. If MEM_NO_RESERVE is 45 | defined, a dummy implementation is created. 46 | */ 47 | void* MemoryReserve(u32 length, void* physicalAddress); 48 | /** 49 | \brief Copies chunks of memory. 50 | 51 | Copies length bytes from source to destinatoin. If either source or 52 | destination are null, should not copy anything. 53 | */ 54 | void MemoryCopy(void* destination, void* source, u32 length); 55 | 56 | #ifdef NO_LOG 57 | #define LOG(x) 58 | #define LOGL(x, len) 59 | #define LOGF(x, ...) 60 | #define LOGFL(x, len, ...) 61 | #else 62 | /** 63 | \brief Notifies the user of progress. 64 | 65 | Notifies the parent system of progress loading the driver. Messages may be 66 | displayed to a semi-technically competant user. 67 | */ 68 | void LogPrint(char* message, u32 messageLength); 69 | /** 70 | \brief Notifies the user of progress. 71 | 72 | Prints our a formatted string. Uses all the formtting options in printf. 73 | Implemented in platform.c, by calling LogPrint. Messages truncated to 160 74 | characters. 75 | */ 76 | void LogPrintF(char* format, u32 formatLength, ...); 77 | 78 | #define LOG(x) (LogPrint(x, sizeof(x))) 79 | #define LOGL(x, len) (LogPrint(x, len)) 80 | #define LOGF(x, ...) (LogPrintF(x, sizeof(x), __VA_ARGS__)) 81 | #define LOGFL(x, len, ...) (LogPrintF(x, len, __VA_ARGS__)) 82 | #endif 83 | #ifdef DEBUG 84 | #define LOG_DEBUG(x) LOG(x) 85 | #define LOG_DEBUGL(x, len) LOGL(x, len) 86 | #define LOG_DEBUGF(x, ...) LOGF(x, __VA_ARGS__) 87 | #define LOG_DEBUGFL(x, len, ...) LOGFL(x, len, __VA_ARGS__) 88 | #else 89 | #define LOG_DEBUG(x) 90 | #define LOG_DEBUGL(x, len) 91 | #define LOG_DEBUGF(x, ...) 92 | #define LOG_DEBUGFL(x, len, ...) 93 | #endif 94 | 95 | /** 96 | \brief Turns on the USB host controller. 97 | 98 | Notifies the parent system that the USB contorller now requires power. 99 | */ 100 | Result PowerOnUsb(); 101 | /** 102 | \brief Turns on the USB host controller. 103 | 104 | Notifies the parent system that the USB contorller no longer requires power. 105 | */ 106 | void PowerOffUsb(); 107 | 108 | /** 109 | \brief Delays for delay microseconds. 110 | 111 | Delays for a number of microseconds. 112 | */ 113 | void MicroDelay(u32 delay); 114 | 115 | 116 | #ifdef ARM 117 | # ifdef ARM_V6 118 | # include "arm/armv6.h" 119 | # ifdef BROADCOM_2835 120 | # include "arm/broadcom2835.h" 121 | # endif // BROADCOM_2835 122 | # else 123 | # error Unrecognised ARM Version 124 | # endif // ARM_V6 125 | #else 126 | #error Unrecognised Processor Family 127 | #endif // ARM 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /csud/old/include/types.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * types.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * types.h contains definitions of standardised types used ubiquitously. 9 | ******************************************************************************/ 10 | #ifndef _TYPES_H 11 | #define _TYPES_H 12 | 13 | /** Unsigned 8 bit type */ 14 | typedef unsigned char u8; 15 | /** Unsigned 16 bit type */ 16 | typedef unsigned short u16; 17 | /** Unsigned 32 bit type */ 18 | typedef unsigned int u32; 19 | /** Unsigned 64 bit type */ 20 | typedef unsigned long long u64; 21 | /** Signed 8 bit type */ 22 | typedef signed char s8; 23 | /** Signed 16 bit type */ 24 | typedef signed short s16; 25 | /** Signed 32 bit type */ 26 | typedef signed int s32; 27 | /** Signed 64 bit type */ 28 | typedef signed long long s64; 29 | 30 | /** One bit truth value */ 31 | typedef enum { 32 | false = 0, 33 | true = 1, 34 | } bool; 35 | 36 | /** 37 | \brief Result of a method call. 38 | 39 | Negative results are errors. 40 | OK is for a general success. 41 | ErrorGeneral is an undisclosed failure. 42 | ErrorArgument is a bad input. 43 | ErrorRetry is a temporary issue that may disappear, the method should be rerun 44 | without modification (the caller is expected to limit number of retries as 45 | required). 46 | ErrorDevice is a more permenant hardware error (a reset procedure should be 47 | enacted before retrying). 48 | ErrorIncompatible is a device driver that will not support the detected 49 | device. 50 | ErrorCompiler is a problem with the configuration of the compiler generating 51 | unusable code. 52 | ErrorMemory is used when the memory is exhausted. 53 | ErrorTimeout is used when a maximum delay is reached when waiting and an 54 | operation is unfinished. This does not necessarily mean the operationg 55 | will not finish, just that it is unreasonably slow. 56 | ErrorDisconnected is used when a device is disconnected in transfer. 57 | */ 58 | typedef enum { 59 | OK = 0, 60 | ErrorGeneral = -1, 61 | ErrorArgument = -2, 62 | ErrorRetry = -3, 63 | ErrorDevice = -4, 64 | ErrorIncompatible = -5, 65 | ErrorCompiler = -6, 66 | ErrorMemory = -7, 67 | ErrorTimeout = -8, 68 | ErrorDisconnected = -9, 69 | } Result; 70 | 71 | /** 72 | \brief Direction of USB communication. 73 | 74 | Many and various parts of the USB standard use this 1 bit field to indicate 75 | in which direction information flows. 76 | */ 77 | typedef enum { 78 | HostToDevice = 0, 79 | Out = 0, 80 | DeviceToHost = 1, 81 | In = 1, 82 | } UsbDirection; 83 | 84 | /** 85 | \brief Speed of USB communication. 86 | 87 | Many and various parts of the USB standard use this 2 bit field to indicate 88 | in which direction information flows. 89 | */ 90 | typedef enum { 91 | High = 0, 92 | Full = 1, 93 | Low = 2, 94 | } UsbSpeed; 95 | 96 | static inline char* SpeedToChar(UsbSpeed speed) { 97 | if (speed == High) return "480 Mb/s"; 98 | else if (speed == Low) return "1.5 Mb/s"; 99 | else if (speed == Full) return "12 Mb/s"; 100 | else return "Unknown Mb/s"; 101 | } 102 | 103 | /** 104 | \brief Transfer type in USB communication. 105 | 106 | Many and various parts of the USB standard use this 2 bit field to indicate 107 | in what type of transaction to use. 108 | */ 109 | typedef enum { 110 | Control = 0, 111 | Isochronous = 1, 112 | Bulk = 2, 113 | Interrupt = 3, 114 | } UsbTransfer; 115 | 116 | /** 117 | \brief Transfer size in USB communication. 118 | 119 | Many and various parts of the USB standard use this 2 bit field to indicate 120 | in what size of transaction to use. 121 | */ 122 | typedef enum { 123 | Bits8, 124 | Bits16, 125 | Bits32, 126 | Bits64, 127 | } UsbPacketSize; 128 | 129 | static inline UsbPacketSize SizeFromNumber(u32 size) { 130 | if (size <= 8) return Bits8; 131 | else if (size <= 16) return Bits16; 132 | else if (size <= 32) return Bits32; 133 | else return Bits64; 134 | } 135 | static inline u32 SizeToNumber(UsbPacketSize size) { 136 | if (size == Bits8) return 8; 137 | else if (size == Bits16) return 16; 138 | else if (size == Bits32) return 32; 139 | else return 64; 140 | } 141 | 142 | /** 143 | \brief Returns the minimum of two inputs. 144 | 145 | Returns the minimum of two inputs, ensuring only one evaluation of each. To 146 | do so, the type must be supplied. 147 | */ 148 | #define Min(x, y, type) ({ type __x = (x); type __y = (y); __x < __y ? __x : __y; }) 149 | /** 150 | \brief Returns the maximum of two inputs. 151 | 152 | Returns the maximum of two inputs, ensuring only one evaluation of each. To 153 | do so, the type must be supplied. 154 | */ 155 | #define Max(x, y, type) ({ type __x = (x); type __y = (y); __x < __y ? __y : __x; }) 156 | 157 | #endif // _TYPES_H -------------------------------------------------------------------------------- /csud/old/include/usbd/descriptors.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * usbd/descriptors.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * usbd/descriptors.h contains structures defined in the USB standard that 9 | * describe various aspects of USB. 10 | ******************************************************************************/ 11 | #ifndef _USBD_DESCRIPTORS_H 12 | #define _USBD_DESCRIPTORS_H 13 | 14 | #include 15 | 16 | /** 17 | \brief The descriptor type field from the header of USB descriptors. 18 | 19 | The descriptor type in the header of all USB descriptor sturctures defined 20 | in the USB 2.0 manual in 9.6. 21 | */ 22 | enum DescriptorType { 23 | Device = 1, 24 | Configuration = 2, 25 | String = 3, 26 | Interface = 4, 27 | Endpoint = 5, 28 | DeviceQualifier = 6, 29 | OtherSpeedConfiguration = 7, 30 | InterfacePower = 8, 31 | Hid = 33, 32 | HidReport = 34, 33 | HidPhysical = 35, 34 | Hub = 41, 35 | }; 36 | 37 | /** 38 | \brief The header of USB descriptor information. 39 | 40 | The header of all USB descriptor sturctures defined in the USB 2.0 manual 41 | in 9.6. 42 | */ 43 | struct UsbDescriptorHeader { 44 | u8 DescriptorLength; // +0x0 45 | enum DescriptorType DescriptorType : 8; // +0x1 46 | }; 47 | 48 | /** 49 | \brief The device descriptor information. 50 | 51 | The device descriptor sturcture defined in the USB 2.0 manual in 9.6.1. 52 | */ 53 | struct UsbDeviceDescriptor { 54 | u8 DescriptorLength; // +0x0 55 | enum DescriptorType DescriptorType : 8; // +0x1 56 | u16 UsbVersion; // (in BCD 0x210 = USB2.10) +0x2 57 | enum DeviceClass { 58 | DeviceClassInInterface = 0x00, 59 | DeviceClassCommunications = 0x2, 60 | DeviceClassHub = 0x9, 61 | DeviceClassDiagnostic = 0xdc, 62 | DeviceClassMiscellaneous = 0xef, 63 | DeviceClassVendorSpecific = 0xff, 64 | } Class : 8; // +0x4 65 | u8 SubClass; // +0x5 66 | u8 Protocol; // +0x6 67 | u8 MaxPacketSize0; // +0x7 68 | u16 VendorId; // +0x8 69 | u16 ProductId; // +0xa 70 | u16 Version; // +0xc 71 | u8 Manufacturer; // +0xe 72 | u8 Product; // +0xf 73 | u8 SerialNumber; // +0x10 74 | u8 ConfigurationCount; // +0x11 75 | } __attribute__ ((__packed__)); 76 | 77 | /** 78 | \brief The device qualifier descriptor information. 79 | 80 | The device descriptor qualifier sturcture defined in the USB 2.0 manual in 81 | 9.6.2. 82 | */ 83 | struct UsbDeviceQualifierDescriptor { 84 | u8 DescriptorLength; // +0x0 85 | enum DescriptorType DescriptorType : 8; // +0x1 86 | u16 UsbVersion; // (in BCD 0x210 = USB2.10) +0x2 87 | enum DeviceClass Class : 8; // +0x4 88 | u8 SubClass; // +0x5 89 | u8 Protocol; // +0x6 90 | u8 MaxPacketSize0; // +0x7 91 | u8 ConfigurationCount; // +0x8 92 | u8 _reserved9; // +0x9 93 | } __attribute__ ((__packed__)); 94 | 95 | /** 96 | \brief The configuration descriptor information. 97 | 98 | The configuration descriptor structure defined in the USB2.0 manual section 99 | 9.6.3. 100 | */ 101 | struct UsbConfigurationDescriptor { 102 | u8 DescriptorLength; // +0x0 103 | enum DescriptorType DescriptorType : 8; // +0x1 104 | u16 TotalLength; // +0x2 105 | u8 InterfaceCount; // +0x4 106 | u8 ConfigurationValue; // +0x5 107 | u8 StringIndex; // +0x6 108 | struct { 109 | unsigned _reserved0_4 : 5; // @0 110 | bool RemoteWakeup : 1; // @5 111 | bool SelfPowered : 1; // @6 112 | unsigned _reserved7 : 1; // @7 113 | } Attributes; // +0x7 114 | u8 MaximumPower; // +0x8 115 | } __attribute__ ((__packed__)); 116 | 117 | /** 118 | \breif The other speed configuration descriptor. 119 | 120 | The other speed configuration descriptor defined in the USB2.0 manual section 121 | 9.6.4. 122 | */ 123 | struct UsbOtherSpeedConfigurationDescriptor { 124 | u8 DescriptorLength; // +0x0 125 | enum DescriptorType DescriptorType : 8; // +0x1 126 | u16 TotalLength; // +0x2 127 | u8 InterfaceCount; // +0x4 128 | u8 ConfigurationValue; // +0x5 129 | u8 StringIndex; // +0x6 130 | struct { 131 | unsigned _reserved0_4 : 5; // @0 132 | bool RemoteWakeup : 1; // @5 133 | bool SelfPowered : 1; // @6 134 | enum { 135 | Valid = 1, 136 | } _reserved7 : 1; // @7 137 | } Attributes; // +0x7 138 | u8 MaximumPower; // +0x8 139 | } __attribute__ ((__packed__)); 140 | 141 | /** 142 | \brief The interface descriptor information. 143 | 144 | The interface descriptor structure defined in the USB2.0 manual section 145 | 9.6.5. 146 | */ 147 | struct UsbInterfaceDescriptor { 148 | u8 DescriptorLength; // +0x0 149 | enum DescriptorType DescriptorType : 8; // +0x1 150 | u8 Number; // +0x2 151 | u8 AlternateSetting; // +0x3 152 | u8 EndpointCount; // +0x4 153 | enum InterfaceClass { 154 | InterfaceClassReserved = 0x0, 155 | InterfaceClassAudio = 0x1, 156 | InterfaceClassCommunications = 0x2, 157 | InterfaceClassHid = 0x3, 158 | InterfaceClassPhysical = 0x5, 159 | InterfaceClassImage = 0x6, 160 | InterfaceClassPrinter = 0x7, 161 | InterfaceClassMassStorage = 0x8, 162 | InterfaceClassHub = 0x9, 163 | InterfaceClassCdcData = 0xa, 164 | InterfaceClassSmartCard = 0xb, 165 | InterfaceClassContentSecurity = 0xd, 166 | InterfaceClassVideo = 0xe, 167 | InterfaceClassPersonalHealthcare = 0xf, 168 | InterfaceClassAudioVideo = 0x10, 169 | InterfaceClassDiagnosticDevice = 0xdc, 170 | InterfaceClassWirelessController = 0xe0, 171 | InterfaceClassMiscellaneous = 0xef, 172 | InterfaceClassApplicationSpecific = 0xfe, 173 | InterfaceClassVendorSpecific = 0xff, 174 | } Class : 8; // +x05 175 | u8 SubClass; 176 | u8 Protocol; 177 | u8 StringIndex; 178 | } __attribute__ ((__packed__)); 179 | 180 | /** 181 | \brief The endpoint descriptor information. 182 | 183 | The endpoint descriptor structure defined in the USB2.0 manual section 184 | 9.6.6. 185 | */ 186 | struct UsbEndpointDescriptor { 187 | u8 DescriptorLength; // +0x0 188 | enum DescriptorType DescriptorType : 8; // +0x1 189 | struct { 190 | unsigned Number : 4; // @0 191 | unsigned _reserved4_6 : 3; // @4 192 | UsbDirection Direction : 1; // @7 193 | } EndpointAddress; // +0x2 194 | struct { 195 | UsbTransfer Type : 2; // @0 196 | enum { 197 | NoSynchronisation = 0, 198 | Asynchronous = 1, 199 | Adaptive = 2, 200 | Synchrouns = 3, 201 | } Synchronisation : 2; // @2 202 | enum { 203 | Data = 0, 204 | Feeback = 1, 205 | ImplicitFeebackData = 2, 206 | } Usage : 2; // @4 207 | unsigned _reserved6_7 : 2; // @6 208 | } Attributes; // +0x3 209 | struct { 210 | unsigned MaxSize : 11; // @0 211 | enum { 212 | None = 0, 213 | Extra1 = 1, 214 | Extra2 = 2, 215 | } Transactions : 2; // @11 216 | unsigned _reserved13_15 : 3; // @13 217 | } Packet; // +0x4 218 | u8 Interval; // +0x6 219 | } __attribute__ ((__packed__)); 220 | 221 | /** 222 | \brief The string descriptor information. 223 | 224 | The string descriptor structure defined in the USB2.0 manual section 225 | 9.6.7. 226 | */ 227 | struct UsbStringDescriptor { 228 | u8 DescriptorLength; // +0x0 229 | enum DescriptorType DescriptorType : 8; // +0x1 230 | u16 Data[]; // +0x2 amount varies 231 | } __attribute__ ((__packed__)); 232 | 233 | #endif // _USBD_DESCRIPTORS_H -------------------------------------------------------------------------------- /csud/old/include/usbd/device.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * usbd/device.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * usbd/device.h contains a definition of a device structure used for 9 | * storing devices and the device tree. 10 | ******************************************************************************/ 11 | #ifndef _DEVICE_H 12 | #define _DEVICE_H 13 | 14 | #include 15 | #include 16 | 17 | /** 18 | \brief The maximum number of children a device could have, by implication, this is 19 | the maximum number of ports a hub supports. 20 | 21 | This is theoretically 255, as 8 bits are used to transfer the port count in 22 | a hub descriptor. Practically, no hub has more than 10, so we instead allow 23 | that many. Increasing this number will waste space, but will not have 24 | adverse consequences up to 255. Decreasing this number will save a little 25 | space in the HubDevice structure, at the risk of removing support for an 26 | otherwise valid hub. 27 | */ 28 | #define MaxChildrenPerDevice 10 29 | /** 30 | \brief The maximum number of interfaces a device configuration could have. 31 | 32 | This is theoretically 255 as one byte is used to transfer the interface 33 | count in a configuration descriptor. In practice this is unlikely, so we 34 | allow an arbitrary 8. Increasing this number wastes (a lot) of space in 35 | every device structure, but should not have other consequences up to 255. 36 | Decreasing this number reduces the overheads of the UsbDevice structure, at 37 | the cost of possibly rejecting support for an otherwise supportable device. 38 | */ 39 | #define MaxInterfacesPerDevice 8 40 | /** 41 | \brief The maximum number of endpoints a device could have (per interface). 42 | 43 | This is theoretically 16, as four bits are used to transfer the endpoint 44 | number in certain device requests. This is possible in practice, so we 45 | allow that many. Decreasing this number reduces the space in each device 46 | structure considerably, while possible removing support for otherwise valid 47 | devices. This number should not be greater than 16. 48 | */ 49 | #define MaxEndpointsPerDevice 16 50 | 51 | /** 52 | \brief Status of a USB device. 53 | 54 | Stores the status of a USB device. Statuses as defined in 9.1 of the USB2.0 55 | manual. 56 | */ 57 | enum UsbDeviceStatus { 58 | Attached = 0, 59 | Powered = 1, 60 | Default = 2, 61 | Addressed = 3, 62 | Configured = 4, 63 | }; 64 | 65 | 66 | /** 67 | \brief Status of a USB transfer. 68 | 69 | Stores the status of the last transfer a USB device did. 70 | */ 71 | enum UsbTransferError { 72 | NoError = 0, 73 | Stall = 1 << 1, 74 | BufferError = 1 << 2, 75 | Babble = 1 << 3, 76 | NoAcknowledge = 1 << 4, 77 | CrcError = 1 << 5, 78 | BitError = 1 << 6, 79 | ConnectionError = 1 << 7, 80 | AhbError = 1 << 8, 81 | NotYetError = 1 << 9, 82 | Processing = 1 << 31 83 | }; 84 | 85 | /** 86 | \brief Start of a device specific data field. 87 | 88 | The first two words of driver data in a UsbDevice. The DeviceDriver field 89 | is a code which uniquely identifies the driver that set the driver data 90 | field (i.e. the lowest driver in the stack above the USB driver). The 91 | DataSize is the size in bytes of the device specific data field. 92 | */ 93 | struct UsbDriverDataHeader { 94 | u32 DeviceDriver; 95 | u32 DataSize; 96 | }; 97 | 98 | /** 99 | \brief Structure to store the details of a USB device that has been 100 | detectd. 101 | 102 | Stores the details about a connected USB device. This is not directly part 103 | of the USB standard, and is instead a mechanism used to control the device 104 | tree. 105 | */ 106 | struct UsbDevice { 107 | u32 Number; 108 | 109 | UsbSpeed Speed; 110 | enum UsbDeviceStatus Status; 111 | volatile u8 ConfigurationIndex; 112 | u8 PortNumber; 113 | volatile enum UsbTransferError Error __attribute__((aligned(4))); 114 | 115 | // Generic device handlers 116 | /** Handler for detaching the device. The device driver should not issue further requests to the device. */ 117 | void (*DeviceDetached)(struct UsbDevice *device) __attribute__((aligned(4))); 118 | /** Handler for deallocation of the device. All memory in use by the device driver should be deallocated. */ 119 | void (*DeviceDeallocate)(struct UsbDevice *device); 120 | /** Handler for checking for changes to the USB device tree. Only hubs need handle with this. */ 121 | void (*DeviceCheckForChange)(struct UsbDevice *device); 122 | /** Handler for removing a child device from this device. Only hubs need handle with this. */ 123 | void (*DeviceChildDetached)(struct UsbDevice *device, struct UsbDevice *child); 124 | /** Handler for reseting a child device of this device. Only hubs need handle with this. */ 125 | Result (*DeviceChildReset)(struct UsbDevice *device, struct UsbDevice *child); 126 | /** Handler for reseting a child device of this device. Only hubs need handle with this. */ 127 | Result (*DeviceCheckConnection)(struct UsbDevice *device, struct UsbDevice *child); 128 | 129 | volatile struct UsbDeviceDescriptor Descriptor __attribute__((aligned(4))); 130 | volatile struct UsbConfigurationDescriptor Configuration __attribute__((aligned(4))); 131 | volatile struct UsbInterfaceDescriptor Interfaces[MaxInterfacesPerDevice] __attribute__((aligned(4))); 132 | volatile struct UsbEndpointDescriptor Endpoints[MaxInterfacesPerDevice][MaxEndpointsPerDevice] __attribute__((aligned(4))); 133 | struct UsbDevice *Parent __attribute__((aligned(4))); 134 | volatile void *FullConfiguration; 135 | volatile struct UsbDriverDataHeader *DriverData; 136 | volatile u32 LastTransfer; 137 | }; 138 | 139 | #define InterfaceClassAttachCount 16 140 | 141 | /** 142 | \brief Methods to attach a particular interface for a particular class. 143 | 144 | The class of the interface is the index into this array of methods. The 145 | array is populated by ConfigurationLoad(). 146 | */ 147 | extern Result (*InterfaceClassAttach[InterfaceClassAttachCount])(struct UsbDevice *device, u32 interfaceNumber); 148 | 149 | #endif // _DEVICE_H -------------------------------------------------------------------------------- /csud/old/include/usbd/devicerequest.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * usbd/devicerequest.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * usbd/devicerequest.h contains a definition of the standard device 9 | * request structure defined in USB2.0 10 | ******************************************************************************/ 11 | #ifndef _DEVICEREQUEST_H 12 | #define _DEVICEREQUEST_H 13 | 14 | #include 15 | 16 | /** 17 | \brief An encapsulated device request. 18 | 19 | A device request is a standard mechanism defined in USB2.0 manual section 20 | 9.3 by which negotiations with devices occur. The request have a number of 21 | parameters, and so are best implemented with a structure. As per usual, 22 | since this structure is arbitrary, we shall match Linux in the hopes of 23 | achieving some compatibility. 24 | */ 25 | struct UsbDeviceRequest { 26 | u8 Type; // +0x0 27 | enum UsbDeviceRequestRequest { 28 | // USB requests 29 | GetStatus = 0, 30 | ClearFeature = 1, 31 | SetFeature = 3, 32 | SetAddress = 5, 33 | GetDescriptor = 6, 34 | SetDescriptor = 7, 35 | GetConfiguration = 8, 36 | SetConfiguration = 9, 37 | GetInterface = 10, 38 | SetInterface = 11, 39 | SynchFrame = 12, 40 | // HID requests 41 | GetReport = 1, 42 | GetIdle = 2, 43 | GetProtocol = 3, 44 | SetReport = 9, 45 | SetIdle = 10, 46 | SetProtocol = 11, 47 | } Request : 8; // +0x1 48 | u16 Value; // +0x2 49 | u16 Index; // +0x4 50 | u16 Length; // +0x6 51 | }; 52 | 53 | #endif // _DEVICEREQUEST_H -------------------------------------------------------------------------------- /csud/old/include/usbd/pipe.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * usbd/pipe.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * usbd/pipe.h contains definitions relating to the USB pipe structure, 9 | * defined as part of the USB protocol. The precise details of this data 10 | * structure are an implementation detail, matching Linux in this case to 11 | * aid compatibility. 12 | ******************************************************************************/ 13 | #ifndef _USBD_PIPE_H 14 | #define _USBD_PIPE_H 15 | 16 | #include 17 | 18 | /** 19 | \brief Our implementation of the USB pipe defined in 10.5.1. 20 | 21 | The UsbPipeAddress holds the address of a pipe. The USB standard defines 22 | these as a software mechanism for communication between the USB driver and the 23 | host controller driver. We shall not have a concept of creating or destroying 24 | pipes, as this is needless clutter, and simply just indicate the pipe by its 25 | physical properties. In other words, we identify the pipe by its physical 26 | consequences on the USB. This is similar to Linux, and vastly reduces 27 | complication, at the expense of requiring a little more sophistication on the 28 | sender's behalf. 29 | */ 30 | struct UsbPipeAddress { 31 | UsbPacketSize MaxSize : 2; // @0 32 | UsbSpeed Speed : 2; // @2 33 | unsigned EndPoint : 4; // @4 34 | unsigned Device : 8; // @8 35 | UsbTransfer Type : 2; // @16 36 | UsbDirection Direction : 1; // @18 37 | unsigned _reserved19_31 : 13; // @19 38 | }; 39 | 40 | #endif // _USBD_PIPE_H -------------------------------------------------------------------------------- /csud/old/include/usbd/usbd.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * usbd/usbd.h 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * usbd/usbd.h contains definitions relating to the generic USB driver. USB 9 | * is designed such that this driver's interface would be virtually the same 10 | * across all systems, and in fact its implementation varies little either. 11 | ******************************************************************************/ 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /** 18 | \brief Performs all necessary operationg to start the USB driver. 19 | 20 | Initialises the USB driver by performing necessary interfactions with the 21 | host controller driver, and enumerating the device tree. 22 | */ 23 | Result UsbInitialise(); 24 | 25 | /** 26 | \brief Gets the descriptor for a given device. 27 | 28 | Gets the descriptor for a given device, using the index and language id 29 | specified. The returned value is not longer than length. 30 | */ 31 | Result UsbGetDescriptor(struct UsbDevice *device, enum DescriptorType type, 32 | u8 index, u16 langId, void* buffer, u32 length, u32 minimumLength, u8 recipient); 33 | 34 | /** 35 | \brief Sends a control message synchronously to a given device. 36 | 37 | Sends a contorl message synchronously to a given device, then waits for 38 | completion. If the timeout is reached returns ErrorTimeout. This puts 39 | device into an inconsistent state, so best not to use it until processing 40 | is unset. 41 | */ 42 | Result UsbControlMessage(struct UsbDevice *device, 43 | struct UsbPipeAddress pipe, void* buffer, u32 bufferLength, 44 | struct UsbDeviceRequest *request, u32 timeout); 45 | 46 | /** 47 | \brief Allocates memory to a new device. 48 | 49 | Sets the value in the parameter device to the address of a new device 50 | allocated on the heap, which then has appropriate default values. 51 | */ 52 | Result UsbAllocateDevice(struct UsbDevice **device); 53 | 54 | /* 55 | \brief Deallocates the memory and resources of a USB device. 56 | 57 | Recursively deallocates the device and all children. Deallocates any class 58 | specific data, as well as the device structure itself and releases the 59 | device number. 60 | */ 61 | void UsbDeallocateDevice(struct UsbDevice *device); 62 | 63 | /** 64 | \brief Recursively enumerates a new device. 65 | 66 | Recursively enumerates a new device that has been allocated. This assigns 67 | an address, determines what the device is, and, if it is a hub, will 68 | configure the device recursively look for new devices. If not, it will 69 | configure the device with the default configuration. 70 | */ 71 | Result UsbAttachDevice(struct UsbDevice *device); 72 | 73 | /** 74 | \brief Returns a description for a device. 75 | 76 | Returns a description for a device. This is not read from the device, this 77 | is just generated given by the driver. 78 | */ 79 | const char* UsbGetDescription(struct UsbDevice *device); 80 | 81 | /** 82 | \brief Returns a pointer to the root hub device. 83 | 84 | On a Universal Serial Bus, there exists a root hub. This if often a virtual 85 | device, and typically represents a one port hub, which is the physical 86 | universal serial bus for this computer. It is always address 1. It is 87 | present to allow uniform software manipulation of the universal serial bus 88 | itself. 89 | */ 90 | struct UsbDevice *UsbGetRootHub(); 91 | 92 | /** 93 | \brief Scans the entire USB tree for changes. 94 | 95 | Recursively calls HubCheckConnection on all ports on all hubs connected to 96 | the root hub. 97 | */ 98 | void UsbCheckForChange(); -------------------------------------------------------------------------------- /csud/old/makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # makefile 3 | # by Alex Chadwick 4 | # 5 | # A makefile script for generation of CSUD. 6 | ############################################################################### 7 | 8 | # Default parameters 9 | TYPE ?= LOWLEVEL 10 | TARGET ?= NONE 11 | CONFIG ?= FINAL 12 | 13 | # The intermediate directory for compiled object files. 14 | BUILD ?= build/ 15 | 16 | # The directory in which source files are stored. 17 | SOURCE ?= source/ 18 | 19 | # The directory in which configuration files are stored. 20 | CONFIGDIR ?= configuration/ 21 | 22 | # The name of the output file to generate. 23 | LIBNAME ?= libcsud.a 24 | 25 | # The include directory 26 | INCDIR ?= include/ 27 | 28 | all: 29 | # @echo CUSD - Chadderz Simple USB Driver 30 | # @echo by Alex Chadwick 31 | # @echo Usage: make driver CONFIG=config TYPE=type TARGET=target GNU=gnu 32 | # @echo Parameters: 33 | # @echo config - DEBUG or FINAL (default) 34 | # @echo alters amount of messages, checks, and the speed. 35 | # @echo type - STANDALONE, LOWLEVEL (default), or DRIVER 36 | # @echo alters how complete the driver is STANDALONE for no external 37 | # @echo dependencies LOWLEVEL for only key dependencies, DRIVER for 38 | # @echo typical levels. 39 | # @echo target - RPI, NONE (default) 40 | # @echo alters the target system. NONE for dummy driver, RPI for 41 | # @echo the RaspberryPi 42 | # @echo gnu - A gnu compiler prefix (arm-none-eabi-) or empty (default). 43 | # @echo The compiler chain to use (for cross compiling). 44 | # @echo See arguments for more. 45 | 46 | # The flags to pass to GCC for compiling. 47 | # -std=c99: Use c99 standard. 48 | # -fpack-struct: Do not insert unnecessary padding in structures to make them faster. 49 | # -Wno-packet-bitfield-compat: Do not warn about structures which would complie differently on older gcc. 50 | # -fshort-wchar: Treat wchar as a 16 bit value. 51 | # -Wall: Print lots of compiler warnings 52 | CFLAGS += -std=c99 -fpack-struct -Wno-packed-bitfield-compat -fshort-wchar -Wall 53 | CFLAGS += $(patsubst %,-I%,$(INCDIRS)) 54 | 55 | include $(CONFIGDIR)makefile.in 56 | include $(SOURCE)makefile.in 57 | 58 | # Rule to make everything. 59 | driver: $(LIBNAME) 60 | 61 | # Rule to make the driver file. 62 | $(LIBNAME) : $(patsubst %/,%, $(BUILD)) $(OBJECTS) 63 | rm -f $(LIBNAME) 64 | arm-none-eabi-ar rc $(LIBNAME) $(OBJECTS) 65 | 66 | # Rule to make the c object files. 67 | GCC := arm-none-eabi-gcc $(CFLAGS) -c -I$(INCDIR) 68 | 69 | $(BUILD): 70 | mkdir $(patsubst %/,%, $(BUILD)) 71 | 72 | # Rule to clean files. 73 | clean : 74 | rm -f $(BUILD)* 75 | rm -f $(LIBNAME) 76 | 77 | .PHONY: clean driver all 78 | -------------------------------------------------------------------------------- /csud/old/readme: -------------------------------------------------------------------------------- 1 | CSUD - Chadderz's Simple USB Driver 2 | by Alex Chadwick 3 | 4 | A USB driver originally written for the raspberry pi (which uses a DesignWare� 5 | Hi-Speed USB 2.0 On-The-Go (HS OTG) Controller), to be integrated into any 6 | operating system with appropriate wrappers. 7 | 8 | The USB standard is prohibitively long and difficult to read, and so this 9 | driver was created to allow those working in Operating Systems development to 10 | achieve USB support, primarily in order to gain access to the keyboard, as this 11 | is the only sensible input on the Raspberry Pi. CSUD is designed to function 12 | either as a standalone code section with no external dependencies, or as a more 13 | typical driver, with external dependencies. CSUD itself is modular, and so 14 | could have components exchanged or replaced. 15 | 16 | CSUD is broken down into a few drivers: 17 | * Generic USB driver (usbd) - manages parts of USB that do not change per 18 | system, for example device enumeration and configuration. Provides 19 | a standard interface to the environment specific host controller. 20 | * Host Controller driver (hcd) - environment specific driver that handles 21 | communication with the physical universal serial bus. No generic 22 | hcd exists, instead a common header file is used for any hcd to 23 | allow the usbd to interact in a generic way. The hcd should 24 | translate between this interface and the physical hardware. 25 | * DesignWare Core (dwc) driver - a specific hcd for the Synopsis DesignWare 26 | Core host controller. 27 | * Hub driver - driver for hubs, one of the most fundamental devices to USB. 28 | Hubs allow multiple devices to utilise a single port, and many 29 | devices are abstracted into hubs. The hub driver is almost 30 | complete, lacking only features pertaining to interrupt transfers. 31 | Built on top of the usbd. 32 | * Human Interface Device (hid) driver - Driver supporting the generic 33 | USB hid standard, which allows communication with logging and 34 | sensing devices. Built on top of the usbd. 35 | * Keyboard (kbd) driver - Driver supporting communication with keyboards. 36 | Built on top of the hid driver, as USB keyboards are a specific 37 | subset of hid devices. Does not have interrupt transfers, limiting 38 | support severely (6/12 keyboards tested functioned correctly). 39 | * Mouse driver - Driver supporting communication with mice. By Steve White. 40 | Built on top of the hid driver, as USB mice are a specific subset 41 | of hid devices. Does not have interrupt transfers, unknown how well 42 | supported it is. 43 | 44 | At present, only USB control transfers are supported by the hcd and usbd, which 45 | is very limiting. Supporting interrupt transfers would be a major benefit, as 46 | most devices require at least these two. 47 | 48 | In order to achieve wider support, the /configuration has a number of makefile 49 | include scripts which can configure the build. The overall makefile also 50 | supports a number of arguments. The arguments are outlined in the file 51 | arguments. 52 | 53 | Since the driver can be standalone, the code in /source/platform.c provides an 54 | interface to 'system' routines. Thus, it implements many methods which are 55 | standardised, such as malloc, memcpy, free, print; though these are 56 | deliberately not named as such. This is to avoid conflict with alternative 57 | definitions should the need arise. Normally, it is perfectly acceptable to 58 | write a wrapper which simply calls these functions when the equivalent is 59 | invoked. For compatibility, print uses both the null termination convention, 60 | and passes the length as an additional argument. 61 | 62 | The mapping between standard methods and platform.c's version is as follows: 63 | malloc <-> MemoryAllocate 64 | free <-> MemoryDeallocate 65 | memcpy <-> MemoryCopy 66 | print <-> LogPrint 67 | 68 | The file structure of the CSUD is as follows: 69 | configuration/ makefile scripts for changing CSUD's build configuration. 70 | include/ included header files. 71 | device/ header files for device drivers 72 | hid/ header files for human interface devices. 73 | hcd/ header files for the host controller driver. 74 | dwc/ header files for the DesignWare core. 75 | platform/ header files for the system CSUD runs in. 76 | arm/ header files for ARM platforms. 77 | none/ header files for generic platforms. 78 | usbd/ header files for the generic USB driver. 79 | 80 | source/ source code files. 81 | device/ source code for device drivers 82 | hid/ source code for human interface device drivers. 83 | hcd/ source code for the host controller driver 84 | dwc/ source code for the DesignWare host controller 85 | platform/ source code for the system CSUD runs in. 86 | arm/ source code for ARM platforms. 87 | usbd/ source code for the generic USB driver. 88 | -------------------------------------------------------------------------------- /csud/old/source/configuration.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * configuration.c 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * configuration.c contains code to load all components. In order to 9 | * allow the actual source files to be completely independent, one file must 10 | * exist which depends upon all of them, to perform static initialisation. 11 | * Each separate 'library' provides a Load method, which ConfigurationLoad 12 | * simply invoeks all of. 13 | ******************************************************************************/ 14 | 15 | #include 16 | #include 17 | 18 | // Add load methods for new modules wrapped in ifdefs here: 19 | void UsbLoad(); 20 | void PlatformLoad(); 21 | #ifdef LIB_ARM_V6 22 | void Arm6Load(); 23 | #endif 24 | #ifdef LIB_BCM2835 25 | void Bcm2835Load(); 26 | #endif 27 | #ifdef LIB_DWC 28 | void DwcLoad(); 29 | #endif 30 | #ifdef LIB_HID 31 | void HidLoad(); 32 | #endif 33 | #ifdef LIB_HUB 34 | void HubLoad(); 35 | #endif 36 | #ifdef LIB_KBD 37 | void KbdLoad(); 38 | #endif 39 | #ifdef LIB_MOUSE 40 | void MouseLoad(); 41 | #endif 42 | 43 | void ConfigurationLoad() { 44 | // Call each libraries load method here. Watch out for the order, load more 45 | // generic libraries first. 46 | PlatformLoad(); 47 | #ifdef LIB_ARM_V6 48 | Arm6Load(); 49 | #endif 50 | #ifdef LIB_BCM2835 51 | Bcm2835Load(); 52 | #endif 53 | UsbLoad(); 54 | #ifdef LIB_DWC 55 | DwcLoad(); 56 | #endif 57 | #ifdef LIB_HID 58 | HidLoad(); 59 | #endif 60 | #ifdef LIB_HUB 61 | HubLoad(); 62 | #endif 63 | #ifdef LIB_KBD 64 | KbdLoad(); 65 | #endif 66 | #ifdef LIB_MOUSE 67 | MouseLoad(); 68 | #endif 69 | } -------------------------------------------------------------------------------- /csud/old/source/device/hid/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)hid/ 2 | 3 | OBJECTS += $(BUILD)hid.c.o 4 | CFLAGS += -DLIB_HID 5 | 6 | $(BUILD)hid.c.o: $(DIR)hid.c $(INCDIR)device/hid/hid.h $(INCDIR)device/hid/report.h $(INCDIR)platform/platform.h $(INCDIR)usbd/descriptors.h $(INCDIR)usbd/device.h $(INCDIR)types.h $(INCDIR)usbd/usbd.h 7 | $(GCC) $< -o $@ 8 | 9 | ifeq ("$(LIB_KBD)", "1") 10 | CFLAGS += -DLIB_KBD 11 | OBJECTS += $(BUILD)keyboard.c.o 12 | 13 | $(BUILD)keyboard.c.o: $(DIR)keyboard.c $(INCDIR)device/hid/hid.h $(INCDIR)device/hid/keyboard.h $(INCDIR)device/hid/report.h $(INCDIR)platform/platform.h $(INCDIR)usbd/device.h $(INCDIR)types.h $(INCDIR)usbd/usbd.h 14 | $(GCC) $< -o $@ 15 | endif 16 | 17 | ifeq ("$(LIB_MOUSE)", "1") 18 | CFLAGS += -DLIB_MOUSE 19 | OBJECTS += $(BUILD)mouse.c.o 20 | 21 | $(BUILD)mouse.c.o: $(DIR)mouse.c $(INCDIR)device/hid/hid.h $(INCDIR)device/hid/mouse.h $(INCDIR)device/hid/report.h $(INCDIR)platform/platform.h $(INCDIR)usbd/device.h $(INCDIR)types.h $(INCDIR)usbd/usbd.h 22 | $(GCC) $< -o $@ 23 | endif 24 | -------------------------------------------------------------------------------- /csud/old/source/device/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)device/ 2 | 3 | ifeq ("$(LIB_HUB)", "1") 4 | CFLAGS += -DLIB_HUB 5 | OBJECTS += $(BUILD)hub.c.o 6 | 7 | $(BUILD)hub.c.o: $(DIR)hub.c $(INCDIR)device/hub.h $(INCDIR)hcd/hcd.h $(INCDIR)platform/platform.h $(INCDIR)usbd/device.h $(INCDIR)usbd/devicerequest.h $(INCDIR)usbd/descriptors.h $(INCDIR)usbd/pipe.h $(INCDIR)usbd/usbd.h 8 | $(GCC) $< -o $@ 9 | endif 10 | 11 | ifeq ("$(LIB_HID)", "1") 12 | include $(DIR)hid/makefile.in 13 | endif -------------------------------------------------------------------------------- /csud/old/source/hcd/dwc/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)dwc/ 2 | 3 | OBJECTS += $(BUILD)designware20.c.o 4 | OBJECTS += $(BUILD)roothub.c.o 5 | 6 | $(BUILD)designware20.c.o: $(DIR)designware20.c $(INCDIR)hcd/hcd.h $(INCDIR)usbd/device.h $(INCDIR)usbd/devicerequest.h $(INCDIR)usbd/pipe.h $(INCDIR)types.h 7 | $(GCC) $< -o $@ 8 | 9 | $(BUILD)roothub.c.o: $(DIR)roothub.c $(INCDIR)device/hub.h $(INCDIR)hcd/hcd.h $(INCDIR)usbd/descriptors.h $(INCDIR)usbd/device.h $(INCDIR)usbd/devicerequest.h $(INCDIR)usbd/pipe.h $(INCDIR)types.h 10 | $(GCC) $< -o $@ -------------------------------------------------------------------------------- /csud/old/source/hcd/dwc/roothub.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlar54/Commodore-Pi/41aa2a1e4a802a9f9dfca3e2a913926cdb0c1870/csud/old/source/hcd/dwc/roothub.c -------------------------------------------------------------------------------- /csud/old/source/hcd/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)hcd/ 2 | 3 | ifeq ("$(LIB_DWC)", "1") 4 | include $(DIR)dwc/makefile.in 5 | endif -------------------------------------------------------------------------------- /csud/old/source/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(SOURCE) 2 | 3 | OBJECTS += $(BUILD)configuration.c.o 4 | 5 | $(BUILD)configuration.c.o: $(DIR)configuration.c 6 | $(GCC) $< -o $@ 7 | 8 | DIR := $(SOURCE) 9 | include $(DIR)device/makefile.in 10 | 11 | DIR := $(SOURCE) 12 | include $(DIR)hcd/makefile.in 13 | 14 | DIR := $(SOURCE) 15 | include $(DIR)platform/makefile.in 16 | 17 | DIR := $(SOURCE) 18 | include $(DIR)usbd/makefile.in 19 | -------------------------------------------------------------------------------- /csud/old/source/platform/arm/armv6.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * platform/arm/armv6.c 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * platform/arm/armv6.c contains code for arm version 6 processors. Compiled 9 | * conditionally on LIB_ARM_V6=1. 10 | ******************************************************************************/ 11 | #include 12 | #include 13 | #include 14 | 15 | void Arm6Load() 16 | { 17 | LOG_DEBUG("CSUD: ARMv6 driver version 0.1.\n"); 18 | } 19 | 20 | #ifndef TYPE_DRIVER 21 | u64 __aeabi_uidivmod(u32 value, u32 divisor) { 22 | u64 answer = 0; 23 | 24 | for (u32 i = 0; i < 32; i++) { 25 | if ((divisor << (31 - i)) >> (31 - i) == divisor) { 26 | if (value >= divisor << (31 - i)) { 27 | value -= divisor << (31 - i); 28 | answer |= 1 << (31 - i); 29 | if (value == 0) break; 30 | } 31 | } 32 | } 33 | 34 | answer |= (u64)value << 32; 35 | return answer; 36 | }; 37 | 38 | u32 __aeabi_uidiv(u32 value, u32 divisor) { 39 | return __aeabi_uidivmod(value, divisor); 40 | }; 41 | #endif -------------------------------------------------------------------------------- /csud/old/source/platform/arm/broadcom2835.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * platform/arm/broadcom2835.c 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * platform/arm/broadcom2835.c contains code for the broadcom2835 chip, used 9 | * in the Raspberry Pi. Compiled conditionally on LIB_BCM2835=1. 10 | ******************************************************************************/ 11 | #include 12 | #include 13 | #include 14 | 15 | void Bcm2835Load() 16 | { 17 | LOG_DEBUG("CSUD: Broadcom2835 driver version 0.1.\n"); 18 | } 19 | 20 | #ifndef TYPE_DRIVER 21 | 22 | void MicroDelay(u32 delay) { 23 | volatile u64* timeStamp = (u64*)0x20003004; 24 | u64 stop = *timeStamp + delay; 25 | 26 | while (*timeStamp < stop) 27 | __asm__("nop"); 28 | } 29 | 30 | Result PowerOnUsb() { 31 | volatile u32* mailbox; 32 | u32 result; 33 | 34 | mailbox = (u32*)0x2000B880; 35 | while (mailbox[6] & 0x80000000); 36 | mailbox[8] = 0x80; 37 | do { 38 | while (mailbox[6] & 0x40000000); 39 | } while (((result = mailbox[0]) & 0xf) != 0); 40 | return result == 0x80 ? OK : ErrorDevice; 41 | } 42 | 43 | #endif -------------------------------------------------------------------------------- /csud/old/source/platform/arm/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)arm/ 2 | 3 | ifeq ("$(LIB_BCM2835)", "1") 4 | OBJECTS += $(BUILD)broadcom2835.c.o 5 | 6 | $(BUILD)broadcom2835.c.o: $(DIR)broadcom2835.c $(INCDIR)configuration.h $(INCDIR)types.h $(INCDIR)platform/platform.h 7 | $(GCC) $< -o $@ 8 | endif 9 | ifeq ("$(LIB_ARM_V6)", "1") 10 | OBJECTS += $(BUILD)armv6.c.o 11 | 12 | $(BUILD)armv6.c.o: $(DIR)armv6.c $(INCDIR)configuration.h $(INCDIR)types.h $(INCDIR)platform/platform.h 13 | $(GCC) $< -o $@ 14 | endif -------------------------------------------------------------------------------- /csud/old/source/platform/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)platform/ 2 | 3 | OBJECTS += $(BUILD)platform.c.o 4 | 5 | $(BUILD)platform.c.o: $(DIR)platform.c $(INCDIR)platform/platform.h 6 | $(GCC) $< -o $@ 7 | 8 | include $(DIR)arm/makefile.in -------------------------------------------------------------------------------- /csud/old/source/usbd/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)usbd/ 2 | 3 | OBJECTS += $(BUILD)usbd.c.o 4 | 5 | $(BUILD)usbd.c.o: $(DIR)usbd.c $(INCDIR)hcd/hcd.h $(INCDIR)platform/platform.h $(INCDIR)usbd/descriptors.h $(INCDIR)usbd/usbd.h 6 | $(GCC) $< -o $@ 7 | -------------------------------------------------------------------------------- /csud/readme: -------------------------------------------------------------------------------- 1 | CSUD - Chadderz's Simple USB Driver 2 | by Alex Chadwick 3 | 4 | A USB driver originally written for the raspberry pi (which uses a DesignWare� 5 | Hi-Speed USB 2.0 On-The-Go (HS OTG) Controller), to be integrated into any 6 | operating system with appropriate wrappers. 7 | 8 | The USB standard is prohibitively long and difficult to read, and so this 9 | driver was created to allow those working in Operating Systems development to 10 | achieve USB support, primarily in order to gain access to the keyboard, as this 11 | is the only sensible input on the Raspberry Pi. CSUD is designed to function 12 | either as a standalone code section with no external dependencies, or as a more 13 | typical driver, with external dependencies. CSUD itself is modular, and so 14 | could have components exchanged or replaced. 15 | 16 | CSUD is broken down into a few drivers: 17 | * Generic USB driver (usbd) - manages parts of USB that do not change per 18 | system, for example device enumeration and configuration. Provides 19 | a standard interface to the environment specific host controller. 20 | * Host Controller driver (hcd) - environment specific driver that handles 21 | communication with the physical universal serial bus. No generic 22 | hcd exists, instead a common header file is used for any hcd to 23 | allow the usbd to interact in a generic way. The hcd should 24 | translate between this interface and the physical hardware. 25 | * DesignWare Core (dwc) driver - a specific hcd for the Synopsis DesignWare 26 | Core host controller. 27 | * Hub driver - driver for hubs, one of the most fundamental devices to USB. 28 | Hubs allow multiple devices to utilise a single port, and many 29 | devices are abstracted into hubs. The hub driver is almost 30 | complete, lacking only features pertaining to interrupt transfers. 31 | Built on top of the usbd. 32 | * Human Interface Device (hid) driver - Driver supporting the generic 33 | USB hid standard, which allows communication with logging and 34 | sensing devices. Built on top of the usbd. 35 | * Keyboard (kbd) driver - Driver supporting communication with keyboards. 36 | Built on top of the hid driver, as USB keyboards are a specific 37 | subset of hid devices. Does not have interrupt transfers, limiting 38 | support severely (6/12 keyboards tested functioned correctly). 39 | * Mouse driver - Driver supporting communication with mice. By Steve White. 40 | Built on top of the hid driver, as USB mice are a specific subset 41 | of hid devices. Does not have interrupt transfers, unknown how well 42 | supported it is. 43 | 44 | At present, only USB control transfers are supported by the hcd and usbd, which 45 | is very limiting. Supporting interrupt transfers would be a major benefit, as 46 | most devices require at least these two. 47 | 48 | In order to achieve wider support, the /configuration has a number of makefile 49 | include scripts which can configure the build. The overall makefile also 50 | supports a number of arguments. The arguments are outlined in the file 51 | arguments. 52 | 53 | Since the driver can be standalone, the code in /source/platform.c provides an 54 | interface to 'system' routines. Thus, it implements many methods which are 55 | standardised, such as malloc, memcpy, free, print; though these are 56 | deliberately not named as such. This is to avoid conflict with alternative 57 | definitions should the need arise. Normally, it is perfectly acceptable to 58 | write a wrapper which simply calls these functions when the equivalent is 59 | invoked. For compatibility, print uses both the null termination convention, 60 | and passes the length as an additional argument. 61 | 62 | The mapping between standard methods and platform.c's version is as follows: 63 | malloc <-> MemoryAllocate 64 | free <-> MemoryDeallocate 65 | memcpy <-> MemoryCopy 66 | print <-> LogPrint 67 | 68 | The file structure of the CSUD is as follows: 69 | configuration/ makefile scripts for changing CSUD's build configuration. 70 | include/ included header files. 71 | device/ header files for device drivers 72 | hid/ header files for human interface devices. 73 | hcd/ header files for the host controller driver. 74 | dwc/ header files for the DesignWare core. 75 | platform/ header files for the system CSUD runs in. 76 | arm/ header files for ARM platforms. 77 | none/ header files for generic platforms. 78 | usbd/ header files for the generic USB driver. 79 | 80 | source/ source code files. 81 | device/ source code for device drivers 82 | hid/ source code for human interface device drivers. 83 | hcd/ source code for the host controller driver 84 | dwc/ source code for the DesignWare host controller 85 | platform/ source code for the system CSUD runs in. 86 | arm/ source code for ARM platforms. 87 | usbd/ source code for the generic USB driver. 88 | -------------------------------------------------------------------------------- /csud/source/configuration.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * configuration.c 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * configuration.c contains code to load all components. In order to 9 | * allow the actual source files to be completely independent, one file must 10 | * exist which depends upon all of them, to perform static initialisation. 11 | * Each separate 'library' provides a Load method, which ConfigurationLoad 12 | * simply invoeks all of. 13 | ******************************************************************************/ 14 | 15 | #include 16 | #include 17 | 18 | // Add load methods for new modules wrapped in ifdefs here: 19 | void UsbLoad(); 20 | void PlatformLoad(); 21 | #ifdef LIB_ARM_V6 22 | void Arm6Load(); 23 | #endif 24 | #ifdef LIB_BCM2835 25 | void Bcm2835Load(); 26 | #endif 27 | #ifdef LIB_DWC 28 | void DwcLoad(); 29 | #endif 30 | #ifdef LIB_HID 31 | void HidLoad(); 32 | #endif 33 | #ifdef LIB_HUB 34 | void HubLoad(); 35 | #endif 36 | #ifdef LIB_KBD 37 | void KbdLoad(); 38 | #endif 39 | #ifdef LIB_MOUSE 40 | void MouseLoad(); 41 | #endif 42 | 43 | void ConfigurationLoad() { 44 | // Call each libraries load method here. Watch out for the order, load more 45 | // generic libraries first. 46 | PlatformLoad(); 47 | #ifdef LIB_ARM_V6 48 | Arm6Load(); 49 | #endif 50 | #ifdef LIB_BCM2835 51 | Bcm2835Load(); 52 | #endif 53 | UsbLoad(); 54 | #ifdef LIB_DWC 55 | DwcLoad(); 56 | #endif 57 | #ifdef LIB_HID 58 | HidLoad(); 59 | #endif 60 | #ifdef LIB_HUB 61 | HubLoad(); 62 | #endif 63 | #ifdef LIB_KBD 64 | KbdLoad(); 65 | #endif 66 | #ifdef LIB_MOUSE 67 | MouseLoad(); 68 | #endif 69 | } -------------------------------------------------------------------------------- /csud/source/device/hid/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)hid/ 2 | 3 | OBJECTS += $(BUILD)hid.c.o 4 | CFLAGS += -DLIB_HID 5 | 6 | $(BUILD)hid.c.o: $(DIR)hid.c $(INCDIR)device/hid/hid.h $(INCDIR)device/hid/report.h $(INCDIR)platform/platform.h $(INCDIR)usbd/descriptors.h $(INCDIR)usbd/device.h $(INCDIR)types.h $(INCDIR)usbd/usbd.h 7 | $(GCC) $< -o $@ 8 | 9 | ifeq ("$(LIB_KBD)", "1") 10 | CFLAGS += -DLIB_KBD 11 | OBJECTS += $(BUILD)keyboard.c.o 12 | 13 | $(BUILD)keyboard.c.o: $(DIR)keyboard.c $(INCDIR)device/hid/hid.h $(INCDIR)device/hid/keyboard.h $(INCDIR)device/hid/report.h $(INCDIR)platform/platform.h $(INCDIR)usbd/device.h $(INCDIR)types.h $(INCDIR)usbd/usbd.h 14 | $(GCC) $< -o $@ 15 | endif 16 | 17 | ifeq ("$(LIB_MOUSE)", "1") 18 | CFLAGS += -DLIB_MOUSE 19 | OBJECTS += $(BUILD)mouse.c.o 20 | 21 | $(BUILD)mouse.c.o: $(DIR)mouse.c $(INCDIR)device/hid/hid.h $(INCDIR)device/hid/mouse.h $(INCDIR)device/hid/report.h $(INCDIR)platform/platform.h $(INCDIR)usbd/device.h $(INCDIR)types.h $(INCDIR)usbd/usbd.h 22 | $(GCC) $< -o $@ 23 | endif 24 | -------------------------------------------------------------------------------- /csud/source/device/hid/mouse.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * device/mouse.c 3 | * by Steve White 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * device/mouse.c contains code relating to USB hid mice. The 9 | * driver maintains a list of the mice on the system, and allows the 10 | * operating system to retrieve the status of each one separately. It is coded 11 | * a little awkwardly on purpose to make OS development more fun! 12 | ******************************************************************************/ 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #define MouseMaxMice 4 22 | 23 | u32 mouseCount __attribute__((aligned(4))) = 0; 24 | u32 mouseAddresses[MouseMaxMice] = { 0, 0, 0, 0 }; 25 | struct UsbDevice* mice[MouseMaxMice]; 26 | 27 | void MouseLoad() 28 | { 29 | LOG_DEBUG("CSUD: Mouse driver version 0.1\n"); 30 | mouseCount = 0; 31 | for (u32 i = 0; i < MouseMaxMice; i++) 32 | { 33 | mouseAddresses[i] = 0; 34 | mice[i] = NULL; 35 | } 36 | HidUsageAttach[DesktopMouse] = MouseAttach; 37 | } 38 | 39 | u32 MouseIndex(u32 address) { 40 | if (address == 0) return 0xffffffff; 41 | 42 | for (u32 i = 0; i < mouseCount; i++) 43 | if (mouseAddresses[i] == address) 44 | return i; 45 | 46 | return 0xffffffff; 47 | } 48 | 49 | u32 MouseGetAddress(u32 index) { 50 | if (index > mouseCount) return 0; 51 | 52 | for (u32 i = 0; index >= 0 && i < MouseMaxMice; i++) { 53 | if (mouseAddresses[i] != 0) 54 | if (index-- == 0) 55 | return mouseAddresses[i]; 56 | } 57 | 58 | return 0; 59 | } 60 | 61 | void MouseDetached(struct UsbDevice *device) { 62 | struct MouseDevice *data; 63 | 64 | data = (struct MouseDevice*)((struct HidDevice*)device->DriverData)->DriverData; 65 | if (data != NULL) { 66 | if (mouseAddresses[data->Index] == device->Number) { 67 | mouseAddresses[data->Index] = 0; 68 | mouseCount--; 69 | mice[data->Index] = NULL; 70 | } 71 | } 72 | } 73 | 74 | void MouseDeallocate(struct UsbDevice *device) { 75 | struct MouseDevice *data; 76 | 77 | data = (struct MouseDevice*)((struct HidDevice*)device->DriverData)->DriverData; 78 | if (data != NULL) { 79 | MemoryDeallocate(data); 80 | ((struct HidDevice*)device->DriverData)->DriverData = NULL; 81 | } 82 | ((struct HidDevice*)device->DriverData)->HidDeallocate = NULL; 83 | ((struct HidDevice*)device->DriverData)->HidDetached = NULL; 84 | } 85 | 86 | Result MouseAttach(struct UsbDevice *device, u32 interface) { 87 | u32 mouseNumber; 88 | struct HidDevice *hidData; 89 | struct MouseDevice *data; 90 | struct HidParserResult *parse; 91 | 92 | if ((MouseMaxMice & 3) != 0) { 93 | LOG("MOUSE: Warning! MouseMaxMice not a multiple of 4. The driver wasn't built for this!\n"); 94 | } 95 | if (mouseCount == MouseMaxMice) { 96 | LOGF("MOUSE: %s not connected. Too many mice connected (%d/%d). Change MouseMaxMice in device.mouse.c to allow more.\n", UsbGetDescription(device), mouseCount, MouseMaxMice); 97 | return ErrorIncompatible; 98 | } 99 | 100 | hidData = (struct HidDevice*)device->DriverData; 101 | if (hidData->Header.DeviceDriver != DeviceDriverHid) { 102 | LOGF("MOUSE: %s isn't a HID device. The mouse driver is built upon the HID driver.\n", UsbGetDescription(device)); 103 | return ErrorIncompatible; 104 | } 105 | 106 | parse = hidData->ParserResult; 107 | if (parse->Application.Page != GenericDesktopControl || 108 | parse->Application.Desktop != DesktopMouse) { 109 | LOGF("MOUSE: %s doesn't seem to be a mouse...\n", UsbGetDescription(device)); 110 | return ErrorIncompatible; 111 | } 112 | if (parse->ReportCount < 1) { 113 | LOGF("MOUSE: %s doesn't have enough outputs to be a mouse.\n", UsbGetDescription(device)); 114 | return ErrorIncompatible; 115 | } 116 | hidData->HidDetached = MouseDetached; 117 | hidData->HidDeallocate = MouseDeallocate; 118 | 119 | if ((hidData->DriverData = MemoryAllocate(sizeof(struct MouseDevice))) == NULL) { 120 | LOGF("MOUSE: Not enough memory to allocate mouse %s.\n", UsbGetDescription(device)); 121 | return ErrorMemory; 122 | } 123 | data = (struct MouseDevice*)hidData->DriverData; 124 | data->Header.DeviceDriver = DeviceDriverMouse; 125 | data->Header.DataSize = sizeof(struct MouseDevice); 126 | data->Index = mouseNumber = 0xffffffff; 127 | for (u32 i = 0; i < MouseMaxMice; i++) { 128 | if (mouseAddresses[i] == 0) { 129 | data->Index = mouseNumber = i; 130 | mouseAddresses[i] = device->Number; 131 | mouseCount++; 132 | break; 133 | } 134 | } 135 | 136 | if (mouseNumber == 0xffffffff) { 137 | LOG("MOUSE: PANIC! Driver in inconsistent state! MouseCount is inaccurate.\n"); 138 | MouseDeallocate(device); 139 | return ErrorGeneral; 140 | } 141 | 142 | mice[mouseNumber] = device; 143 | 144 | for (u32 i = 0; i < parse->ReportCount; i++) { 145 | if (parse->Report[i]->Type == Input 146 | // && data->MouseReport == NULL 147 | ) { 148 | LOG_DEBUGF("MOUSE: Output report %d. %d fields.\n", i, parse->Report[i]->FieldCount); 149 | data->MouseReport = parse->Report[i]; 150 | } 151 | } 152 | 153 | data->mouseX = 0; 154 | data->mouseY = 0; 155 | data->wheel = 0; 156 | data->buttonState = 0; 157 | 158 | LOG_DEBUGF("MOUSE: New mouse assigned %d!\n", device->Number); 159 | 160 | return OK; 161 | } 162 | 163 | u32 MouseCount() { 164 | return mouseCount; 165 | } 166 | 167 | Result MousePoll(u32 mouseAddress) { 168 | u32 mouseNumber; 169 | Result result; 170 | struct MouseDevice *data; 171 | 172 | mouseNumber = MouseIndex(mouseAddress); 173 | if (mouseNumber == 0xffffffff) return ErrorDisconnected; 174 | data = (struct MouseDevice*)((struct HidDevice*)mice[mouseNumber]->DriverData)->DriverData; 175 | if ((result = HidReadDevice(mice[mouseNumber], data->MouseReport->Index)) != OK) { 176 | if (result != ErrorDisconnected) 177 | LOGF("MOUSE: Could not get mouse report from %s.\n", UsbGetDescription(mice[mouseNumber])); 178 | return result; 179 | } 180 | 181 | struct HidParserReport *MouseReport = data->MouseReport; 182 | if (MouseReport->Type == Input) { 183 | // XXX: I'm sure I should be using HidGetFieldValue() 184 | // But this was so terribly easy. 185 | u8 *ReportBuffer = MouseReport->ReportBuffer; 186 | data->buttonState = (u8)ReportBuffer[0]; 187 | data->mouseX += (s8)ReportBuffer[1]; 188 | data->mouseY += (s8)ReportBuffer[2]; 189 | data->wheel += (s8)ReportBuffer[3]; 190 | if (data->mouseX < 0) { 191 | data->mouseX = 0; 192 | } 193 | if (data->mouseY < 0) { 194 | data->mouseY = 0; 195 | } 196 | } 197 | 198 | return OK; 199 | } 200 | 201 | s16 MouseGetPositionX(u32 mouseAddress) { 202 | u32 mouseNumber; 203 | struct MouseDevice *data; 204 | 205 | mouseNumber = MouseIndex(mouseAddress); 206 | if (mouseNumber == 0xffffffff) return 0; 207 | data = (struct MouseDevice*)((struct HidDevice*)mice[mouseNumber]->DriverData)->DriverData; 208 | return data->mouseX; 209 | } 210 | 211 | s16 MouseGetPositionY(u32 mouseAddress) { 212 | u32 mouseNumber; 213 | struct MouseDevice *data; 214 | 215 | mouseNumber = MouseIndex(mouseAddress); 216 | if (mouseNumber == 0xffffffff) return 0; 217 | data = (struct MouseDevice*)((struct HidDevice*)mice[mouseNumber]->DriverData)->DriverData; 218 | return data->mouseY; 219 | } 220 | 221 | s16 MouseGetWheel(u32 mouseAddress) { 222 | u32 mouseNumber; 223 | struct MouseDevice *data; 224 | 225 | mouseNumber = MouseIndex(mouseAddress); 226 | if (mouseNumber == 0xffffffff) return 0; 227 | data = (struct MouseDevice*)((struct HidDevice*)mice[mouseNumber]->DriverData)->DriverData; 228 | return data->wheel; 229 | } 230 | 231 | u32 MouseGetPosition(u32 mouseAddress) { 232 | u32 mouseNumber; 233 | struct MouseDevice *data; 234 | 235 | mouseNumber = MouseIndex(mouseAddress); 236 | if (mouseNumber == 0xffffffff) return 0; 237 | data = (struct MouseDevice*)((struct HidDevice*)mice[mouseNumber]->DriverData)->DriverData; 238 | return (data->mouseX << 16) | (data->mouseY & 0xFFFF); /* x is high 16 bits; y is low 16 bits */ 239 | } 240 | 241 | u8 MouseGetButtons(u32 mouseAddress) { 242 | u32 mouseNumber; 243 | struct MouseDevice *data; 244 | 245 | mouseNumber = MouseIndex(mouseAddress); 246 | if (mouseNumber == 0xffffffff) return 0; 247 | data = (struct MouseDevice*)((struct HidDevice*)mice[mouseNumber]->DriverData)->DriverData; 248 | return data->buttonState; 249 | } 250 | 251 | bool MouseGetButtonIsPressed(u32 mouseAddress, enum MouseDeviceButton button) { 252 | u32 mouseNumber; 253 | struct MouseDevice *data; 254 | 255 | mouseNumber = MouseIndex(mouseAddress); 256 | if (mouseNumber == 0xffffffff) return 0; 257 | data = (struct MouseDevice*)((struct HidDevice*)mice[mouseNumber]->DriverData)->DriverData; 258 | 259 | switch (button) { 260 | case MouseDeviceButtonLeft: 261 | return (data->buttonState & 0x01); 262 | case MouseDeviceButtonRight: 263 | return (data->buttonState & 0x02); 264 | case MouseDeviceButtonMiddle: 265 | return (data->buttonState & 0x04); 266 | case MouseDeviceButtonSide: 267 | return (data->buttonState & 0x08); 268 | case MouseDeviceButtonExtra: 269 | return (data->buttonState & 0x10); 270 | } 271 | return false; 272 | } 273 | -------------------------------------------------------------------------------- /csud/source/device/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)device/ 2 | 3 | ifeq ("$(LIB_HUB)", "1") 4 | CFLAGS += -DLIB_HUB 5 | OBJECTS += $(BUILD)hub.c.o 6 | 7 | $(BUILD)hub.c.o: $(DIR)hub.c $(INCDIR)device/hub.h $(INCDIR)hcd/hcd.h $(INCDIR)platform/platform.h $(INCDIR)usbd/device.h $(INCDIR)usbd/devicerequest.h $(INCDIR)usbd/descriptors.h $(INCDIR)usbd/pipe.h $(INCDIR)usbd/usbd.h 8 | $(GCC) $< -o $@ 9 | endif 10 | 11 | ifeq ("$(LIB_HID)", "1") 12 | include $(DIR)hid/makefile.in 13 | endif -------------------------------------------------------------------------------- /csud/source/hcd/dwc/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)dwc/ 2 | 3 | OBJECTS += $(BUILD)designware20.c.o 4 | OBJECTS += $(BUILD)roothub.c.o 5 | 6 | $(BUILD)designware20.c.o: $(DIR)designware20.c $(INCDIR)hcd/hcd.h $(INCDIR)usbd/device.h $(INCDIR)usbd/devicerequest.h $(INCDIR)usbd/pipe.h $(INCDIR)types.h 7 | $(GCC) $< -o $@ 8 | 9 | $(BUILD)roothub.c.o: $(DIR)roothub.c $(INCDIR)device/hub.h $(INCDIR)hcd/hcd.h $(INCDIR)usbd/descriptors.h $(INCDIR)usbd/device.h $(INCDIR)usbd/devicerequest.h $(INCDIR)usbd/pipe.h $(INCDIR)types.h 10 | $(GCC) $< -o $@ -------------------------------------------------------------------------------- /csud/source/hcd/dwc/roothub.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlar54/Commodore-Pi/41aa2a1e4a802a9f9dfca3e2a913926cdb0c1870/csud/source/hcd/dwc/roothub.c -------------------------------------------------------------------------------- /csud/source/hcd/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)hcd/ 2 | 3 | ifeq ("$(LIB_DWC)", "1") 4 | include $(DIR)dwc/makefile.in 5 | endif -------------------------------------------------------------------------------- /csud/source/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(SOURCE) 2 | 3 | OBJECTS += $(BUILD)configuration.c.o 4 | 5 | $(BUILD)configuration.c.o: $(DIR)configuration.c 6 | $(GCC) $< -o $@ 7 | 8 | DIR := $(SOURCE) 9 | include $(DIR)device/makefile.in 10 | 11 | DIR := $(SOURCE) 12 | include $(DIR)hcd/makefile.in 13 | 14 | DIR := $(SOURCE) 15 | include $(DIR)platform/makefile.in 16 | 17 | DIR := $(SOURCE) 18 | include $(DIR)usbd/makefile.in 19 | -------------------------------------------------------------------------------- /csud/source/platform/arm/armv6.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * platform/arm/armv6.c 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * platform/arm/armv6.c contains code for arm version 6 processors. Compiled 9 | * conditionally on LIB_ARM_V6=1. 10 | ******************************************************************************/ 11 | #include 12 | #include 13 | #include 14 | 15 | void Arm6Load() 16 | { 17 | LOG_DEBUG("CSUD: ARMv6 driver version 0.1.\n"); 18 | } 19 | 20 | #ifndef TYPE_DRIVER 21 | u64 __aeabi_uidivmod(u32 value, u32 divisor) { 22 | u64 answer = 0; 23 | 24 | for (u32 i = 0; i < 32; i++) { 25 | if ((divisor << (31 - i)) >> (31 - i) == divisor) { 26 | if (value >= divisor << (31 - i)) { 27 | value -= divisor << (31 - i); 28 | answer |= 1 << (31 - i); 29 | if (value == 0) break; 30 | } 31 | } 32 | } 33 | 34 | answer |= (u64)value << 32; 35 | return answer; 36 | }; 37 | 38 | u32 __aeabi_uidiv(u32 value, u32 divisor) { 39 | return __aeabi_uidivmod(value, divisor); 40 | }; 41 | #endif -------------------------------------------------------------------------------- /csud/source/platform/arm/broadcom2835.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * platform/arm/broadcom2835.c 3 | * by Alex Chadwick 4 | * 5 | * A light weight implementation of the USB protocol stack fit for a simple 6 | * driver. 7 | * 8 | * platform/arm/broadcom2835.c contains code for the broadcom2835 chip, used 9 | * in the Raspberry Pi. Compiled conditionally on LIB_BCM2835=1. 10 | ******************************************************************************/ 11 | #include 12 | #include 13 | #include 14 | 15 | void Bcm2835Load() 16 | { 17 | LOG_DEBUG("CSUD: Broadcom2835 driver version 0.1.\n"); 18 | } 19 | 20 | #ifndef TYPE_DRIVER 21 | 22 | void MicroDelay(u32 delay) { 23 | volatile u64* timeStamp = (u64*)0x20003004; 24 | u64 stop = *timeStamp + delay; 25 | 26 | while (*timeStamp < stop) 27 | __asm__("nop"); 28 | } 29 | 30 | Result PowerOnUsb() { 31 | volatile u32* mailbox; 32 | u32 result; 33 | 34 | mailbox = (u32*)0x2000B880; 35 | while (mailbox[6] & 0x80000000); 36 | mailbox[8] = 0x80; 37 | do { 38 | while (mailbox[6] & 0x40000000); 39 | } while (((result = mailbox[0]) & 0xf) != 0); 40 | return result == 0x80 ? OK : ErrorDevice; 41 | } 42 | 43 | #endif -------------------------------------------------------------------------------- /csud/source/platform/arm/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)arm/ 2 | 3 | ifeq ("$(LIB_BCM2835)", "1") 4 | OBJECTS += $(BUILD)broadcom2835.c.o 5 | 6 | $(BUILD)broadcom2835.c.o: $(DIR)broadcom2835.c $(INCDIR)configuration.h $(INCDIR)types.h $(INCDIR)platform/platform.h 7 | $(GCC) $< -o $@ 8 | endif 9 | ifeq ("$(LIB_ARM_V6)", "1") 10 | OBJECTS += $(BUILD)armv6.c.o 11 | 12 | $(BUILD)armv6.c.o: $(DIR)armv6.c $(INCDIR)configuration.h $(INCDIR)types.h $(INCDIR)platform/platform.h 13 | $(GCC) $< -o $@ 14 | endif -------------------------------------------------------------------------------- /csud/source/platform/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)platform/ 2 | 3 | OBJECTS += $(BUILD)platform.c.o 4 | 5 | $(BUILD)platform.c.o: $(DIR)platform.c $(INCDIR)platform/platform.h 6 | $(GCC) $< -o $@ 7 | 8 | include $(DIR)arm/makefile.in -------------------------------------------------------------------------------- /csud/source/usbd/makefile.in: -------------------------------------------------------------------------------- 1 | DIR := $(DIR)usbd/ 2 | 3 | OBJECTS += $(BUILD)usbd.c.o 4 | 5 | $(BUILD)usbd.c.o: $(DIR)usbd.c $(INCDIR)hcd/hcd.h $(INCDIR)platform/platform.h $(INCDIR)usbd/descriptors.h $(INCDIR)usbd/usbd.h 6 | $(GCC) $< -o $@ 7 | -------------------------------------------------------------------------------- /include/6510.h: -------------------------------------------------------------------------------- 1 | #define FLAG_NEGATIVE 128 2 | #define FLAG_OVERFLOW 64 3 | #define FLAG_BREAK 16 4 | #define FLAG_DECIMAL 8 5 | #define FLAG_INT 4 6 | #define FLAG_ZERO 2 7 | #define FLAG_CARRY 1 8 | 9 | #define NEG_OFF 127 10 | #define OVER_OFF 191 11 | #define BRK_OFF 239 12 | #define DEC_OFF 247 13 | #define INT_OFF 251 14 | #define ZERO_OFF 253 15 | #define CRRY_OFF 254 16 | 17 | 18 | 19 | void CB64_6510(); 20 | 21 | #define setflags(r) { \ 22 | if(r&0x80)\ 23 | {\ 24 | flags|=FLAG_NEGATIVE;\ 25 | }\ 26 | else\ 27 | {\ 28 | flags&=(NEG_OFF);\ 29 | }\ 30 | if(!r)flags|=FLAG_ZERO;else flags&=(ZERO_OFF);\ 31 | } 32 | #define IndX(){\ 33 | address=(BYTE)(Peek(curr_loc+1)+x_reg);\ 34 | address=Deek(address);\ 35 | curr_loc+=2;\ 36 | } 37 | #define Zero(){\ 38 | address=(WORD)Peek(curr_loc+1);\ 39 | curr_loc+=2;\ 40 | } 41 | #define Imm(){\ 42 | address=++curr_loc;\ 43 | curr_loc++;\ 44 | } 45 | #define Abs(){\ 46 | address=(WORD)Peek(++curr_loc);\ 47 | address+=((WORD)Peek(++curr_loc)<<8);\ 48 | curr_loc++;\ 49 | } 50 | #define Ind_Y(){\ 51 | address=(WORD)Peek(curr_loc+1);\ 52 | address=Deek(address)+(WORD)y_reg;\ 53 | curr_loc+=2;\ 54 | } 55 | #define Zero_X(){\ 56 | address=(BYTE)(Peek(curr_loc+1)+x_reg);\ 57 | curr_loc+=2;\ 58 | } 59 | #define Zero_Y(){\ 60 | address=(BYTE)(Peek(curr_loc+1)+y_reg);\ 61 | curr_loc+=2;\ 62 | } 63 | #define Abs_Y(){\ 64 | address=Deek(curr_loc+1)+y_reg;\ 65 | curr_loc+=3;\ 66 | } 67 | #define Abs_X(){\ 68 | address=Deek(curr_loc+1)+x_reg;\ 69 | curr_loc+=3;\ 70 | } 71 | 72 | #define ORA(){\ 73 | a_reg|=Peek(address);\ 74 | setflags(a_reg);\ 75 | } 76 | 77 | //ASL//////////////////////// 78 | 79 | #define ASL(){\ 80 | if(Peek(address)&0x80)flags|=FLAG_CARRY;else flags&=CRRY_OFF;\ 81 | Poke(address,gen1=Peek(address)<<1);\ 82 | setflags(gen1);\ 83 | } 84 | 85 | //AND///////////////////////// 86 | #define AND(){\ 87 | a_reg&=Peek(address);\ 88 | setflags(a_reg);\ 89 | } 90 | 91 | //BIT////////////////////////// 92 | #define BIT(){\ 93 | gen1=Peek(address);\ 94 | K.B.l=a_reg&gen1;\ 95 | setflags(K.B.l);\ 96 | if(gen1&0x80)flags|=FLAG_NEGATIVE;else flags&=(NEG_OFF);\ 97 | if(gen1&0x40)flags|=FLAG_OVERFLOW;else flags&=(OVER_OFF);\ 98 | } 99 | 100 | //ROL////////////////////////// 101 | #define ROL(){\ 102 | gen1=Peek(address)<<1;\ 103 | if(flags&FLAG_CARRY)gen1|=1;\ 104 | if(Peek(address)&0x80)\ 105 | flags|=FLAG_CARRY;\ 106 | else\ 107 | flags&=CRRY_OFF;\ 108 | setflags(gen1);\ 109 | Poke(address,gen1);\ 110 | } 111 | 112 | //EOR////////////////////////// 113 | #define EOR(){\ 114 | a_reg^=Peek(address);\ 115 | setflags(a_reg);\ 116 | } 117 | 118 | //LSR//////////////////////// 119 | #define LSR(){\ 120 | gen1=Peek(address);\ 121 | if(gen1&1)flags|=FLAG_CARRY;else flags&=(CRRY_OFF);\ 122 | gen1>>=1;\ 123 | setflags(gen1);\ 124 | Poke(address,gen1);\ 125 | } 126 | 127 | //ADC//////////////////////// Thanks to M6502 128 | // NOT original M6502 code 129 | #define ADC(){ \ 130 | gen1=Peek(address); \ 131 | if(flags&FLAG_DECIMAL) \ 132 | { \ 133 | K.W=(a_reg&0xF)+(gen1&0xF)+(flags&FLAG_CARRY); \ 134 | if(K.B.l>=0xA) \ 135 | K.B.l+=0x6; \ 136 | if(K.B.l>=0x20) \ 137 | K.B.l=(K.B.l&0xF)+0x10; \ 138 | K.W+=(a_reg&0xF0)+(gen1&0xF0); \ 139 | flags&=~(FLAG_ZERO|FLAG_NEGATIVE|FLAG_OVERFLOW); \ 140 | if(K.B.l&0x80) \ 141 | flags|=FLAG_NEGATIVE; \ 142 | if((BYTE)(a_reg+gen1+(flags&FLAG_CARRY))==0) \ 143 | flags|=FLAG_ZERO; \ 144 | if(~(a_reg^gen1)&(a_reg^K.B.l)&0x80) \ 145 | flags|=FLAG_OVERFLOW; \ 146 | if(K.W>=0xA0) \ 147 | { \ 148 | flags|=FLAG_CARRY; \ 149 | K.W+=0x60; \ 150 | } \ 151 | else \ 152 | flags&=CRRY_OFF; \ 153 | a_reg=K.B.l; \ 154 | } \ 155 | else \ 156 | { \ 157 | K.W=a_reg+gen1+(flags&FLAG_CARRY); \ 158 | flags&=~(FLAG_NEGATIVE|FLAG_CARRY|FLAG_ZERO|FLAG_OVERFLOW); \ 159 | if(K.B.l&0x80) \ 160 | flags|=FLAG_NEGATIVE; \ 161 | if(!K.B.l) \ 162 | flags|=FLAG_ZERO; \ 163 | if(~(a_reg^gen1)&(a_reg^K.B.l)&0x80) \ 164 | flags|=FLAG_OVERFLOW; \ 165 | if(K.B.h) \ 166 | flags|=FLAG_CARRY; \ 167 | a_reg=K.B.l; \ 168 | } \ 169 | } 170 | 171 | 172 | //ROR////////////////////////// 173 | #define ROR(){\ 174 | gen1=Peek(address)>>1;\ 175 | if(flags&FLAG_CARRY)gen1|=0x80;\ 176 | if(Peek(address)&1)\ 177 | flags|=FLAG_CARRY;\ 178 | else\ 179 | flags&=CRRY_OFF;\ 180 | setflags(gen1);\ 181 | Poke(address,gen1);\ 182 | } 183 | 184 | //CPY//////////////////////// 185 | #define CPY(){\ 186 | gen1=Peek(address);\ 187 | if(gen1<=y_reg)flags|=FLAG_CARRY;\ 188 | else flags&=(CRRY_OFF);\ 189 | K.B.l=y_reg-gen1;\ 190 | setflags(K.B.l);\ 191 | } 192 | 193 | //CMP//////////////////////// 194 | #define CMP(){\ 195 | gen1=Peek(address);\ 196 | K.B.l=a_reg-gen1;\ 197 | setflags(K.B.l);\ 198 | if(gen1<=a_reg)flags|=FLAG_CARRY;\ 199 | else flags&=(CRRY_OFF);\ 200 | } 201 | 202 | //CPX////////////////////////// 203 | #define CPX(){\ 204 | gen1=Peek(address);\ 205 | K.B.l=x_reg-gen1;\ 206 | setflags(K.B.l);\ 207 | if(gen1<=x_reg)flags|=FLAG_CARRY;\ 208 | else flags&=(CRRY_OFF);\ 209 | } 210 | 211 | //SBC////////////////////////// 212 | // 213 | #define SBC(){\ 214 | gen1=Peek(address); \ 215 | if(flags&FLAG_DECIMAL) \ 216 | { \ 217 | K.W=(a_reg&0xF)+0x100; \ 218 | K.W-=(gen1&0xF)+(~flags&FLAG_CARRY); \ 219 | if(K.W<0x100) \ 220 | K.W-=6; \ 221 | if(K.W<0xF0) \ 222 | K.W+=0x10; \ 223 | K.W+=a_reg&0xF0; \ 224 | K.W-=gen1&0xF0; \ 225 | flags&=~(FLAG_ZERO|FLAG_NEGATIVE|FLAG_OVERFLOW); \ 226 | if(K.B.l&0x80) \ 227 | flags|=FLAG_NEGATIVE; \ 228 | if((BYTE)(a_reg-gen1-(~flags&FLAG_CARRY))==0) \ 229 | flags|=FLAG_ZERO; \ 230 | if(~(K.B.l^gen1)&(a_reg^gen1)&0x80) \ 231 | flags|=FLAG_OVERFLOW; \ 232 | if(K.B.h) \ 233 | flags|=FLAG_CARRY; \ 234 | else \ 235 | { \ 236 | K.B.l-=0x60; \ 237 | flags&=CRRY_OFF; \ 238 | } \ 239 | a_reg=K.B.l; \ 240 | } \ 241 | else \ 242 | { \ 243 | K.B.l=a_reg; \ 244 | K.B.h=1; \ 245 | K.W-=gen1+(~flags&FLAG_CARRY); \ 246 | flags&=~(FLAG_NEGATIVE|FLAG_CARRY|FLAG_ZERO|FLAG_OVERFLOW); \ 247 | if(K.B.l&0x80) \ 248 | flags|=FLAG_NEGATIVE; \ 249 | if(!K.B.l) \ 250 | flags|=FLAG_ZERO; \ 251 | if(~(K.B.l^gen1)&(a_reg^gen1)&0x80) \ 252 | flags|=FLAG_OVERFLOW; \ 253 | if(K.B.h) \ 254 | flags|=FLAG_CARRY; \ 255 | a_reg=K.B.l; \ 256 | } \ 257 | } 258 | 259 | 260 | // UNDOC'D INSTRUCTIONS /////////////////// 261 | #define ASO(){\ 262 | ASL();\ 263 | ORA();\ 264 | } 265 | #define RLA(){\ 266 | ROL();\ 267 | AND();\ 268 | } 269 | #define LSE(){\ 270 | LSR();\ 271 | EOR();\ 272 | } 273 | #define RRA(){\ 274 | ROR();\ 275 | ADC();\ 276 | } 277 | #define AXS(){\ 278 | Poke(address,a_reg&x_reg);\ 279 | } 280 | #define LAX(){\ 281 | a_reg=x_reg=Peek(address);\ 282 | setflags(a_reg);\ 283 | } 284 | #define DCM(){\ 285 | Poke(address,gen1=Peek(address)-1);\ 286 | setflags(gen1);\ 287 | CMP();\ 288 | } 289 | #define INS(){\ 290 | Poke(address,Peek(address)+1);\ 291 | SBC();\ 292 | } 293 | #define ALR(){\ 294 | AND();\ 295 | if(a_reg&1)flags|=FLAG_CARRY;else flags&=(CRRY_OFF);\ 296 | a_reg>>=1;\ 297 | setflags(a_reg);\ 298 | } 299 | #define ARR(){\ 300 | AND();\ 301 | gen1=a_reg>>1;\ 302 | if(flags&FLAG_CARRY)gen1|=0x80;\ 303 | if(a_reg&1)\ 304 | flags|=FLAG_CARRY;\ 305 | else\ 306 | flags&=CRRY_OFF;\ 307 | setflags(gen1);\ 308 | a_reg=gen1;\ 309 | } 310 | #define OAL(){\ 311 | a_reg|=0xEE;\ 312 | setflags(a_reg);\ 313 | AND();\ 314 | x_reg=a_reg;\ 315 | setflags(x_reg);\ 316 | } 317 | #define SAX(){\ 318 | gen1=Peek(address);\ 319 | x_reg&=a_reg;\ 320 | if(flags&FLAG_DECIMAL) \ 321 | { \ 322 | K.B.l=(x_reg&0x0F)-(gen1&0x0F)-(~flags&FLAG_CARRY); \ 323 | if(K.B.l&0x10) K.B.l-=6; \ 324 | K.B.h=(x_reg>>4)-(gen1>>4)-(K.B.l&0x10); \ 325 | if(K.B.h&0x10) K.B.h-=6; \ 326 | x_reg=(K.B.l&0x0F)|(K.B.h<<4); \ 327 | if(K.B.h>15) \ 328 | flags|=FLAG_CARRY; \ 329 | else \ 330 | flags&=CRRY_OFF; \ 331 | } \ 332 | else \ 333 | { \ 334 | K.W=x_reg-gen1-(~flags&FLAG_CARRY); \ 335 | flags&=~(FLAG_NEGATIVE|FLAG_OVERFLOW|FLAG_ZERO|FLAG_CARRY); \ 336 | flags|=((x_reg^gen1)&(x_reg^K.B.l)&0x80? FLAG_OVERFLOW:0)| \ 337 | (K.B.h? 0:FLAG_CARRY)|(K.B.l?0:FLAG_ZERO)|(K.B.l&0x80?FLAG_NEGATIVE:0); \ 338 | x_reg=K.B.l; \ 339 | }\ 340 | } 341 | -------------------------------------------------------------------------------- /include/C64.h: -------------------------------------------------------------------------------- 1 | #ifndef _CB64W_H 2 | #define _CB64W_H 3 | 4 | typedef short SHORT; 5 | typedef unsigned long DWORD; 6 | typedef int BOOL; 7 | typedef unsigned char BYTE; 8 | typedef unsigned short WORD; 9 | 10 | #define TRUE 1 11 | #define FALSE 0 12 | #define NULL 0 13 | 14 | // --------------------------------------------------------------------------- 15 | // Cb64 Defines 16 | 17 | #define VERMAJ 0 18 | #define VERMIN 9 19 | #define VERMINTWO 8 20 | 21 | #define DEFAULTEMULATEDJOYSTICK 1 22 | #define DEFAULTGAMMA 1.0 23 | #define DEFAULTSKIPRATE 1 24 | #define DEFAULTGRAYSCALEON 0 25 | #define DEFAULTILLEGALOPCODE 0 26 | 27 | #define ATNOR 1 28 | #define CLKOR 2 29 | #define INITOR 4 30 | #define DATAOR 8 31 | #define ATNAND 254 32 | #define CLKAND 253 33 | #define INITAND 251 34 | #define DATAAND 247 35 | 36 | typedef union 37 | { 38 | struct { BYTE l,h; } B; 39 | WORD W; 40 | } CB64_pair; 41 | 42 | typedef struct 43 | { 44 | BYTE C64CART[16]; 45 | DWORD headerlen; 46 | WORD version; 47 | WORD hardtype; 48 | BYTE exromline; 49 | BYTE gameline; 50 | BYTE dummy[6]; 51 | BYTE name[20]; 52 | BYTE chip[4]; 53 | DWORD packlen; 54 | WORD chiptype; 55 | WORD bank; 56 | WORD address; 57 | WORD length; 58 | } CARTRIDGE; 59 | 60 | // --------------------------------------------------------------------------- 61 | // Globals 62 | 63 | extern BOOL g_fPAL; 64 | 65 | extern BYTE *BasicPointer; 66 | extern BYTE *KernalPointer; 67 | extern BYTE *RAMPointer; 68 | extern BYTE *CharPointer; 69 | extern BYTE *ColorPointer; 70 | extern BYTE *Virtualscreen; 71 | 72 | extern int done,reset,percent,skipper; 73 | extern int cycles,cyc_orig,cyc_last; 74 | extern char illopc; 75 | extern char NMI,IRQ; 76 | 77 | extern BYTE SIDRegs[0x1D]; 78 | 79 | extern int Cartflg; 80 | extern CARTRIDGE cart; 81 | 82 | // --------------------------------------------------------------------------- 83 | // Functions 84 | extern void CB64_ClearMem(); 85 | extern void CB64_MainLoop(); 86 | extern void CB64_Draw(); 87 | extern BYTE Peek(WORD address); 88 | extern WORD Deek(WORD address); 89 | extern void Poke(WORD address, BYTE value); 90 | 91 | #endif -------------------------------------------------------------------------------- /include/C64Data.h: -------------------------------------------------------------------------------- 1 | #ifndef _TABLES_H 2 | #define _TABLES_H 3 | 4 | extern BYTE key_table[256][2]; 5 | 6 | extern BYTE ORIGINAL64B[8193]; 7 | extern BYTE ORIGINAL64C[4097]; 8 | extern BYTE ORIGINAL64K[8193]; 9 | 10 | extern char * opcodes[256]; 11 | extern DWORD cbmcolor[16]; 12 | #endif -------------------------------------------------------------------------------- /include/font.h: -------------------------------------------------------------------------------- 1 | //{ 16,16,16,16,22,1,2,4,7 }, // 1/2 2 | //{ 6,9,8,28,8,8,31,0,0 }, // £ 3 | // { 0,4,8,31,8,4,0,0,0 }, // left arrow [ in ASCII 4 | // { 0,4,2,31,2,4,0,0,0 }, // right arrow ] in ASCII 5 | 6 | static const unsigned char teletext[][8] = { 7 | { 0,0,0,0,0,0,0,0}, // space 8 | {24,24,24,24,0,0,24,0}, // ! 9 | {102,102,102,0,0,0,0,0}, // " 10 | {102,102,255,102,255,102,102,0}, // # 11 | {24,62,64,60,2,124,24,0}, // $ 12 | {98,98,12,24,48,102,70,0}, // % 13 | {120,204,120,112,206,204,126,0}, // & 14 | {24,24,24,0,0,0,0,0}, // ' 15 | {24,48,96,96,96,48,24,0}, // ( 16 | {24,12,6,6,6,12,24,0}, // ) 17 | {0,102,60,255,60,60,102,0}, // * 18 | {0,24,24,126,24,24,0,0}, // + 19 | {0,0,0,0,24,24,48,0}, // , 20 | {0,0,0,126,0,0,0,0}, // - 21 | {0,0,0,0,24,24,0,0}, // . 22 | {2,6,12,24,48,96,64,0}, // / 23 | {60,102,110,118,102,102,60,0}, // 0 24 | {24,24,56,24,24,24,126,0}, // 1 25 | {60,102,6,12,48,96,126,0}, // 2 26 | {60,102,6,28,6,102,60,0}, // 3 27 | {12,28,60,204,254,12,12,0}, // 4 28 | {126,96,124,6,6,102,60,0}, // 5 29 | {60,102,96,124,102,102,60,0}, // 6 30 | {126,102,12,24,24,24,24,0}, // 7 31 | {60,102,102,60,102,102,60,0}, // 8 32 | {60,102,102,62,6,102,60,0}, // 9 33 | {0,24,0,0,24,0,0,0}, // : 34 | {0,24,0,0,24,24,48,0}, // ; 35 | {14,24,48,96,48,24,14,0}, // < 36 | {0,0,0,124,0,124,0,0}, // = 37 | {112,24,12,6,12,24,112,0}, // > 38 | {60,102,6,24,24,0,24,0}, // ? 39 | {60,102,110,110,96,98,60,0}, // @ 40 | {24,60,102,126,102,102,102,0}, // A 41 | {124,102,102,124,102,102,124,0}, // B 42 | {60,102,96,96,96,102,60,0}, // C 43 | {120,108,102,102,102,108,120,0}, // D 44 | {126,96,96,124,96,96,126,0}, // E 45 | {126,96,96,124,96,96,96,0}, // F 46 | {60,102,96,110,102,102,60,0}, // G 47 | {102,102,102,126,102,102,102,0}, // H 48 | {60,24,24,24,24,24,60,0}, // I 49 | {30,12,12,12,12,108,56,0}, // J 50 | {102,108,120,116,120,108,102,0}, // K 51 | {96,96,96,96,96,96,124,0}, // L 52 | {198,238,254,214,198,198,198,0}, // M 53 | {102,118,126,126,110,102,102,0}, // N 54 | {60,102,102,102,102,102,60,0}, // O 55 | {124,102,102,124,96,96,96,0}, // P 56 | {60,102,102,102,102,60,14,0}, // Q 57 | {124,102,102,124,120,108,102,0}, // R 58 | {60,102,96,60,6,102,60,0}, // S 59 | {126,24,24,24,24,24,24,0}, // T 60 | {102,102,102,102,102,102,60,0}, // U 61 | {102,102,102,102,102,60,24,0}, // V 62 | {198,198,198,214,254,238,198,0}, // W 63 | {102,102,60,24,60,102,102,0}, // X 64 | {102,102,102,60,24,24,24,0}, // Y 65 | {126,6,12,24,48,32,126,0}, // Z 66 | {120,96,96,96,96,96,120,0}, // [ 67 | {64,96,48,24,12,6,2,0}, // Backslash 68 | {60,12,12,12,12,12,60,0},// ] 69 | {24,60,102,0,0,0,0,0}, // up arrow ^ in ASCII 70 | {0,0,0,0,0,0,255,0}, // # _ in ASCII 71 | {96,96,48,0,0,0,0,0}, // dash ` in ASCII 72 | {0,0,60,6,62,102,62,0}, // a 73 | {0,96,96,124,102,102,124,0}, // b 74 | {0,0,60,96,96,96,60,0}, // c 75 | {0,12,12,60,108,108,60,0}, // d 76 | {0,0,60,102,126,96,60,0}, // e 77 | {0,28,48,124,48,48,48,0}, // f 78 | {0,0,62,102,102,62,6,120}, // g 79 | {0,96,96,120,108,108,108,0}, // h 80 | {0,24,0,56,24,24,28,0}, // i 81 | {0,12,0,12,12,12,12,56}, // j 82 | {0,96,96,108,120,120,108,0}, // k 83 | {0,56,24,24,24,24,60,0}, // l 84 | {0,0,102,127,127,107,99,0}, // m 85 | {0,0,124,126,102,102,102,0}, // n 86 | {0,0,60,102,102,102,60,0}, // o 87 | {0,0,124,102,102,124,96,96}, // p 88 | {0,0,62,102,102,62,6,6}, // q 89 | {0,0,124,102,96,96,96,0}, // r 90 | {0,0,62,96,60,6,124,0}, // s 91 | {0,24,126,24,24,24,14,0}, // t 92 | {0,0,102,102,102,102,62,0}, // u 93 | {0,0,102,102,102,60,24,0}, // v 94 | {0,0,99,107,127,62,20,0}, // w 95 | {0,0,102,60,24,60,102,0}, // x 96 | {0,0,102,102,102,62,12,120}, // y 97 | {0,0,126,12,24,48,126,0}, // z 98 | {0,56,48,112,192,112,48,56}, // 1/4 { in ASCII 99 | {24,24,24,24,24,24,24,24}, // || | in ASCII 100 | {0,56,24,28,6,28,24,56}, // 3/4 } in ASCII 101 | {0,0,50,126,76,0,0,0}, // divide sign ~ in ASCII 102 | {255,255,255,255,255,255,255,255} // character-sized block 103 | // not defined in ASCII 104 | }; -------------------------------------------------------------------------------- /include/framebuffer.h: -------------------------------------------------------------------------------- 1 | #define SCREEN_WIDTH 360 //320 2 | #define SCREEN_HEIGHT 240 //200 3 | #define CSIZE unsigned short int 4 | 5 | int GetScreenSizeFromTags(); 6 | int SetupScreen(); 7 | int GetPitch(); 8 | int InitializeFramebuffer(); 9 | void DisplayVirtualFramebuffer(int bufferId); 10 | unsigned int GetFramebufferAddress(); 11 | 12 | -------------------------------------------------------------------------------- /include/gpio.h: -------------------------------------------------------------------------------- 1 | void LedInit(void); 2 | void LedOn(void); 3 | void LedOff(void); 4 | -------------------------------------------------------------------------------- /include/graphics.h: -------------------------------------------------------------------------------- 1 | #include "font.h" 2 | #include "math.h" 3 | 4 | #define CHAR_HEIGHT 9 5 | #define CHAR_WIDTH 9 6 | #define CSIZE unsigned short int 7 | 8 | extern unsigned int gFbAddr; 9 | extern unsigned int gPitch; 10 | extern unsigned int gScreenWidth, gScreenHeight; 11 | 12 | 13 | void DrawLine(int x0, int y0, int x1, int y1, CSIZE color); 14 | void DrawRectangle(int x0, int y0, int x1, int y1, CSIZE color); 15 | void DrawCircle(int x0, int y0, int radius, CSIZE color); 16 | void DrawPixel(unsigned int x, unsigned int y, CSIZE color); 17 | void DrawCharacterAt(unsigned int c, unsigned int x, unsigned int y, CSIZE color); 18 | void DrawFilledRectangle(int x0, int y0, int x1, int y1, CSIZE color); 19 | void PutsAt(const char *s, unsigned int x, unsigned int y, CSIZE color); 20 | void SetVirtualFrameBuffer(int bufferId); 21 | void DisplayVirtualFramebuffer(int bufferId); -------------------------------------------------------------------------------- /include/keyboard.h: -------------------------------------------------------------------------------- 1 | #ifndef PIOS_KEYBOARD_C 2 | #define PIOS_KEYBOARD_C 3 | #include "types.h" 4 | 5 | typedef enum 6 | { 7 | VK_A, 8 | VK_B, 9 | VK_C, 10 | VK_D, 11 | VK_E, 12 | VK_F, 13 | VK_G, 14 | VK_H, 15 | VK_I, 16 | VK_J, 17 | VK_K, // 10 18 | VK_L, 19 | VK_M, 20 | VK_N, 21 | VK_O, 22 | VK_P, 23 | VK_Q, 24 | VK_R, 25 | VK_S, 26 | VK_T, 27 | VK_U, // 20 28 | VK_V, 29 | VK_W, 30 | VK_X, 31 | VK_Y, 32 | VK_Z, 33 | VK_0, 34 | VK_1, 35 | VK_2, 36 | VK_3, 37 | VK_4, // 30 38 | VK_5, 39 | VK_6, 40 | VK_7, 41 | VK_8, 42 | VK_9, 43 | VK_ENTER, 44 | VK_ESC, 45 | VK_BSP, 46 | VK_TAB, 47 | VK_SPACE, // 40 48 | VK_MINUS, 49 | VK_EQUALS, 50 | VK_SBLEFT, 51 | VK_SBRIGHT, 52 | VK_BACKSLASH, 53 | VK_HASH, 54 | VK_SEMICOLON, 55 | VL_APOSTROPHE, 56 | VK_GRAVE, 57 | VK_COMMA, // 50 58 | VK_FULLSTOP, 59 | VK_FORWARDSLASH, 60 | VK_CAPS, 61 | VK_F1, 62 | VK_F2, 63 | VK_F3, 64 | VK_F4, 65 | VK_F5, 66 | VK_F6, 67 | VK_F7, // 60 68 | VK_F8, 69 | VK_F9, 70 | VK_F10, 71 | VK_F11, 72 | VK_F12, 73 | VK_PRTSCN, 74 | VK_SCL, 75 | VK_BREAK, 76 | VK_INSERT, 77 | VK_HOME, // 70 78 | VK_PGUP, // 71 79 | VK_DELETE, // 72 80 | VK_END, //73 81 | VK_PG_DN, // 74 82 | VK_RIGHT, // 75 83 | VK_LEFT, // 76 84 | VK_DOWN, // 77 85 | VK_UP, // 78 86 | VK_NUMLOCK, // 79 87 | VK_NUM_DIV, // 80 88 | VK_NUM_MUL, 89 | VK_NUM_SUB, 90 | VK_NUM_ADD, 91 | VK_NUM_ENTER, // 83 92 | VK_NUM1, 93 | VK_NUM2, // 85 94 | VK_NUM3, 95 | VK_NUM4, // 87 96 | VK_NUM5, 97 | VK_NUM6, // 90 98 | VK_NUM7, 99 | VK_NUM8, 100 | VK_NUM9, 101 | VK_NUM0, 102 | VK_NUM_DEL, 103 | VK_BACKSLASH2, 104 | VK_RMENU 105 | } virtualkey; 106 | 107 | unsigned int KeyboardInitialise(void); 108 | void KeyboardUpdate(void); 109 | unsigned short KeyboardGetChar(void); 110 | bool EnsureKeyboard(void); 111 | virtualkey ScanToVirtual(unsigned int scanCode); 112 | unsigned char VirtualToAsci(virtualkey vk, bool shiftDown); 113 | char* GetKeyName(char* buf, unsigned int bufLen, virtualkey vk); 114 | bool KeyboardShiftDown(void); 115 | bool KeyboardCtrlDown(void); 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /include/mailbox.h: -------------------------------------------------------------------------------- 1 | void Mailbox_Write(unsigned int channel, unsigned int data); 2 | unsigned int Mailbox_Read(unsigned int channel); -------------------------------------------------------------------------------- /include/math.h: -------------------------------------------------------------------------------- 1 | extern int abs(int x); -------------------------------------------------------------------------------- /include/mmio.h: -------------------------------------------------------------------------------- 1 | // 2 | // Utility functions for interacting with the memory mapped IO peripherals 3 | // 4 | 5 | // C Function for the assembly instruction 6 | // str val, [addr] 7 | // which stores the value of val in addr 8 | static inline void mmio_write(unsigned int addr, unsigned int data) 9 | { 10 | asm volatile("str %[data], [%[address]]" 11 | : : [address]"r"((unsigned int*)addr), [data]"r"(data)); 12 | } 13 | 14 | // C Function for the assembly instruction 15 | // ldr val, [addr] 16 | // Which loads the value at addr into val 17 | static inline void unsigned int mmio_read(unsigned int addr) 18 | { 19 | unsigned int data; 20 | asm volatile("ldr %[data], [%[addr]]" 21 | : [data]"=r"(data) : [addr]"r"((unsigned int*)addr)); 22 | 23 | return data; 24 | } -------------------------------------------------------------------------------- /include/stat.h: -------------------------------------------------------------------------------- 1 | #ifndef STAT_H_INCLUDED 2 | #define STAT_H_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | #ifdef _WIN32 8 | #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 9 | #define stat _stat 10 | #else 11 | #include 12 | #endif 13 | 14 | #endif /* STAT_H_INCLUDED */ 15 | -------------------------------------------------------------------------------- /include/stdio.h: -------------------------------------------------------------------------------- 1 | 2 | void stdio_init(void); 3 | void cin(char*, unsigned int); 4 | -------------------------------------------------------------------------------- /include/string.h: -------------------------------------------------------------------------------- 1 | /* String.h */ 2 | #ifndef STRING_H 3 | #define STRING_H 4 | 5 | #include // Needed for varying argument length 6 | 7 | typedef unsigned char BYTE; 8 | typedef unsigned int size_t; 9 | 10 | int strlen(char* str); 11 | char* strcpy(const char* src, char* dst); 12 | void itoa(int number, char* buf); 13 | void printf(char* text, ...); 14 | void *ucmemset(unsigned char *s, int c, size_t n); 15 | void *imemset(int *s, int c, size_t n); 16 | void *cmemset(char *s, int c, size_t n); 17 | void *memcpy(BYTE *dest, const BYTE *src, size_t n); 18 | 19 | #endif // STRINGUTIL_H 20 | 21 | 22 | -------------------------------------------------------------------------------- /include/terminal.h: -------------------------------------------------------------------------------- 1 | void print(char* string, unsigned int length); 2 | int terminal_init(void); 3 | void terminal_clear(void); 4 | void terminal_back(void); 5 | -------------------------------------------------------------------------------- /include/timer.h: -------------------------------------------------------------------------------- 1 | void wait(unsigned int milliSeconds); 2 | -------------------------------------------------------------------------------- /libcsud.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlar54/Commodore-Pi/41aa2a1e4a802a9f9dfca3e2a913926cdb0c1870/libcsud.a -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | TOOL = arm-none-eabi 2 | CFLAGS = -O3 -nostdlib -nostartfiles -ffreestanding --no-common -Wno-write-strings 3 | LINKER_FLAGS = --no-wchar-size-warning --no-undefined 4 | 5 | # Make sure gcc searches the include folder 6 | C_INCLUDE_PATH=include;csud\include 7 | export C_INCLUDE_PATH 8 | 9 | LIBRARIES = csud 10 | BUILD_DIR = bin 11 | SOURCE_DIR = source 12 | 13 | CSOURCE := $(wildcard $(SOURCE_DIR)/*.c) 14 | ASOURCE := $(wildcard $(SOURCE_DIR)/*.s) 15 | 16 | _COBJECT := $(patsubst %.c,%.o, $(CSOURCE)) 17 | _AOBJECT := $(patsubst %.s,%.o, $(ASOURCE)) 18 | AOBJECT = $(addprefix $(BUILD_DIR)/, $(notdir $(_AOBJECT))) 19 | COBJECT = $(addprefix $(BUILD_DIR)/, $(notdir $(_COBJECT))) 20 | 21 | all: kernel 22 | 23 | # Create the final binary 24 | kernel: theelf 25 | $(TOOL)-objcopy $(BUILD_DIR)/kernel.elf -O binary $(BUILD_DIR)/kernel.img 26 | 27 | # Link all of the objects 28 | theelf: $(AOBJECT) $(COBJECT) libcsud.a 29 | $(TOOL)-ld $(LINKER_FLAGS) $(AOBJECT) $(COBJECT) -L. -l $(LIBRARIES) -Map $(BUILD_DIR)/kernel.map -T memorymap -o $(BUILD_DIR)/kernel.elf 30 | 31 | #build c files 32 | $(BUILD_DIR)/%.o: $(SOURCE_DIR)/%.c 33 | $(TOOL)-gcc -c $< -o $@ $(CFLAGS) 34 | 35 | #build s files (Assembly) 36 | $(BUILD_DIR)/%.o: $(SOURCE_DIR)/%.s 37 | $(TOOL)-as $< -o $@ 38 | 39 | clean: 40 | rm $(BUILD_DIR)/*.o 41 | rm $(BUILD_DIR)/*.map 42 | rm $(BUILD_DIR)/*.elf 43 | rm $(BUILD_DIR)/*.img 44 | -------------------------------------------------------------------------------- /memorymap: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | /* Hardcoded 1 MB kernel size */ 4 | ram : ORIGIN = 0x8000, LENGTH = 1M 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | . = ALIGN(4096); /* align to page size */ 11 | 12 | _bss_start = .; 13 | 14 | .bss : { *(.bss*) } > ram 15 | . = ALIGN(4096); /* align to page size */ 16 | 17 | _bss_end = .; 18 | } -------------------------------------------------------------------------------- /source/C64Data.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlar54/Commodore-Pi/41aa2a1e4a802a9f9dfca3e2a913926cdb0c1870/source/C64Data.c -------------------------------------------------------------------------------- /source/framebuffer.c: -------------------------------------------------------------------------------- 1 | #include "framebuffer.h" 2 | #include "mailbox.h" 3 | 4 | unsigned int gFbAddr; 5 | unsigned int gPitch; 6 | unsigned int gScreenWidth, gScreenHeight; 7 | 8 | unsigned int GetFramebufferAddress() 9 | { 10 | return gFbAddr; 11 | } 12 | 13 | 14 | int InitializeFramebuffer() 15 | { 16 | unsigned int result = 0; 17 | 18 | if((result = GetScreenSizeFromTags()) > 0) 19 | { 20 | return result; 21 | } 22 | 23 | if((result = SetupScreen()) > 0) 24 | { 25 | return result; 26 | } 27 | 28 | if((result = GetPitch()) > 0) 29 | { 30 | return result; 31 | } 32 | 33 | return result; 34 | } 35 | 36 | // 0: Success. 1: Invalid response to property request, 2: Invalid screen size returned 37 | int GetScreenSizeFromTags() 38 | { 39 | volatile unsigned int mailbuffer[256] __attribute__ ((aligned (16))); 40 | unsigned int mailbufferAddr = (unsigned int)mailbuffer; 41 | 42 | mailbuffer[0] = 8 * 4; // Total size 43 | mailbuffer[1] = 0; // Request 44 | mailbuffer[2] = 0x40003; // Display size 45 | mailbuffer[3] = 8; // Buffer size 46 | mailbuffer[4] = 0; // Request size 47 | mailbuffer[5] = 0; // Space for horizontal resolution 48 | mailbuffer[6] = 0; // Space for vertical resolution 49 | mailbuffer[7] = 0; // End tag 50 | 51 | Mailbox_Write(8, mailbufferAddr); 52 | 53 | Mailbox_Read(8); 54 | 55 | if(mailbuffer[1] != 0x80000000) 56 | return 1; 57 | 58 | gScreenWidth = mailbuffer[5]; 59 | gScreenHeight = mailbuffer[6]; 60 | 61 | if(gScreenWidth == 0 || gScreenHeight == 0) 62 | return 2; 63 | 64 | return 0; 65 | } 66 | 67 | // 0: Success, 1: Invalid response to Setup screen request, 2: Framebuffer setup failed, Invalid tags, 3: Invalid tag response, 4: Invalid tag data 68 | int SetupScreen() 69 | { 70 | volatile unsigned int mailbuffer[256] __attribute__ ((aligned (16))); 71 | unsigned int mailbufferAddr = (unsigned int)mailbuffer; 72 | 73 | mailbuffer[0] = 8 * 4; // NOT SURE IF WE NEED THIS 74 | 75 | unsigned int c = 1; 76 | mailbuffer[c++] = 0; // This is a request 77 | mailbuffer[c++] = 0x00048003; // Tag id (set physical size) 78 | mailbuffer[c++] = 8; // Value buffer size (bytes) 79 | mailbuffer[c++] = 8; // Req. + value length (bytes) 80 | mailbuffer[c++] = SCREEN_WIDTH; // Horizontal resolution 81 | mailbuffer[c++] = SCREEN_HEIGHT; // Vertical resolution 82 | 83 | mailbuffer[c++] = 0x00048004; // Tag id (set virtual size) 84 | mailbuffer[c++] = 8; // Value buffer size (bytes) 85 | mailbuffer[c++] = 8; // Req. + value length (bytes) 86 | mailbuffer[c++] = SCREEN_WIDTH; // Horizontal resolution 87 | mailbuffer[c++] = SCREEN_HEIGHT*2; // Vertical resolution - x2 allows for a second virtual framebuffer 88 | 89 | mailbuffer[c++] = 0x00048005; // Tag id (set depth) 90 | mailbuffer[c++] = 4; // Value buffer size (bytes) 91 | mailbuffer[c++] = 4; // Req. + value length (bytes) 92 | mailbuffer[c++] = 16; // 16 bpp 93 | 94 | mailbuffer[c++] = 0x00040001; // Tag id (allocate framebuffer) 95 | mailbuffer[c++] = 8; // Value buffer size (bytes) 96 | mailbuffer[c++] = 4; // Req. + value length (bytes) 97 | mailbuffer[c++] = 16; // Alignment = 16 98 | mailbuffer[c++] = 0; // Space for response 99 | 100 | mailbuffer[c++] = 0; // Terminating tag 101 | 102 | mailbuffer[0] = c*4; // Buffer size 103 | 104 | Mailbox_Write(8, mailbufferAddr); 105 | 106 | Mailbox_Read(8); 107 | 108 | if(mailbuffer[1] != 0x80000000) 109 | return 1; 110 | 111 | unsigned int temp; 112 | unsigned int count = 2; // Read the first tag 113 | while((temp = mailbuffer[count])) 114 | { 115 | if(temp == 0x40001) 116 | break; 117 | 118 | count += 3 + (mailbuffer[count + 1] >> 2); 119 | if(count > c) 120 | return 2; // Framebuffer setup failed, Invalid tags. 121 | } 122 | 123 | // 8 bytes, plus the MSB is set to indicate that this is a response 124 | if(mailbuffer[count + 2] != 0x80000008) 125 | return 3; // Invalid tag response 126 | 127 | gFbAddr = mailbuffer[count + 3]; 128 | unsigned int screenSize = mailbuffer[count + 4]; 129 | 130 | if(gFbAddr == 0 || screenSize == 0) 131 | return 4; 132 | 133 | return 0; 134 | } 135 | 136 | // 0: Success, 1: Invalid pitch response, 2: Invalid pitch response 137 | int GetPitch() 138 | { 139 | volatile unsigned int mailbuffer[256] __attribute__ ((aligned (16))); 140 | unsigned int mailbufferAddr = (unsigned int)mailbuffer; 141 | 142 | // All super so far - Now time to get the pitch (bytes per line) 143 | mailbuffer[0] = 7 * 4; // Total Size 144 | mailbuffer[1] = 0; // This is a request 145 | mailbuffer[2] = 0x40008; // Display size 146 | mailbuffer[3] = 4; // Buffer size 147 | mailbuffer[4] = 0; // Request size 148 | mailbuffer[5] = 0; // REPONSE - Pitch 149 | mailbuffer[6] = 0; // end tag 150 | 151 | Mailbox_Write(8, mailbufferAddr); 152 | 153 | Mailbox_Read(8); 154 | 155 | // 4 bytes, plus the MSB set to indicate a response 156 | if(mailbuffer[4] != 0x80000004) 157 | return 1; // Invalid pitch response 158 | 159 | unsigned int pitch = mailbuffer[5]; 160 | if(pitch == 0) 161 | return 2; // Invalid pitch response 162 | 163 | gPitch = pitch; 164 | 165 | return 0; 166 | } 167 | 168 | void DoFlipy( void ) 169 | { 170 | // Copy all the things from one buffer to the other. 171 | unsigned int ctr = gScreenWidth * gScreenHeight; 172 | 173 | unsigned short int* onscreenBuffer = (unsigned short int*)gFbAddr; 174 | unsigned short int* offscreenBuffer = (unsigned short int*)(gFbAddr + (ctr * sizeof(unsigned short int) ) - gScreenWidth); 175 | 176 | while(ctr--) 177 | *onscreenBuffer++ = *offscreenBuffer++; 178 | } 179 | void DoFlipx( void ) 180 | { 181 | int x, y; 182 | unsigned short int* a; 183 | unsigned short int* b; 184 | 185 | for ( y = 0; y < gScreenHeight; y++ ) { 186 | for ( x = 0; x < gScreenWidth; x++ ) { 187 | 188 | // Do a double array copy. 189 | a = (unsigned short int*)( gFbAddr + ( y * gPitch ) + (x * 2) ); 190 | b = (unsigned short int*)( gFbAddr+ ( ( y + gScreenHeight ) * gPitch ) + (x * 2) ); 191 | 192 | *a = *b; 193 | } 194 | } 195 | } 196 | 197 | void DisplayVirtualFramebuffer(int bufferId) 198 | { 199 | volatile unsigned int mailbuffer[256] __attribute__ ((aligned (16))); 200 | unsigned int mailbufferAddr = (unsigned int)mailbuffer; 201 | 202 | mailbuffer[0] = 8 * 4; // Total size 203 | mailbuffer[1] = 0; // Request 204 | mailbuffer[2] = 0x48009; // Display size 205 | mailbuffer[3] = 8; // Buffer size 206 | mailbuffer[4] = 8; // Request size 207 | mailbuffer[5] = SCREEN_WIDTH; // Space for horizontal resolution 208 | mailbuffer[6] = SCREEN_HEIGHT * bufferId; // Space for vertical resolution 209 | mailbuffer[7] = 0; // End tag 210 | 211 | Mailbox_Write(8, mailbufferAddr); 212 | 213 | Mailbox_Read(8); 214 | 215 | // We should do some kind of error handling 216 | if(mailbuffer[1] != 0x80000000) 217 | return; 218 | 219 | return; 220 | } -------------------------------------------------------------------------------- /source/gpio.c: -------------------------------------------------------------------------------- 1 | extern unsigned int GET32(unsigned int); 2 | extern void PUT32(unsigned int, unsigned int); 3 | 4 | #define GPFSEL1 0x20200004 5 | #define GPSET0 0x2020001C 6 | #define GPCLR0 0x20200028 7 | 8 | void LedInit() 9 | { 10 | // Enable output on the LED 11 | unsigned int ra = GET32(GPFSEL1); 12 | 13 | ra &= ~(7 << 18); 14 | ra |= 1 << 18; 15 | 16 | PUT32(GPFSEL1, ra); 17 | } 18 | 19 | void LedOn() 20 | { 21 | PUT32(GPCLR0, 1 << 16); // On 22 | } 23 | 24 | void LedOff() 25 | { 26 | PUT32(GPSET0, 1 << 16); // Off 27 | } 28 | -------------------------------------------------------------------------------- /source/graphics.c: -------------------------------------------------------------------------------- 1 | #include "graphics.h" 2 | 3 | unsigned int gFrameBufferId=1; // 1 or 2 4 | 5 | void SetVirtualFrameBuffer(int bufferId) 6 | { 7 | gFrameBufferId = bufferId; 8 | } 9 | 10 | inline void DrawPixel(unsigned int x, unsigned int y, CSIZE color) 11 | { 12 | if(gFrameBufferId == 1) 13 | { 14 | CSIZE* ptr = (CSIZE*)(gFbAddr + (y * gPitch) + (x * 2)); 15 | *ptr = color; 16 | } 17 | else 18 | { 19 | CSIZE* ptr = (CSIZE*)(gFbAddr + ( (y+gScreenHeight) * gPitch ) + (x * 2)); 20 | *ptr = color; 21 | } 22 | } 23 | 24 | void DrawLine(int x0, int y0, int x1, int y1, CSIZE color) 25 | { 26 | 27 | int dx = abs(x1-x0), sx = x0dy ? dx : -dy)/2, e2; 30 | 31 | for(;;){ 32 | DrawPixel(x0,y0, color); 33 | if (x0==x1 && y0==y1) break; 34 | e2 = err; 35 | if (e2 >-dx) { err -= dy; x0 += sx; } 36 | if (e2 < dy) { err += dx; y0 += sy; } 37 | } 38 | } 39 | 40 | void DrawRectangle(int x0, int y0, int x1, int y1, CSIZE color) 41 | { 42 | DrawLine(x0, y0, x1, y0, color); 43 | DrawLine(x0, y0, x0, y1, color); 44 | DrawLine(x0, y1, x1, y1, color); 45 | DrawLine(x1, y1, x1, y0, color); 46 | } 47 | 48 | void DrawFilledRectangle(int x0, int y0, int x1, int y1, CSIZE color) 49 | { 50 | while(x0 <= x1 && y0 <= y1) 51 | DrawRectangle(x0++, y0++, x1, y1, color); 52 | } 53 | 54 | void DrawCircle(int x0, int y0, int radius, CSIZE color) 55 | { 56 | int x = radius, y = 0; 57 | int radiusError = 1-x; 58 | 59 | while(x >= y) 60 | { 61 | DrawPixel(x + x0, y + y0, color); 62 | DrawPixel(y + x0, x + y0, color); 63 | DrawPixel(-x + x0, y + y0, color); 64 | DrawPixel(-y + x0, x + y0, color); 65 | DrawPixel(-x + x0, -y + y0, color); 66 | DrawPixel(-y + x0, -x + y0, color); 67 | DrawPixel(x + x0, -y + y0, color); 68 | DrawPixel(y + x0, -x + y0, color); 69 | 70 | y++; 71 | if(radiusError<0) 72 | radiusError+=2*y+1; 73 | else 74 | { 75 | x--; 76 | radiusError+=2*(y-x+1); 77 | } 78 | } 79 | } 80 | 81 | void DrawCharacterAt(unsigned int ch, unsigned int x, unsigned int y, CSIZE color) 82 | { 83 | // Ensure valid char table lookup 84 | ch = ch < 32 ? 0 : ch > 127 ? 0 : ch - 32; 85 | 86 | int col; 87 | unsigned int row; 88 | for(row = 0; row < CHAR_HEIGHT; row++) 89 | { 90 | unsigned int i = 0; 91 | for(col = CHAR_HEIGHT - 2; col >= 0 ; col--) 92 | { 93 | if(row < (CHAR_HEIGHT - 1) && (teletext[ch][row] & (1 << col))) 94 | { 95 | DrawPixel(x + i, y + row, color); 96 | } 97 | else 98 | { 99 | DrawPixel(x + i, y + row, 0x0000); 100 | } 101 | i++; 102 | } 103 | } 104 | } 105 | 106 | void PutsAt(const char *s, unsigned int x, unsigned int y, CSIZE color) 107 | { 108 | unsigned int i = 0; 109 | unsigned int c = 0; 110 | 111 | while(s[i] !=0) 112 | { 113 | c = s[i++]; 114 | DrawCharacterAt(c, x,y, color); 115 | x += 8; 116 | }; 117 | 118 | } -------------------------------------------------------------------------------- /source/keyboard.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "usbd/usbd.h" 3 | #include "device/hid/keyboard.h" 4 | #include "terminal.h" 5 | #include "string.h" 6 | #include "keyboard.h" 7 | 8 | 9 | char* gKeynames[] = 10 | { 11 | "A", // 0 12 | "B", 13 | "C", 14 | "D", 15 | "E", 16 | "F", 17 | "G", 18 | "H", 19 | "I", 20 | "J", 21 | "K", // 10 22 | "L", 23 | "M", 24 | "N", 25 | "O", 26 | "P", 27 | "Q", 28 | "R", 29 | "S", 30 | "T", 31 | "U", // 20 32 | "V", 33 | "W", 34 | "X", 35 | "Y", 36 | "Z", 37 | "1", 38 | "2", 39 | "3", 40 | "4", 41 | "5", // 30 42 | "6", 43 | "7", 44 | "8", 45 | "9", 46 | "0", 47 | "RETURN", 48 | "ESC", 49 | "BSP", 50 | "TAB", 51 | "SPACE", // 40 52 | "MINUS", 53 | "EQUALS", 54 | "LSQUAREBRACKET", 55 | "RSQUAREBRACKET", 56 | "BACKSLASH", // NO 57 | "HASH", 58 | "SEMICOLON", 59 | "APOSTROPHE", 60 | "GRAVE", 61 | "COMMA", // 50 62 | "FULLSTOP", 63 | "FORWARDFLASH", 64 | "CAPS-LOCK", 65 | "F1", 66 | "F2", 67 | "F3", 68 | "F4", 69 | "F5", 70 | "F6", 71 | "F7", // 60 72 | "F8", 73 | "F9", 74 | "F10", 75 | "F11", 76 | "F12", 77 | "PRTSCN", 78 | "SCROLL-LOCK", 79 | "BREAK", 80 | "INSERT", 81 | "HOME", // 70 82 | "PAGE-UP", 83 | "DELETE", 84 | "END", 85 | "PAGE-DOWN", 86 | "RIGHT", //5 87 | "LEFT", // 6 88 | "DOWN", // 7 89 | "UP", // 8 90 | "NUM-LOCK", 91 | "NUMDIV", // 80 92 | "NUMMUL", 93 | "NUMSUB", 94 | "NUMADD", 95 | "NUMRETURN", 96 | "NUM1", 97 | "NUM2", 98 | "NUM3", 99 | "NUM4", 100 | "NUM5", 101 | "NUM6", // 90 102 | "NUM7", 103 | "NUM8", 104 | "NUM9", 105 | "NUM10", 106 | "NUMDELETE", 107 | "BACKSLASH", 108 | "RMENU" 109 | }; 110 | 111 | const char gVirtualTable_shifted[] = 112 | { 113 | 0, 114 | 0, 115 | 0, 116 | 0, 117 | 'A', 118 | 'B', 119 | 'C', 120 | 'D', 121 | 'E', 122 | 'F', 123 | 'G', 124 | 'H', 125 | 'I', 126 | 'J', 127 | 'K', // 10 128 | 'L', 129 | 'M', 130 | 'N', 131 | 'O', 132 | 'P', 133 | 'Q', 134 | 'R', 135 | 'S', 136 | 'T', 137 | 'U', // 20 138 | 'V', 139 | 'W', 140 | 'X', 141 | 'Y', 142 | 'Z', 143 | '!', 144 | '"', 145 | '*', 146 | '$', // 30 147 | '%', 148 | '^', 149 | '&', 150 | '*', 151 | '(', 152 | ')', 153 | '\r', 154 | /*esc*/0, 155 | /*Bsp*/0, 156 | '\t', 157 | ' ', // 40 158 | '_', 159 | '+', 160 | '{', 161 | '}', 162 | '|', 163 | '~', 164 | ':', 165 | '@', 166 | '*', 167 | '<', // 50 168 | '>', 169 | '?', 170 | 0, 171 | 0, 172 | 0, 173 | 0, 174 | 0, 175 | 0, 176 | 0, 177 | 0, // 60 178 | 0, 179 | 0, 180 | 0, 181 | 0, 182 | 0, 183 | 0, 184 | 0, 185 | 0, 186 | 0, 187 | 0, // 70 188 | 0, 189 | 0, 190 | 0, 191 | 0, 192 | 0, 193 | 0, 194 | 0, 195 | 0, 196 | 0, 197 | '/', // 80 198 | '*', 199 | '-', 200 | '+', 201 | '\n', 202 | '1', 203 | '2', 204 | '3', 205 | '4', 206 | '5', 207 | '6', // 90 208 | '7', 209 | '8', 210 | '9', 211 | '0', 212 | 0, // Numpad delete 213 | '\\' 214 | }; 215 | 216 | const char gVirtualTable[] = 217 | { 218 | 0, 219 | 0, 220 | 0, 221 | 0, 222 | 'A', 223 | 'B', 224 | 'C', 225 | 'D', 226 | 'E', 227 | 'F', 228 | 'G', 229 | 'H', 230 | 'I', 231 | 'J', 232 | 'K', // 10 233 | 'L', 234 | 'M', 235 | 'N', 236 | 'O', 237 | 'P', 238 | 'Q', 239 | 'R', 240 | 'S', 241 | 'T', 242 | 'U', // 20 243 | 'V', 244 | 'W', 245 | 'X', 246 | 'Y', 247 | 'Z', 248 | '1', 249 | '2', 250 | '3', 251 | '4', // 30 252 | '5', 253 | '6', 254 | '7', 255 | '8', 256 | '9', 257 | '0', 258 | '\r', 259 | /*esc*/27, 260 | /*Bsp*/20, 261 | '\t', 262 | ' ', // 40 263 | '-', 264 | '=', 265 | '[', 266 | ']', 267 | '\\', 268 | '#', 269 | ';', 270 | '\'', 271 | '`', 272 | ',', // 50 273 | '.', 274 | '/', 275 | 0, 276 | 0, 277 | 0, 278 | 0, 279 | 0, 280 | 0, 281 | 0, 282 | 0, // 60 283 | 0, 284 | 0, 285 | 0, 286 | 0, 287 | 0, 288 | 0, 289 | 0, 290 | 0, 291 | 0, 292 | 0, // 70 293 | 0, 294 | 0, 295 | 0, 296 | 0, 297 | 29, 298 | 157, 299 | 17, 300 | 145, 301 | 0, 302 | '/', // 80 303 | '*', 304 | '-', 305 | '+', 306 | '\n', 307 | '1', 308 | '2', 309 | '3', 310 | '4', 311 | '5', 312 | '6', // 90 313 | '7', 314 | '8', 315 | '9', 316 | '0', 317 | 20, // Numpad delete 318 | '\\' 319 | }; 320 | 321 | bool gHaveKeyboard; 322 | unsigned int gKeyboardAddr; 323 | unsigned short gLastKeystate[6]; 324 | struct KeyboardModifiers gLastModifiers; 325 | 326 | bool KeyboardCtrlDown(void) 327 | { 328 | return gLastModifiers.LeftControl || gLastModifiers.RightControl; 329 | } 330 | 331 | bool KeyboardShiftDown(void) 332 | { 333 | return gLastModifiers.LeftShift || gLastModifiers.RightShift; 334 | } 335 | 336 | virtualkey ScanToVirtual(unsigned int scanCode) 337 | { 338 | if(scanCode < 0) return -1; 339 | 340 | return (virtualkey)(scanCode - 4); 341 | } 342 | 343 | unsigned char VirtualToAsci(virtualkey vk, bool shifted) 344 | { 345 | if(vk < 0 || vk > (sizeof(gVirtualTable) / sizeof(gVirtualTable[0]))) return -1; 346 | 347 | if(shifted) 348 | return gVirtualTable_shifted[vk + 4]; 349 | else 350 | return gVirtualTable[vk + 4]; 351 | } 352 | 353 | char* GetKeyName(char* buf, unsigned int bufLen, virtualkey vk) 354 | { 355 | char* keyName = gKeynames[vk]; 356 | 357 | if(strlen(keyName) < bufLen) 358 | strcpy(keyName, buf); 359 | 360 | return buf; 361 | } 362 | 363 | // Retrieves the address of the first attached keyboard 364 | bool EnsureKeyboard(void) 365 | { 366 | // KeyboardUpdate() modifies this 367 | if(gHaveKeyboard) 368 | return true; 369 | 370 | UsbCheckForChange(); 371 | 372 | if(KeyboardCount() == 0) 373 | { 374 | gHaveKeyboard = false; 375 | return false; 376 | } 377 | 378 | gKeyboardAddr = KeyboardGetAddress(0); 379 | gHaveKeyboard = true; 380 | 381 | return true; 382 | } 383 | 384 | bool KeyWasDown(unsigned short scanCode) 385 | { 386 | unsigned int i; 387 | for(i = 0; i < 6; i++) 388 | if(gLastKeystate[i] == scanCode) return true; 389 | 390 | return false; 391 | } 392 | 393 | // Gets the scanCode of the first currently pressed key (0 if none) 394 | unsigned short KeyboardGetChar(void) 395 | { 396 | unsigned int i; 397 | for(i = 0; i < 6; i++) 398 | { 399 | unsigned short key = KeyboardGetKeyDown(gKeyboardAddr, i); 400 | 401 | if(key == 0) return 0; 402 | if(KeyWasDown(key)) continue; 403 | if(key >= 104) continue; 404 | 405 | return key; 406 | } 407 | 408 | return 0; 409 | } 410 | 411 | unsigned int KeyboardInitialise(void) 412 | { 413 | gHaveKeyboard = false; 414 | gKeyboardAddr = 0; 415 | 416 | unsigned int i; 417 | for(i = 0; i < 6; i++) 418 | gLastKeystate[i] = 0; 419 | 420 | return 0; 421 | } 422 | 423 | void KeyboardUpdate(void) 424 | { 425 | if(!EnsureKeyboard()) 426 | { 427 | print("Failed to update keyboard, could not obtain device.", strlen("Failed to update keyboard, could not obtain device.")); 428 | return; 429 | } 430 | 431 | unsigned int i; 432 | for(i = 0; i < 6; i++) 433 | gLastKeystate[i] = KeyboardGetKeyDown(gKeyboardAddr, i); 434 | 435 | gHaveKeyboard = KeyboardPoll(gKeyboardAddr) == 0; 436 | gLastModifiers = KeyboardGetModifiers(gKeyboardAddr); 437 | } 438 | -------------------------------------------------------------------------------- /source/mailbox.c: -------------------------------------------------------------------------------- 1 | #define MAILBOX_FULL 0x80000000 2 | #define MAILBOX_EMPTY 0x40000000 3 | 4 | static volatile unsigned int *MAILBOX0READ = (unsigned int *)(0x2000b880); 5 | static volatile unsigned int *MAILBOX0STATUS = (unsigned int *)(0x2000b898); 6 | static volatile unsigned int *MAILBOX0WRITE = (unsigned int *)(0x2000b8a0); 7 | 8 | unsigned int Mailbox_Read(unsigned int channel) 9 | { 10 | unsigned int count = 0; 11 | unsigned int data; 12 | 13 | // Loop until something is received on the channel 14 | while(1) 15 | { 16 | while (*MAILBOX0STATUS & MAILBOX_EMPTY) 17 | { 18 | // Arbitrary large number for timeout 19 | if(count++ >(1<<25)) 20 | { 21 | return 0xffffffff; 22 | } 23 | } 24 | 25 | data = *MAILBOX0READ; 26 | 27 | if ((data & 15) == channel) 28 | return data; 29 | } 30 | } 31 | 32 | void Mailbox_Write(unsigned int channel, unsigned int data) 33 | { 34 | // Wait until there's space in the mailbox 35 | while (*MAILBOX0STATUS & MAILBOX_FULL){ 36 | } 37 | 38 | // 28 MSB is data, 4 LSB = channel 39 | *MAILBOX0WRITE = (data | channel); 40 | } 41 | -------------------------------------------------------------------------------- /source/main.c: -------------------------------------------------------------------------------- 1 | #include "gpio.h" 2 | #include "timer.h" 3 | #include "terminal.h" 4 | #include "string.h" 5 | #include "usbd/usbd.h" 6 | #include "keyboard.h" 7 | 8 | extern unsigned int gPitch; 9 | 10 | void OnCriticalError(void) 11 | { 12 | while(1) 13 | { 14 | LedOff(); 15 | 16 | wait(1000); 17 | 18 | LedOn(); 19 | 20 | wait(1000); 21 | } 22 | } 23 | 24 | // Log function for CSUD 25 | void LogPrint(char* message, unsigned int length) 26 | { 27 | //print(message, length); 28 | } 29 | 30 | int cmain2(void) 31 | { 32 | //No keyboard 33 | unsigned int result = 0; 34 | 35 | LedInit(); 36 | 37 | if((result = terminal_init()) != 0) 38 | OnCriticalError(); 39 | 40 | CB64_MainLoop(); 41 | 42 | } 43 | 44 | int cmain(void) 45 | { 46 | unsigned int result = 0; 47 | 48 | //Enable cache 49 | unsigned int controlRegister; 50 | asm volatile ("MRC p15, 0, %0, c1, c0, 0" : "=r" (controlRegister)); 51 | controlRegister|=0x1800; 52 | asm volatile ("MCR p15, 0, %0, c1, c0, 0" :: "r" (controlRegister)); 53 | 54 | LedInit(); 55 | 56 | if((result = terminal_init()) != 0) 57 | OnCriticalError(); 58 | 59 | printf("\n\n One moment..."); 60 | 61 | if((result = UsbInitialise()) != 0) 62 | printf("Usb initialise failed, error code: %d\n", result); 63 | else 64 | { 65 | if((result = KeyboardInitialise()) != 0) 66 | printf("Keyboard initialise failed, error code: %d\n", result); 67 | else 68 | CB64_MainLoop(); 69 | } 70 | 71 | } 72 | 73 | int cmainx(void) 74 | { 75 | unsigned int result = 0; 76 | int fb = 1; 77 | 78 | LedInit(); 79 | 80 | if((result = terminal_init()) != 0) 81 | OnCriticalError(); 82 | 83 | if((result = UsbInitialise()) != 0) 84 | printf("Usb initialise failed, error code: %d\n", result); 85 | else 86 | { 87 | if((result = KeyboardInitialise()) != 0) 88 | printf("Keyboard initialise failed, error code: %d\n", result); 89 | else 90 | { 91 | //Draw on second buffer 92 | SetVirtualFrameBuffer(2); 93 | terminal_clear(); 94 | printf("This is framebuffer 2"); 95 | 96 | SetVirtualFrameBuffer(1); 97 | terminal_clear(); 98 | printf("\nFramebuffer 1 - Keyboard test\n\n"); 99 | printf("gPitch= %d\n\n", gPitch); 100 | 101 | while(1) 102 | { 103 | KeyboardUpdate(); 104 | 105 | short scanCode = KeyboardGetChar(); 106 | 107 | // Nothing pressed 108 | if(scanCode == 0) 109 | { 110 | wait(10); 111 | continue; 112 | } 113 | 114 | virtualkey vk = ScanToVirtual(scanCode); 115 | 116 | char c = VirtualToAsci(vk, KeyboardShiftDown()); 117 | 118 | //printf("%c", c); 119 | 120 | char name[15]; 121 | char* keyname = GetKeyName(name, 15, vk); 122 | 123 | printf("Scan: %d Vk: %d Name: %s\n", scanCode, (unsigned int)vk, keyname); 124 | 125 | wait(10); 126 | 127 | if(c == 65) 128 | { 129 | if(fb == 1) 130 | fb=2; 131 | else 132 | fb=1; 133 | 134 | SetVirtualFrameBuffer(fb); 135 | DisplayVirtualFramebuffer(fb); 136 | } 137 | 138 | } 139 | } 140 | 141 | } 142 | 143 | } 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /source/math.c: -------------------------------------------------------------------------------- 1 | int abs(int x) 2 | { 3 | int t = x >> 31; 4 | // t is -1 if x is negative otherwise it is 0 5 | return t ^ (x + t); 6 | } 7 | -------------------------------------------------------------------------------- /source/start.s: -------------------------------------------------------------------------------- 1 | .globl _start 2 | _start: 3 | 4 | mov sp, #0x8000 5 | 6 | ;@ Clear out bss. 7 | ldr r4, =_bss_start 8 | ldr r9, =_bss_end 9 | mov r5, #0 10 | mov r6, #0 11 | mov r7, #0 12 | mov r8, #0 13 | b 2f 14 | 15 | 1: 16 | ;@ store multiple at r4. 17 | stmia r4!, {r5-r8} 18 | 19 | ;@ If we are still below bss_end, loop. 20 | 2: 21 | cmp r4, r9 22 | blo 1b 23 | 24 | bl cmain 25 | 26 | hang: 27 | b hang 28 | 29 | .globl PUT32 30 | PUT32: 31 | str r1, [r0] 32 | bx lr 33 | 34 | .globl GET32 35 | GET32: 36 | ldr r0, [r0] 37 | bx lr 38 | 39 | .globl dummy 40 | dummy: 41 | bx lr 42 | -------------------------------------------------------------------------------- /source/stdio.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "usbd/usbd.h" // For UsbCheckForChange() 3 | #include "device/hid/keyboard.h" 4 | #include "terminal.h" 5 | #include "string.h" 6 | #include "keyboard.h" 7 | 8 | void cin(char* buf, unsigned int bufLen) 9 | { 10 | unsigned int readChars = 0; 11 | char temp[bufLen]; 12 | 13 | if(!EnsureKeyboard()) 14 | return; // We have no keyboard 15 | 16 | do 17 | { 18 | char k = KeyboardGetChar(); 19 | if(k == 0) 20 | continue; 21 | 22 | if(k == '\n') 23 | break; 24 | 25 | temp[readChars] = k; 26 | readChars++; 27 | 28 | }while(readChars < bufLen); // Just keep reading (Return cancels this early) 29 | 30 | if(readChars < bufLen - 1) 31 | temp[readChars + 1] = '\0'; 32 | else 33 | temp[bufLen - 1] = '\0'; 34 | 35 | // Copy the read stuff into the buffer 36 | strcpy(temp, buf); 37 | } -------------------------------------------------------------------------------- /source/string.c: -------------------------------------------------------------------------------- 1 | #include "string.h" 2 | #include "terminal.h" 3 | 4 | int strlen(char* str) 5 | { 6 | int length = 0; 7 | while(*str++) 8 | length++; 9 | 10 | return length; 11 | } 12 | 13 | char* strcpy(const char* src, char* dst) 14 | { 15 | char *ptr; 16 | ptr = dst; 17 | while((*dst++ = *src++)); 18 | 19 | return ptr; 20 | } 21 | 22 | // TODO: Rewrite this to take in the pointer to a buffer where the result will be stored 23 | void itoa(int number, char* buf) 24 | { 25 | // We populate the string backwards, increment to make room for \0 26 | buf++; 27 | 28 | int negative = number < 0; 29 | if(negative) 30 | { 31 | buf++; 32 | number = -number; 33 | } 34 | 35 | // Find where our string will end 36 | int shifter = number; 37 | do 38 | { 39 | buf++; 40 | shifter /= 10; 41 | }while(shifter > 0); 42 | 43 | // Make sure the string is terminated nicely 44 | *--buf = '\0'; 45 | 46 | // Start converting the digits into characters 47 | do 48 | { 49 | *--buf = '0' + (number % 10); // Muahaha! 50 | number /= 10; 51 | }while(number > 0); 52 | 53 | if(negative) 54 | *--buf = '-'; 55 | 56 | // Done! 57 | } 58 | 59 | void printf(char* text, ...) 60 | { 61 | // set up variable argument list 62 | va_list ap; 63 | va_start(ap, text); 64 | 65 | char res[256]; 66 | char* result = res; 67 | 68 | // scan all characters in 'text' and look for format specifiers 69 | do 70 | { 71 | if(*text == '%') 72 | { 73 | if(*(text + 1) == 'c') // unsigned char 74 | { 75 | *result++ = (char)va_arg(ap, unsigned int); 76 | } 77 | else if(*(text + 1) == 'd') // integer (signed) 78 | { 79 | char itoBuf[10]; 80 | itoa(va_arg(ap, int), &itoBuf[0]); 81 | 82 | char* intstr = strcpy(itoBuf, result); 83 | 84 | result += strlen(intstr); 85 | } 86 | else if(*(text + 1) == 's') // string 87 | { 88 | char* arg = (char*)va_arg(ap, int); 89 | 90 | strcpy(arg, result); 91 | 92 | result += strlen(arg); 93 | } 94 | 95 | // make sure we skip the type specifier 96 | text++; 97 | 98 | continue; 99 | } 100 | 101 | // if we got thus far, it's probably just a normal character 102 | *result++ = *text; 103 | }while(*text++ != '\0'); 104 | 105 | print(res, strlen(res)); 106 | } 107 | 108 | void *ucmemset(unsigned char *s, int c, size_t n) 109 | { 110 | unsigned char* p=s; 111 | while(n--) 112 | *p++ = (unsigned char)c; 113 | return s; 114 | } 115 | 116 | void *imemset(int *s, int c, size_t n) 117 | { 118 | int* p=s; 119 | while(n--) 120 | *p++ = (unsigned char)c; 121 | return s; 122 | } 123 | void *cmemset(char *s, int c, size_t n) 124 | { 125 | char* p=s; 126 | while(n--) 127 | *p++ = (unsigned char)c; 128 | return s; 129 | } 130 | 131 | void *memcpy(BYTE *dest, const BYTE *src, size_t n) 132 | { 133 | BYTE *dp = dest; 134 | const BYTE *sp = src; 135 | while (n--) 136 | *dp++ = *sp++; 137 | return dest; 138 | } -------------------------------------------------------------------------------- /source/terminal.c: -------------------------------------------------------------------------------- 1 | #define CHAR_HEIGHT 8 2 | #define CHAR_WIDTH 8 3 | #define CHAR_VSPACING 0 4 | #define CHAR_HSPACING 0 5 | #define TERMINAL_WIDTH (SCREEN_WIDTH / (CHAR_WIDTH + CHAR_HSPACING)) - 1 // 191 @ 1920 6 | #define TERMINAL_HEIGHT (SCREEN_HEIGHT / (CHAR_HEIGHT + CHAR_VSPACING)) - 1 // 76 @ 1080 7 | #define BUFFER_HEIGHT TERMINAL_HEIGHT 8 | #define BUFFER_WIDTH TERMINAL_WIDTH 9 | 10 | #include "framebuffer.h" 11 | 12 | // TODO 0: Make buffer larger than display to allow for some history to get saved 13 | // TODO 1: Change to int buffers and embed colors in value 14 | char gBuffer[BUFFER_HEIGHT][BUFFER_WIDTH]; 15 | char gTerminal[TERMINAL_HEIGHT][TERMINAL_WIDTH]; 16 | int gBufferCaretRow; // The current row of the caret - where text will be written to 17 | int gBufferCaretCol; // The current column of the caret - where text will be written to 18 | int gFirstVisibleBufferRow; // The row in the first buffer that is currently the first row on screen 19 | 20 | void PresentBufferToScreen(void) 21 | { 22 | 23 | unsigned int row; 24 | unsigned int col; 25 | for(row = 0; row < TERMINAL_HEIGHT; row++) 26 | { 27 | for(col = 0; col < TERMINAL_WIDTH; col++) 28 | { 29 | if(gTerminal[row][col] != gBuffer[row][col]) 30 | { 31 | gTerminal[row][col] = gBuffer[row][col]; 32 | DrawCharacterAt(gTerminal[row][col], col * (CHAR_WIDTH + CHAR_HSPACING), row * (CHAR_HEIGHT + CHAR_VSPACING), 0x07FF); 33 | } 34 | } 35 | } 36 | } 37 | 38 | void terminal_clear(void) 39 | { 40 | gFirstVisibleBufferRow = 0; 41 | gBufferCaretRow = 0; 42 | gBufferCaretCol = 0; 43 | 44 | unsigned int row; 45 | for(row = 0; row < BUFFER_HEIGHT; row++) 46 | { 47 | unsigned int col; 48 | for(col = 0; col < BUFFER_WIDTH; col++) 49 | { 50 | gBuffer[row][col] = ' '; 51 | } 52 | } 53 | 54 | // Sync to display 55 | PresentBufferToScreen(); 56 | } 57 | 58 | int terminal_init(void) 59 | { 60 | if(InitializeFramebuffer() != 0) 61 | { 62 | return -1; 63 | } 64 | 65 | // Initial setup of buffers etc 66 | terminal_clear(); 67 | 68 | return(0); 69 | } 70 | 71 | void terminal_back(void) 72 | { 73 | if(gBufferCaretCol == 0) 74 | { 75 | gBufferCaretRow--; 76 | gBufferCaretCol = BUFFER_WIDTH - 1; 77 | 78 | // We have to go back up a row 79 | gBuffer[gBufferCaretRow][gBufferCaretCol] = ' '; 80 | } 81 | else 82 | { 83 | gBufferCaretCol--; 84 | gBuffer[gBufferCaretRow][gBufferCaretCol] = ' '; 85 | } 86 | 87 | PresentBufferToScreen(); 88 | } 89 | 90 | void print(char* string, unsigned int length) 91 | { 92 | // 1. "Draw" everything to the buffer 93 | unsigned int i; 94 | for(i = 0; i < length; i++) 95 | { 96 | if(string[i] == '\n') 97 | { 98 | gBuffer[gBufferCaretRow][gBufferCaretCol] = ' '; 99 | gBufferCaretRow++; 100 | gBufferCaretCol = 0; 101 | continue; 102 | } 103 | 104 | if(gBuffer[gBufferCaretRow][gBufferCaretCol] != string[i]) 105 | gBuffer[gBufferCaretRow][gBufferCaretCol] = string[i]; 106 | 107 | if(gBufferCaretCol < BUFFER_WIDTH - 1) 108 | { 109 | gBufferCaretCol++; 110 | } 111 | else 112 | { 113 | // Reached the end of this row 114 | gBufferCaretRow++; 115 | gBufferCaretCol = 0; 116 | } 117 | 118 | if(gBufferCaretRow >= BUFFER_HEIGHT) 119 | { 120 | terminal_clear(); 121 | gBufferCaretRow = 0; 122 | } 123 | } 124 | 125 | // 2. Flip buffer to screen 126 | PresentBufferToScreen(); 127 | } 128 | -------------------------------------------------------------------------------- /source/timer.c: -------------------------------------------------------------------------------- 1 | extern unsigned int GET32(unsigned int); 2 | 3 | #define SYSTIMER_COUNTER 0x20003004 4 | 5 | void wait(unsigned int milliSeconds) 6 | { 7 | unsigned int ttw = 1048 * milliSeconds; 8 | unsigned int start = GET32(SYSTIMER_COUNTER); 9 | while(1) 10 | { 11 | if(GET32(SYSTIMER_COUNTER) - start >= ttw) 12 | break; 13 | } 14 | } 15 | --------------------------------------------------------------------------------