From b28059d49afce8524361fa7597adcc9e108f4eab Mon Sep 17 00:00:00 2001 From: Xavi Del Campo Date: Tue, 3 Mar 2020 18:10:15 +0100 Subject: Renamed folders to lowercase --- src/Serial.c | 278 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 src/Serial.c (limited to 'src/Serial.c') diff --git a/src/Serial.c b/src/Serial.c new file mode 100644 index 0000000..2e2a1a4 --- /dev/null +++ b/src/Serial.c @@ -0,0 +1,278 @@ +/* ************************************* + * Includes + * *************************************/ + +#include "Serial.h" + +/* ************************************* + * Defines + * *************************************/ + +#define SERIAL_BAUDRATE 115200 +#define SERIAL_TX_RX_TIMEOUT 20000 +#define SERIAL_RX_FIFO_EMPTY 0 +#define SERIAL_TX_NOT_READY 0 + +/* ************************************* + * Local Variables + * *************************************/ + +static volatile SERIAL_STATE SerialState; +static volatile size_t bytesRead; +static volatile uint32_t initPC_Address; +static volatile uint32_t RAMDest_Address; +static volatile size_t ExeSize; +static volatile size_t totalBytes; +static volatile size_t exeBytesRead; +static volatile bool serial_busy; + +/* ************************************* + * Local Prototypes + * *************************************/ + +void ISR_Serial(void) +{ + enum + { + SERIAL_BG_X0 = 0, + SERIAL_BG_X1 = X_SCREEN_RESOLUTION - SERIAL_BG_X0, + SERIAL_BG_X2 = SERIAL_BG_X0, + SERIAL_BG_X3 = SERIAL_BG_X1, + + SERIAL_BG_Y0 = 0, + SERIAL_BG_Y1 = SERIAL_BG_Y0, + SERIAL_BG_Y2 = Y_SCREEN_RESOLUTION - SERIAL_BG_Y0, + SERIAL_BG_Y3 = SERIAL_BG_Y2, + + SERIAL_BG_R = 0, + SERIAL_BG_G = NORMAL_LUMINANCE, + SERIAL_BG_B = NORMAL_LUMINANCE, + }; + + static GsGPoly4 SerialBg = { .x[0] = SERIAL_BG_X0, + .x[1] = SERIAL_BG_X1, + .x[2] = SERIAL_BG_X2, + .x[3] = SERIAL_BG_X3, + + .y[0] = SERIAL_BG_Y0, + .y[1] = SERIAL_BG_Y1, + .y[2] = SERIAL_BG_Y2, + .y[3] = SERIAL_BG_Y3, + + .r[0] = 0, + .r[1] = 0, + .r[2] = SERIAL_BG_R, + .r[3] = SERIAL_BG_R, + + .g[0] = 0, + .g[1] = 0, + .g[2] = SERIAL_BG_G, + .g[3] = SERIAL_BG_G, + + .b[0] = 0, + .b[1] = 0, + .b[2] = SERIAL_BG_B, + .b[3] = SERIAL_BG_B, }; + + enum + { + SERIAL_STATE_TEXT_X = 148, + SERIAL_STATE_TEXT_Y = Y_SCREEN_RESOLUTION >> 1, + }; + + SystemIncreaseGlobalTimer(); + + if( (GfxIsGPUBusy() == true) || (SystemIsBusy() == true) ) + { + return; + } + + FontSetFlags(&SmallFont, FONT_BLEND_EFFECT | FONT_H_CENTERED); + + if(SerialState == SERIAL_STATE_READING_EXE_DATA) + { + if(System1SecondTick() == false) + { + return; + } + else + { + FontSetFlags(&SmallFont, FONT_H_CENTERED); + } + } + + GsSortGPoly4(&SerialBg); + + switch(SerialState) + { + case SERIAL_STATE_INIT: + FontPrintText(&SmallFont, SERIAL_STATE_TEXT_X, SERIAL_STATE_TEXT_Y, "Serial initialization"); + break; + + case SERIAL_STATE_STANDBY: + FontPrintText(&SmallFont, SERIAL_STATE_TEXT_X, SERIAL_STATE_TEXT_Y, "Waiting for PC..."); + break; + + case SERIAL_STATE_WRITING_ACK: + FontPrintText(&SmallFont, SERIAL_STATE_TEXT_X, SERIAL_STATE_TEXT_Y, "Writing ACK"); + break; + + case SERIAL_STATE_READING_HEADER: + FontPrintText(&SmallFont, SERIAL_STATE_TEXT_X, SERIAL_STATE_TEXT_Y, "Reading data from header (%d/%d bytes)...", bytesRead, totalBytes); + break; + + case SERIAL_STATE_READING_EXE_SIZE: + FontPrintText(&SmallFont, SERIAL_STATE_TEXT_X, SERIAL_STATE_TEXT_Y, "Getting PSX-EXE size from PC..."); + break; + + case SERIAL_STATE_READING_EXE_DATA: + FontPrintText(&SmallFont, SERIAL_STATE_TEXT_X, SERIAL_STATE_TEXT_Y, "Reading PSX-EXE data (%d/%d bytes)...", exeBytesRead, ExeSize); + break; + + case SERIAL_STATE_WAITING_USER_INPUT: + FontPrintText(&SmallFont, SERIAL_STATE_TEXT_X, SERIAL_STATE_TEXT_Y, "Press any key to continue"); + break; + + case SERIAL_STATE_CLEANING_MEMORY: + FontPrintText(&SmallFont, SERIAL_STATE_TEXT_X, SERIAL_STATE_TEXT_Y, "Cleaning RAM before EXE data transfer..."); + break; + + default: + FontPrintText(&SmallFont, SERIAL_STATE_TEXT_X, SERIAL_STATE_TEXT_Y, "Unknown state"); + break; + } + + FontSetFlags(&SmallFont, FONT_H_CENTERED); + + if(RAMDest_Address != 0) + { + FontPrintText(&SmallFont, SERIAL_STATE_TEXT_X, SERIAL_STATE_TEXT_Y + 16, "RAM Dest address: 0x%08X", RAMDest_Address); + } + + if(initPC_Address != 0) + { + FontPrintText(&SmallFont, SERIAL_STATE_TEXT_X, SERIAL_STATE_TEXT_Y + 32, "Init PC address: 0x%08X", initPC_Address); + } + + if(ExeSize != 0) + { + FontPrintText(&SmallFont, SERIAL_STATE_TEXT_X, SERIAL_STATE_TEXT_Y + 48, "PSX-EXE size: 0x%08X", ExeSize); + } + + GfxDrawScene_Fast(); +} + +void SerialSetState(SERIAL_STATE state) +{ + SerialState = state; +} + +void SerialSetPCAddress(uint32_t addr) +{ + initPC_Address = addr; +} + +void SerialSetRAMDestAddress(uint32_t addr) +{ + RAMDest_Address = addr; +} + +void SerialSetExeSize(size_t size) +{ + ExeSize = size; +} + +void SerialInit(void) +{ + uint8_t receivedBytes; + + SetVBlankHandler(&ISR_Serial); + + SerialState = SERIAL_STATE_INIT; + + SIOStart(SERIAL_BAUDRATE); + + SerialState = SERIAL_STATE_STANDBY; + + // ------------------------------------ + // Protocol description + // ------------------------------------ + + // 1. Wait to receive magic byte "99" from PC. + + SerialRead(&receivedBytes, sizeof(uint8_t) ); + + if(receivedBytes != 99) + { + dprintf("Did not receive input magic number!\n"); + return; + } + + // 2. Send ACK (magic byte is ASCII code for 'b'). + + SerialState = SERIAL_STATE_WRITING_ACK; + + SerialWrite(ACK_BYTE_STRING, sizeof(uint8_t) ); +} + +void SerialSetExeBytesReceived(uint32_t bytes_read) +{ + exeBytesRead += bytes_read; +} + +bool SerialRead(uint8_t* ptrArray, size_t nBytes) +{ + bytesRead = 0; + totalBytes = nBytes; + + serial_busy = true; + + if(nBytes == 0) + { + SerialWrite("SerialRead: invalid size %d\n", strnlen("SerialRead: invalid size %d\n", 30)); + return false; + } + + do + { + //uint16_t timeout = SERIAL_TX_RX_TIMEOUT; + + while( (SIOCheckInBuffer() == SERIAL_RX_FIFO_EMPTY)); // Wait for RX FIFO not empty + + *(ptrArray++) = SIOReadByte(); + bytesRead++; + }while(--nBytes); + + serial_busy = false; + + return true; +} + +bool SerialWrite(void* ptrArray, size_t nBytes) +{ + serial_busy = true; + + SystemDisableVBlankInterrupt(); + + if(nBytes == 0) + { + SerialWrite("SerialRead: invalid size %d\n", strnlen("SerialRead: invalid size %d\n", 30)); + return false; + } + + do + { + //uint16_t timeout = SERIAL_TX_RX_TIMEOUT; + + while( (SIOCheckOutBuffer() == SERIAL_TX_NOT_READY)); // Wait for TX FIFO empty. + + SIOSendByte(*(uint8_t*)ptrArray++); + + }while(--nBytes); + + SystemEnableVBlankInterrupt(); + + serial_busy = false; + + return true; +} -- cgit v1.2.3