From ec123fffde444fb2898c72ce7ad1947e4bada135 Mon Sep 17 00:00:00 2001 From: barret Date: Wed, 22 Jan 2025 17:01:33 -0700 Subject: [PATCH] working? --- src/H8300.cpp | 310 ++++++++++++++++++++++++++++++++++++++++++++++-- src/H8300.h | 18 ++- src/NDSCart.cpp | 33 +----- 3 files changed, 316 insertions(+), 45 deletions(-) diff --git a/src/H8300.cpp b/src/H8300.cpp index aa241863..b985e196 100644 --- a/src/H8300.cpp +++ b/src/H8300.cpp @@ -6,14 +6,21 @@ #include "H8300.h" #include #include "types.h" +#include +#include +#include +#include +#include + + + H8300::H8300(){ printf("H8/300 has been created"); + //debugSerialPort(); } H8300::~H8300(){ - printf("H8/300 has been killed"); - } void H8300::speak(){ @@ -21,10 +28,259 @@ void H8300::speak(){ } +//This should be called dynamically?? +int H8300::configureSerialPort(){ + + + memset(buf, 0, sizeof(buf)); + //This should be configures in options + const char *portname = "/dev/ttyUSB0"; + + //sudo chmod 666 /dev/ttyUSB0 + fd = open(portname, O_RDWR | O_NOCTTY | O_NDELAY); + if (fd == -1){ + printf("H8/300 failed to open the serial port\n"); + return 1; + } + + struct termios options; + tcgetattr(fd, &options); + + //Set walker params. We can potentially make this different if we want to talk to walker EMUS + + + //baud rate + cfsetispeed(&options, B115200); + cfsetospeed(&options, B115200); + + + //no parity, 1 stop bit, clear char size mask, 8 data bits, no hardware flow ctrl, + // enable reciever, ignore modem control lines + options.c_cflag &= ~PARENB; + options.c_cflag &= ~CSTOPB; + options.c_cflag &= ~CSIZE; + options.c_cflag |= CS8; + options.c_cflag &= ~CRTSCTS; + options.c_cflag |= CREAD | CLOCAL; + + +// options.c_cc[VTIME] = 1; +// options.c_cc[VMIN] = 0; + + + tcflush(fd, TCIFLUSH); + tcsetattr(fd, TCSANOW, &options); + + if (tcgetattr(fd, &options) == -1){ + printf("H8/300 failed to configure the serial port\n"); + close(fd); + return 1; + } + return 0; +} + + + +int H8300::readSerialPort(){ + + //needs to be done this way so we dont have spliced packets. 4ms of no comms indicates eof. Try to ignore and just wait till there are no packets + + + + /* WORKING BETTER*/ + char tempBuf[0xB8]; + int len = 1; //read(fd, tempBuf, sizeof(tempBuf)); + u8 pointer = 0; + while (len > 0){ + usleep(4000); + len = read(fd, tempBuf, sizeof(tempBuf)); + + if (len < 0) break; + + for(int i = 0; i < len; i++){ + + buf[pointer + i] = tempBuf[i]; + + } + pointer = pointer + len; + } + recvLen = pointer; + + if (recvLen == 0) return 0; + + + printf("\nrecieved a packet of len: %d\n", recvLen); + + for (int i = 0; i < recvLen; i++){ + printf("0x%02x ", (u8)buf[i] ^ 0xaa); + } + printf("\n"); + + + return recvLen; + +/* + printf("trying to recieve\n"); + struct timeval tv; + gettimeofday(&tv, NULL); + long lastRxTime = tv.tv_usec; + + + char tempBuf[0xB8]; + int len = read(fd, tempBuf, sizeof(tempBuf)); + u8 pointer = 0; + + if (len > 0){ + printf("we are rxing a packer"); + //We are now recieving a packet + long cond = tv.tv_usec - lastRxTime; + while(cond < 3500){ + cond = tv.tv_usec - lastRxTime; + gettimeofday(&tv, NULL); + + len = read(fd, tempBuf, sizeof(tempBuf)); + + if (len < 0) continue; + else{ + lastRxTime = tv.tv_usec; + for(int i = 0; i < len; i++){ + buf[pointer + i] = tempBuf[i]; + } + pointer = pointer + len; + } + + } + } + + recvLen = pointer; + + if (recvLen == 0) return 0; + + + printf("\nrecieved a packet of len: %d\n", recvLen); + + for (int i = 0; i < recvLen; i++){ + printf("0x%02x ", (u8)buf[i] ^ 0xaa); + } + printf("\n"); + + + return recvLen; + + +*/ +} + +int H8300::sendSerialPort(){ + + + tcflush(fd, TCIFLUSH); + + + //printf("Send packet requested\n"); + printf("\n Sending %d Bytes: %d", sendLen); + /* + for (int i = 0; i < sendLen; i++){ + + printf("0x%02x ", (u8)sendBuf[i] ^ 0xaa); + + } + printf("\n");*/ + u8 written = write(fd, sendBuf, sendLen); + + //printf("wrote %d bytes\n", written); + +// getchar(); + + + return 0; +} + + + +int H8300::debugSerialPort(){ + + + int option = 0; + while(option != 9){ + + printf("\n\nWelcome to the mini H8/300 Debugger. Please select an option.\n"); + printf("1. Read\n"); + printf("2. Write\n"); + printf("3. FD status\n"); + printf("4. Configure Serial Port\n"); + printf("5. Close serial port\n"); + printf("8. Exit without closing port\n"); + printf("9. Exit and close serial port\n"); + scanf("%d", &option); + + if (option ==1){ + //printf("You have 5 seconds to send me some data!!!\n"); + //sleep(5); + + memset(buf, 0, sizeof(buf)); + int len = -1; + + while (len < 0){ + + len = read(fd, buf, sizeof(buf)); + } + + printf("Rxed %d bytes\n", len); + + for (int i = 0; i < len; i++){ + printf("0x%02x ", (unsigned char)buf[i]); + } + printf("\n"); + } + + else if (option == 2){ + printf("writing not implemented\n"); + } + else if (option == 3){ + + printf("FD status: %d\n", fd); + } + + else if (option == 4){ + configureSerialPort(); + } + else if (option == 5){ + close(fd); + printf("hopefully closed fd\n"); + } + + else if (option == 8){ + break; + } + + else if (option == 9){ + close(fd); + printf("Exiting.\n"); + break; + } + } + return 0; +} + + + + + + + + + //A botched implementation u8 H8300::handleSPI(u8& IRCmd, u8& val, u32&pos, bool& last){ - printf("IRCmd: %d val:%d pos: %ld last: %d\n", IRCmd, val, pos, last); + // readSerialPort(); + + + + + + // printf("IRCmd: %d val:%02x pos: %ld last: %d\n", IRCmd, val, pos, last); switch (IRCmd) { case 0x00: // pass-through @@ -33,21 +289,51 @@ u8 H8300::handleSPI(u8& IRCmd, u8& val, u32&pos, bool& last){ case 0x01: - u8 rtnval; + + if (pos == 0){ + return 0x00; + } if (pos == 1){ - rtnval = 0x01; - } - if (pos == 2){ - rtnval = 0x56; - } - printf(" returning: 0x%02x val: %d pos: %ld last: %d\n", rtnval, val, pos, last); - return rtnval; + recvLen = readSerialPort(); +// printf(" pos 1: found %d bytes\n", recvLen); + return recvLen; + } + else{ + u8 data = (unsigned char)buf[pos-2]; + // printf(" pos: %02x, last: %d, dgettimeofday(&tv, NULL);ata: 0x%02x \n", pos, last, data); + return data; + } + return 0x00; + case 0x02: + //printf(" press any key to continue."); + //getchar(); + + if (pos == 0){ + + // memset(buf, 0, sizeof(buf)); //we can clear our read buffer because we are sending now. (make easier) + // recvLen = 0; + + } + else{ + sendBuf[pos-1] = val; //Load the spi packet into the buffer; + } + + if (last == 1){ + sendLen = pos; + sendSerialPort(); + } + return 0x00; case 0x08: // ID + if (fd <0){ + printf("Configuring port during IR init sequence\n"); + configureSerialPort(); + } + return 0xAA; } - printf("Unhandled: %d val:%d pos: %ld last: %d\n", IRCmd, val, pos, last); +// printf("Unhandled: %d val:%d pos: %ld last: %d\n", IRCmd, val, pos, last); return 0x00; } diff --git a/src/H8300.h b/src/H8300.h index c5f0a070..0eb6f1d6 100644 --- a/src/H8300.h +++ b/src/H8300.h @@ -23,8 +23,24 @@ public: u8 handleSPI(u8& IRCmd, u8& val, u32&pos, bool& last); + + //TODO add options later + int configureSerialPort(); + int debugSerialPort(); + int readSerialPort(); + int sendSerialPort(); + private: - int exampleInt; + int sessionStatus = 0; + //file where the TTY will be stores + int fd = -1; + + u8 recvLen = 0; + char buf[0xB8]; + + + char sendBuf[0xB8]; + u8 sendLen; }; #endif diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index d87a06a8..ffb55775 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -1129,48 +1129,17 @@ u8 CartRetailIR::SPIWrite(u8 val, u32 pos, bool last) //Kind of like an init sequence, we only really care about commands after this first one if (pos == 0) { -// printf("IRCmd: %d val:%d pos: %ld last: %d\n", val, val, pos, last); IRCmd = val; return 0; } - // TODO: emulate actual IR comm if (IRCmd == 0){ return CartRetail::SPIWrite(val, pos-1, last); - } - + //Yay I am doing the TODO :) Thanks to the giants that came before me! else{ return IRChip.handleSPI(IRCmd, val, pos, last); - } - - - /* - switch (IRCmd) - { - case 0x00: // pass-through - return CartRetail::SPIWrite(val, pos-1, last); - - - case 0xaa: - u8 rtnval; - if (pos == 1){ - rtnval = 0x01; - } - if (pos == 2){ - rtnval = 0x56; - } - printf(" returning: 0x%02x val: %d pos: %ld last: %d\n", rtnval, val, pos, last); - return rtnval; - - - case 0x08: // ID - return 0xAA; - } - return IRChip.handleSPI(val, pos,last); - //printf(" Unhandled Case: val: 0x%02x\n", val); - //return 0;*/ } //BARRET END CHANGES CartRetailBT::CartRetailBT(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr&& sram, u32 sramlen, void* userdata) :