From 2acc10f5d653a2f0d25c11c3559830aedf61ddad Mon Sep 17 00:00:00 2001 From: Florian Fleissner Date: Thu, 13 Jun 2019 14:02:14 +0200 Subject: [PATCH] Restructured the virtual hardware Some parts were moved over from Kaleidoscope-Hardware-Virtual. The virtual hardware is now a drop in for the real pluggable USB interface. Signed-off-by: Florian Fleissner --- virtual/cores/virtual/EEPROM.cpp | 22 ++++ virtual/cores/virtual/EEPROM.h | 150 +++++++++++++++++++++++++ virtual/cores/virtual/PluggableUSB.cpp | 24 ++++ virtual/cores/virtual/PluggableUSB.h | 132 ++++++++++++++++++++++ virtual/cores/virtual/mcu/atmega32u4.h | 37 ++++++ 5 files changed, 365 insertions(+) create mode 100644 virtual/cores/virtual/EEPROM.cpp create mode 100644 virtual/cores/virtual/EEPROM.h create mode 100644 virtual/cores/virtual/PluggableUSB.cpp create mode 100644 virtual/cores/virtual/PluggableUSB.h create mode 100644 virtual/cores/virtual/mcu/atmega32u4.h diff --git a/virtual/cores/virtual/EEPROM.cpp b/virtual/cores/virtual/EEPROM.cpp new file mode 100644 index 0000000..a32e702 --- /dev/null +++ b/virtual/cores/virtual/EEPROM.cpp @@ -0,0 +1,22 @@ +/* -*- mode: c++ -*- + * Kaleidoscope + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "EEPROM.h" + +uint8_t EERef::eeprom_[kaleidoscope::hardware::mcu::eeprom_size]; + +EEPROMClass EEPROM; diff --git a/virtual/cores/virtual/EEPROM.h b/virtual/cores/virtual/EEPROM.h new file mode 100644 index 0000000..07e5690 --- /dev/null +++ b/virtual/cores/virtual/EEPROM.h @@ -0,0 +1,150 @@ +/* + EEPROM.h - EEPROM library + Original Copyright (c) 2006 David A. Mellis. All right reserved. + New version by Christopher Andrews 2015. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// This is a stub implementation replaces EEPROM by an array stored in RAM. + +#ifndef EEPROM_h +#define EEPROM_h + +#include "Arduino.h" + +#include KALEIDOSCOPE_MCU_H + +/*** + EERef class. + + This object references an EEPROM cell. + Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM. + This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell. +***/ + +struct EERef{ + + EERef( const int index ) + : index( index ) {} + + //Access/read members. + uint8_t operator*() const { return eeprom_[index]; } + operator uint8_t() const { return **this; } + + //Assignment/write members. + EERef &operator=( const EERef &ref ) { return *this = *ref; } + EERef &operator=( uint8_t in ) { eeprom_[index] = in; return *this; } + EERef &operator +=( uint8_t in ) { return *this = **this + in; } + EERef &operator -=( uint8_t in ) { return *this = **this - in; } + EERef &operator *=( uint8_t in ) { return *this = **this * in; } + EERef &operator /=( uint8_t in ) { return *this = **this / in; } + EERef &operator ^=( uint8_t in ) { return *this = **this ^ in; } + EERef &operator %=( uint8_t in ) { return *this = **this % in; } + EERef &operator &=( uint8_t in ) { return *this = **this & in; } + EERef &operator |=( uint8_t in ) { return *this = **this | in; } + EERef &operator <<=( uint8_t in ) { return *this = **this << in; } + EERef &operator >>=( uint8_t in ) { return *this = **this >> in; } + + EERef &update( uint8_t in ) { return in != *this ? *this = in : *this; } + + /** Prefix increment/decrement **/ + EERef& operator++() { return *this += 1; } + EERef& operator--() { return *this -= 1; } + + /** Postfix increment/decrement **/ + uint8_t operator++ (int){ + uint8_t ret = **this; + return ++(*this), ret; + } + + uint8_t operator-- (int){ + uint8_t ret = **this; + return --(*this), ret; + } + + int index; //Index of current EEPROM cell. + + static uint8_t eeprom_[kaleidoscope::hardware::mcu::eeprom_size]; +}; + +/*** + EEPtr class. + + This object is a bidirectional pointer to EEPROM cells represented by EERef objects. + Just like a normal pointer type, this can be dereferenced and repositioned using + increment/decrement operators. +***/ + +struct EEPtr{ + + EEPtr( const int index ) + : index( index ) {} + + operator int() const { return index; } + EEPtr &operator=( int in ) { return index = in, *this; } + + //Iterator functionality. + bool operator!=( const EEPtr &ptr ) { return index != ptr.index; } + EERef operator*() { return index; } + + /** Prefix & Postfix increment/decrement **/ + EEPtr& operator++() { return ++index, *this; } + EEPtr& operator--() { return --index, *this; } + EEPtr operator++ (int) { return index++; } + EEPtr operator-- (int) { return index--; } + + int index; //Index of current EEPROM cell. +}; + +/*** + EEPROMClass class. + + This object represents the entire EEPROM space. + It wraps the functionality of EEPtr and EERef into a basic interface. + This class is also 100% backwards compatible with earlier Arduino core releases. +***/ + +struct EEPROMClass{ + + //Basic user access methods. + EERef operator[]( const int idx ) { return idx; } + uint8_t read( int idx ) { return EERef( idx ); } + void write( int idx, uint8_t val ) { (EERef( idx )) = val; } + void update( int idx, uint8_t val ) { EERef( idx ).update( val ); } + + //STL and C++11 iteration capability. + EEPtr begin() { return 0x00; } + EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid. + uint16_t length() { return kaleidoscope::hardware::mcu::eeprom_size; } + + //Functionality to 'get' and 'put' objects to and from EEPROM. + template< typename T > T &get( int idx, T &t ){ + EEPtr e = idx; + uint8_t *ptr = (uint8_t*) &t; + for( int count = sizeof(T) ; count ; --count, ++e ) *ptr++ = *e; + return t; + } + + template< typename T > const T &put( int idx, const T &t ){ + EEPtr e = idx; + const uint8_t *ptr = (const uint8_t*) &t; + for( int count = sizeof(T) ; count ; --count, ++e ) (*e).update( *ptr++ ); + return t; + } +}; + +extern EEPROMClass EEPROM; +#endif diff --git a/virtual/cores/virtual/PluggableUSB.cpp b/virtual/cores/virtual/PluggableUSB.cpp new file mode 100644 index 0000000..2adca18 --- /dev/null +++ b/virtual/cores/virtual/PluggableUSB.cpp @@ -0,0 +1,24 @@ +/* -*- mode: c++ -*- + * Kaleidoscope + * Copyright (C) 2019 noseglasses (shinynoseglasses@gmail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "PluggableUSB.h" + +PluggableUSB_ &PluggableUSB() { + static PluggableUSB_ dummy; + return dummy; +} diff --git a/virtual/cores/virtual/PluggableUSB.h b/virtual/cores/virtual/PluggableUSB.h new file mode 100644 index 0000000..fafec09 --- /dev/null +++ b/virtual/cores/virtual/PluggableUSB.h @@ -0,0 +1,132 @@ +/* -*- mode: c++ -*- + * Kaleidoscope + * Copyright (C) 2019 noseglasses (shinynoseglasses@gmail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +// This file contains only stub implementation. +// The content is in great parts copied from +// arduino/avr/cores/arduino/PluggableUSB.* + +struct InterfaceDescriptor { + template + InterfaceDescriptor(_Dummy...) {} +}; +struct EndpointDescriptor { + template + EndpointDescriptor(_Dummy...) {} +}; + +struct USBSetup; + +class PluggableUSBModule { + public: + PluggableUSBModule(uint8_t numEps, uint8_t numIfs, uint8_t *epType) : + numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType) + { } + + protected: + virtual bool setup(USBSetup &setup) = 0; + virtual int getInterface(uint8_t *interfaceCount) = 0; + virtual int getDescriptor(USBSetup &setup) = 0; + virtual uint8_t getShortName(char *name) { + name[0] = 'A'+pluggedInterface; + return 1; + } + + uint8_t pluggedInterface = 0; + uint8_t pluggedEndpoint; + + const uint8_t numEndpoints; + const uint8_t numInterfaces; + const uint8_t *endpointType; + + PluggableUSBModule *next = nullptr; + + friend class PluggableUSB_; +}; + +class PluggableUSB_ { + public: + PluggableUSB_() {} + bool plug(PluggableUSBModule *node) { + return true; + } + int getInterface(uint8_t *interfaceCount) { + return 1; + } + int getDescriptor(USBSetup &setup) { + return 1; + } + bool setup(USBSetup &setup) { + return true; + } + void getShortName(char *iSerialNum) {} + + private: + uint8_t lastIf; + uint8_t lastEp; + PluggableUSBModule *rootNode; +}; + +// Replacement for global singleton. +// This function prevents static-initialization-order-fiasco +// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use +PluggableUSB_ &PluggableUSB(); + +#define EP_TYPE_INTERRUPT_IN 1 +#define USB_DEVICE_CLASS_HUMAN_INTERFACE 1 +#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ + { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } +#define USB_ENDPOINT_IN(addr) (lowByte((addr) | 0x80)) +#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 +#define USB_EP_SIZE 1 +#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \ + { 7, 5, _addr,_attr,_packetSize, _interval } +#define REQUEST_DEVICETOHOST_STANDARD_INTERFACE 0 +#define REQUEST_DEVICETOHOST_CLASS_INTERFACE 0 +#define REQUEST_HOSTTODEVICE_CLASS_INTERFACE 0 + +#define TRANSFER_PGM 0 + +#define TRANSFER_RELEASE 0 + +inline +int USB_SendControl(uint8_t flags, const void *d, int len) { + return 1; +} + +inline +int USB_RecvControl(void *d, int len) { + return 0; +} + +inline +int USB_Send(uint8_t ep, const void *data, int len) { + return 0; +} + +struct USBSetup { + uint8_t bmRequestType = REQUEST_DEVICETOHOST_CLASS_INTERFACE; + uint8_t bRequest = 0x01; //HID_GET_REPORT; + uint8_t wValueL; + uint8_t wValueH = 0x21; //HID_REPORT_DESCRIPTOR_TYPE + uint16_t wIndex = 0; + uint16_t wLength; +}; diff --git a/virtual/cores/virtual/mcu/atmega32u4.h b/virtual/cores/virtual/mcu/atmega32u4.h new file mode 100644 index 0000000..7133c9c --- /dev/null +++ b/virtual/cores/virtual/mcu/atmega32u4.h @@ -0,0 +1,37 @@ +/* -*- mode: c++ -*- + * Kaleidoscope + * Copyright (C) 2019 noseglasses (shinynoseglasses@gmail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +namespace kaleidoscope { +namespace hardware { +namespace mcus { + +class atmega32u4 { + + public: + + static constexpr int eeprom_size = 1024; +}; + +} // namespace mcus + +typedef mcus::atmega32u4 mcu; + +} // namespace hardware +} // namespace kaleidoscope