diff --git a/Firmware/Hub-Mega2560/Hub-Mega2560.ino b/Firmware/Hub-Mega2560/Hub-Mega2560.ino index a156778..94f0e65 100644 --- a/Firmware/Hub-Mega2560/Hub-Mega2560.ino +++ b/Firmware/Hub-Mega2560/Hub-Mega2560.ino @@ -72,7 +72,7 @@ char urlVer[] = "http://8bit-unity.com/Hub-Version.txt"; const char* cmdString[] = {"SYS_ERROR","SYS_RESET","SYS_NOTIF", "SYS_SCAN", "SYS_CONNECT","SYS_IP", "SYS_MOUSE","SYS_VERSION","SYS_UPDATE","", "DIR_LS", "DIR_MK", "DIR_RM", "DIR_CD", "", "", "", "", "", "", - "FILE_OPEN","FILE_SEEK","FILE_READ", "FILE_WRITE","FILE_CLOSE", "", "", "", "", "", + "", "FILE_OPEN","FILE_SEEK", "FILE_READ", "FILE_WRITE", "FILE_CLOSE","", "", "", "", "UDP_OPEN", "UDP_RECV", "UDP_SEND", "UDP_CLOSE", "UDP_SLOT", "", "", "", "", "", "TCP_OPEN", "TCP_RECV", "TCP_SEND", "TCP_CLOSE", "TCP_SLOT", "", "", "", "", "", "WEB_OPEN", "WEB_RECV", "WEB_HEADER","WEB_BODY", "WEB_SEND", "WEB_CLOSE","", "", "", "", @@ -93,9 +93,12 @@ const char* fail = "Update failed! "; #define MODE_C64 4 #define MODE_NES 5 #define MODE_ORIC 6 -#define MODE_LYNX 7 -#define HUB_MODES 8 -const char* modeString[HUB_MODES] = {"Please setup", "Apple //", "Atari 8bit", "BBC Micro", "C64/C128", "NES", "Oric", "Lynx"}; +#define MODE_LYNXOLD 7 +#define MODE_LYNXNEW 8 +#define HUB_MODES 9 +const char* modeString[HUB_MODES] = { + "Please setup", "Apple //", "Atari 8bit", "BBC Micro", "C64/C128", "NES", "Oric", + "Lynx(old)", "Lynx(new)"}; byte hubMode = MODE_NONE; // COMM Params @@ -550,6 +553,10 @@ volatile unsigned long interruptTimer = 0; unsigned long timerIO = millis(); #endif +// For Lynx(new), we use two interfaces and name them according to function +#define LynxSerialRecv Serial1 +#define LynxSerialSend Serial2 + void setupCOM() { // Setup COM Connection switch (hubMode) { @@ -572,7 +579,7 @@ void setupCOM() { PORTH &= ~_BV(PH1); // Pin 16 LOW == READY attachInterrupt(digitalPinToInterrupt(18), c64Interrupt, FALLING); break; - case MODE_LYNX: + case MODE_LYNXOLD: // Setup Serial 2 on pins 16/17 Serial2.begin(62500, SERIAL_8N2); // Lynx comm (Bauds 62500, 41666, 9600) while (!Serial2) { } @@ -580,6 +587,18 @@ void setupCOM() { Serial2.flush(); Serial2.readString(); break; + case MODE_LYNXNEW: + // Issue with parity: + // In the hub code on the lynx, parity for receiving is checked! + // But the Lynx cannot create correct parity. + // The code here cannot use different setting for send and recv in one interface + // Thus we need two to make it workin hardware + LynxSerialRecv.begin(62500, SERIAL_8N2); // recv // Lynx comm (Bauds 62500, 41666, 9600) + LynxSerialSend.begin(62500, SERIAL_8O1); // send // Lynx comm (Bauds 62500, 41666, 9600) + LynxSerialRecv.setTimeout(30); + LynxSerialSend.flush(); + LynxSerialRecv.readString();// why need readstring? + break; case MODE_NES: pinMode(18, INPUT_PULLUP); // STROBE (PC) pinMode(16, INPUT_PULLUP); // R/W STATE @@ -851,26 +870,26 @@ void c64Interrupt() { } //////////////////////////////// -// LYNX Communication // +// LYNX Communication (old) // //////////////////////////////// unsigned char lynxBitPeriod = 16; // Bauds: 62500=16 / 41666=24 / 9600=104 unsigned long lynxTimer; -void lynxOutputMode(void) { +void lynxOldOutputMode(void) { // Switch pin to output PORTD |= B00000100; DDRD |= B00000100; - lynxTimer = micros(); + lynxTimer = micros(); while (micros()-lynxTimer < lynxBitPeriod); } -void lynxInputMode(void) { +void lynxOldInputMode(void) { // Switch pin to input DDRD &= B11111011; } -void lynxWrite(char value) { +void lynxOldWrite(char value) { unsigned char i, parity = 0, mask = 1; // Start Bit @@ -904,13 +923,13 @@ void lynxWrite(char value) { } } -void lynxProcessCOM() { +void lynxOldProcessCOM() { // Have we got data? if (!Serial2.available()) { comCode = COM_ERR_NODATA; return; } // Get Header if (!Serial2.readBytes((unsigned char*)&comInHeader, 1)) { comCode = COM_ERR_HEADER; return; } - #ifdef __DEBUG_IO__ + #ifdef __DEBUG_IO__ inRec++; #endif @@ -919,7 +938,7 @@ void lynxProcessCOM() { // Get Command if (!Serial2.readBytes((unsigned char*)&comInCMD, 1)) { comCode = COM_ERR_TRUNCAT; return; } - #ifdef __DEBUG_IO__ + #ifdef __DEBUG_IO__ inRec++; #endif @@ -927,7 +946,7 @@ void lynxProcessCOM() { if (comInHeader == 85) { // Get RecvID if (!Serial2.readBytes((unsigned char*)&comInID, 1)) { comCode = COM_ERR_TRUNCAT; return; } - #ifdef __DEBUG_IO__ + #ifdef __DEBUG_IO__ inRec++; #endif @@ -937,49 +956,145 @@ void lynxProcessCOM() { // Send DATA //delayMicroseconds(6*lynxBitPeriod); // Bauds: 62500=6* / 41666=8* / 9600=2* - lynxOutputMode(); + lynxOldOutputMode(); for (unsigned char i=0; i255){ + // printf("Buffer length exceeded!"); + break; + } + memcpy(&serBuffer[length], entry.name(), slen); + length += slen; + serBuffer[length++] = 0; + serBuffer[length++] = (unsigned char)(entry.size() & 0xff); + serBuffer[length++] = (unsigned char)((entry.size() >> 8)&0xff); + count++; + } + } + + entry.close(); + } + dir.close(); + serBuffer[0] = count; + serLen = length; + } + + pushPacket(HUB_DIR_LS, -1); + break; + case HUB_FILE_OPEN: // Check if file was previously opened if (hubFile[comInBuffer[0]]) @@ -1418,7 +1577,7 @@ void comProcessCMD() { // Send back file size length = hubFile[comInBuffer[0]].size(); memcpy(serBuffer, (char*)&length, 4); serLen = 4; - pushPacket(HUB_FILE_OPEN, comInBuffer[0]); + pushPacket(HUB_FILE_OPEN, -1); break; case HUB_FILE_SEEK: @@ -2493,9 +2652,13 @@ void loop() { espProcessCMD(); // Process COM I/O - if (hubMode == MODE_LYNX) { + if (hubMode == MODE_LYNXOLD) { + // Process Lynx Communication (asynchronously) + lynxOldProcessCOM(); + } else + if (hubMode == MODE_LYNXNEW) { // Process Lynx Communication (asynchronously) - lynxProcessCOM(); + lynxNewProcessCOM(); } else if (hubMode == MODE_ATARI || hubMode == MODE_C64 || hubMode == MODE_NES || hubMode == MODE_ORIC) { // Check if data burst stalled (allow extra time for VBI/DLI interrupts)