From 164659fe0570ee510f742bad1f381cb9a754733d Mon Sep 17 00:00:00 2001 From: Lars Wadefalk Date: Tue, 16 Jul 2013 23:43:19 +0200 Subject: [PATCH] Added more info in README.TXT. Conditional compiling of the MAX7219 stuff in the arduino project. --- README.TXT | 117 +++++++++++++++++++++++++++++++++++++-- uno2iec/global_defines.h | 6 ++ uno2iec/interface.cpp | 21 ++++++- uno2iec/interface.h | 7 +++ uno2iec/uno2iec.ino | 14 ++++- 5 files changed, 157 insertions(+), 8 deletions(-) diff --git a/README.TXT b/README.TXT index 9348549..8742f77 100755 --- a/README.TXT +++ b/README.TXT @@ -1,4 +1,4 @@ - UNO2IEC ReadMe + UNO2IEC README DISCLAIMER: @@ -15,9 +15,27 @@ which can be found at http://www.gnu.org/licenses/gpl.txt Description ------------ -The UNO2IEC device simulates a 1541 drive and enables loading and saving -programs to MMC or SD flash media with a CBM. The FAT16 and FAT32 filesystems -are supported on raspberry as as a server via serial communication. +The UNO2IEC device simulates a 1541 drive and enables loading and saving files or +programs between a CBM and any "current" folder on the host system. The host system location can be network share, +USB, SD flash media, SSD or any hard disk that is supported by a Windows, Linux or Mac operating system. + +The direct commununication with the CBM is an arduino (uno or similar) communicating over a regular serial line +with the media host system. The serial line can be either the gpio pin mapped serial port on the arduino or the +serial over USB port. In case using the USB-over-serial port, the benefit is automatic reset of the arduino when the +host connects to it. + +Note: As of writing the project does not yet support any turboloaders. There are however plans or ideas to provide +this support. It should be possible with some extra work of performance tuning optimum handling of the serial interface. + +The project inherits both code and ideas from the MMC2IEC project, originally written by +Jan Derogee's and Lars Pontoppidan. Their original work is great and highly respected. +The code in this project however, has been subject to heavy redesign. While ported to C++ the idea is to let the +old commodore targeted media be transferred from a PC host rather than just a MMC or SD card. +The design of this project required the IEC protocol between the CBM and the emulated 1541 to be refactored into having +splitted responsibilities between the arduino and the PC host. +A secondary RS232-serial based protocol between the arduino is utilized to be able to transfer the actual media to +the CBM. + Target device ------------- @@ -35,16 +53,103 @@ Project homepage: Hardware setup -------------- +Arduino Uno: ATmega 16U2 328 microcontroller @ 16Mhz, 32KB flash, SRAM 2KB, EEPOM 1 KB. +Connect at least ATN, CLOCK and DATA pin to the IEC bus on the CBM. The Reset and SRQIN (latter one is unused on C64) +are optional to wire. +Can be bought cheap at dx.com: +http://dx.com/p/uno-r3-development-board-microcontroller-mega328p-atmega16u2-compat-for-arduino-blue-black-215600 + + +Optional: LED matrix with MAX7219 controller. +Can be bought cheap at dx.com with 5 dupont lines: +http://dx.com/p/max7219-dot-matrix-module-w-5-dupont-lines-184854 +Whether or not using the LED matrix when compiling, either define or comment out the USE_LED_DISPLAY macro in the +global_defines.h header in the uno2iec project. + +Either connect Arduino to a PC or MAC. Media host side project can be compiled on either Linux, Windows or Mac desktop. +It works on the Raspberry Pi as a host as well. Connect three serial pins on the PI to the arduino. The raspbian image +is the suggested linux, needs Qt build and runtime support. +For more info about how to prepare a raspberry pi for external serial communication, read the notes.txt file. + How to build ------------ Open the PC/Raspberry project in Qt creator and build either release or debug. +REQUIRES: (external dependencies): +QExtSerialPort project: +https://code.google.com/p/qextserialport/ + +The QExterSerialPort project should be located on the same directory level as the rpi2iec project. + + +Optional: Max7219 driver library (modified by Lars Wadefalk to c++ with support for progress bar display and scroller). +Github project: + +First build the Qt project on the desired platform. Then build and deploy the arduino project using the latest arduino +suite to the arduino target. + + Files in release: ----------------- README.TXT notes.txt -changes.txt -license.txt +TODO: changes.txt +TODO: license.txt + ./ Under repo root is the PC/Raspberry Qt project files. uni2iec/ All files under here is the arduino sketch. + +What else? +---------- +Ideas and improvements are highly welcome. Please contribute to this project! +The retro machine community gains from it. + +There are a few coding guidelines I would like to be followed (except for the ones who are obvious by just looking +at the code). + +The c++ files should have cpp and hpp file extensions. +Tabs instead of spaces are used (!), personally I use 2 indents (blanks) for each TAB. +Using TABs gives us more freedom. + +There is no limitation to 80 columns at all, but use common sense. +For splitted lines, operators are placed at the beginning of each new line to make code more clear (Qt style). + +Try to use constants rather than preprocess defines, and try to keep methods/functions const, if possible. + +Use camelCase. + +Blanks between operators, NOT between any parenthesis or NOT after any keyword. +Opening curly braces on same line for: while, do, for, if, namespace keywords. Not for classes, structs and typedefs. + +Use textual operators instead of the sadly enough common operators: +not_eq instead of != +not instead of ! +and instead of && +bitand instead of & +and_eq instead of &= +or instead of || +bitor instead of | +or_eq instead of |= + + +Always put comment at closing brace for function / method for the name, like: + +} // my_func + +Except for very short functions not expected to grow. + +Single line if / while / for statements are allowed, like: +if(isThisTrue) + YesItWas+++; + +Use with care of course, if you have a macro...think first. + +Think of minimal scope for variable declaration. + +Try to put related code/functions/method next to each other, like sections in a module. Don't mix unrelated code. + +Prefer Qt classes over STL. + +If there are any questions about these recommended guidlines, please don't hesitate to contact me. +Don't hesitate to let me know if I break my own recommendations...or better up, correct it. diff --git a/uno2iec/global_defines.h b/uno2iec/global_defines.h index 2beafce..9475c8a 100644 --- a/uno2iec/global_defines.h +++ b/uno2iec/global_defines.h @@ -4,4 +4,10 @@ #define CONSOLE_DEBUG //#define DEBUGLINES +// Define this if you want to include the support for the MAX7219 display library in this project. +// What it does is showing loading progress on the display and some nice scrolling of the filename and other +// stuff on the display. The display hardware can be bought here at dx.com: +// http://dx.com/p/max7219-dot-matrix-module-w-5-dupont-lines-184854 +#define USE_LED_DISPLAY + #endif // GLOBAL_DEFINES_HPP diff --git a/uno2iec/interface.cpp b/uno2iec/interface.cpp index 282f4db..5409ee5 100755 --- a/uno2iec/interface.cpp +++ b/uno2iec/interface.cpp @@ -63,7 +63,11 @@ const char errorEnding[] = ",00,00"; Interface::Interface(IEC& iec) - : m_iec(iec), m_pDisplay(0) + : m_iec(iec) +#ifdef USE_LED_DISPLAY + , m_pDisplay(0) +#endif + { reset(); } // ctor @@ -184,8 +188,11 @@ void Interface::sendFile() if(3 not_eq len or serCmdIOBuf[0] not_eq 'S') return; word written = 0; + +#ifdef USE_LED_DISPLAY if(0 not_eq m_pDisplay) m_pDisplay->resetPercentage((serCmdIOBuf[1] << 8) bitor serCmdIOBuf[2]); +#endif do { Serial.write('R'); // ask for a byte @@ -212,15 +219,22 @@ void Interface::sendFile() success = m_iec.send(serCmdIOBuf[i]); interrupts(); ++written; + +#ifdef USE_LED_DISPLAY if(!(written % 32) and 0 not_eq m_pDisplay) m_pDisplay->showPercentage(written); +#endif + } } else if('E' not_eq resp) Log(Error, FAC_IFACE, "Got unexpected command response char."); } while(resp == 'B'); // keep asking for more as long as we don't get the 'E' or something else (indicating out of sync). + +#ifdef USE_LED_DISPLAY if(0 not_eq m_pDisplay) m_pDisplay->showPercentage(written); +#endif } // sendFile @@ -298,10 +312,12 @@ void Interface::handler(void) } // handler +#ifdef USE_LED_DISPLAY void Interface::setMaxDisplay(Max7219 *pDisplay) { m_pDisplay = pDisplay; } // setMaxDisplay +#endif void Interface::handleATNCmdCodeOpen(IEC::ATNCmd& cmd) @@ -435,8 +451,11 @@ void Interface::handleATNCmdClose() serCmdIOBuf[len] = '\0'; strcpy((char*)scrollBuffer, " LOADED: "); strcat((char*)scrollBuffer, serCmdIOBuf); + +#ifdef USE_LED_DISPLAY if(0 not_eq m_pDisplay) m_pDisplay->resetScrollText(scrollBuffer); +#endif } else { diff --git a/uno2iec/interface.h b/uno2iec/interface.h index 91e6319..a3483a5 100755 --- a/uno2iec/interface.h +++ b/uno2iec/interface.h @@ -2,7 +2,9 @@ #define INTERFACE_H #include "IEC_driver.h" +#ifdef USE_LED_DISPLAY #include +#endif typedef enum { ErrOK, @@ -52,7 +54,10 @@ class Interface void handler(void); +#ifdef USE_LED_DISPLAY void setMaxDisplay(Max7219* pDisplay); +#endif + private: void reset(void); void saveFile(); @@ -78,7 +83,9 @@ class Interface // send listing pointer in basic memory: volatile word m_basicPtr; +#ifdef USE_LED_DISPLAY Max7219* m_pDisplay; +#endif }; #endif diff --git a/uno2iec/uno2iec.ino b/uno2iec/uno2iec.ino index 8c8bf32..f9972bf 100644 --- a/uno2iec/uno2iec.ino +++ b/uno2iec/uno2iec.ino @@ -1,9 +1,13 @@ #include "log.h" #include "iec_driver.h" #include "interface.h" -#include #include "global_defines.h" +#ifdef USE_LED_DISPLAY +#include +#endif + + #define DEFAULT_BAUD_RATE 57600 // Pin 13 has a LED connected on most Arduino boards. @@ -21,7 +25,11 @@ void waitForPeer(); // The global IEC handling singleton: IEC iec(8); Interface iface(iec); + +#ifdef USE_LED_DISPLAY Max7219* pMax; +#endif + static unsigned long lastMillis = 0; static unsigned long now; @@ -39,9 +47,11 @@ void setup() lastMillis = millis(); +#ifdef USE_LED_DISPLAY pMax = new Max7219(INPIN, LOADPIN, CLOCKPIN); pMax->resetScrollText(myText); iface.setMaxDisplay(pMax); +#endif } // setup @@ -54,11 +64,13 @@ void loop() iface.handler(); #endif +#ifdef USE_LED_DISPLAY now = millis(); if(now - lastMillis >= 50) { pMax->doScrollLeft(); lastMillis = now; } +#endif } // loop