summaryrefslogtreecommitdiff
path: root/src/Serial.c
diff options
context:
space:
mode:
authorXavi Del Campo <xavi.dcr@tutanota.com>2020-03-03 18:10:15 +0100
committerXavi Del Campo <xavi.dcr@tutanota.com>2020-03-03 18:10:27 +0100
commitb28059d49afce8524361fa7597adcc9e108f4eab (patch)
tree5041d37aa9571ac738ced4b9f16388550d0e8f78 /src/Serial.c
parentbf3bb8cdc590a18195e25c38f4f4db11e8bcd1c4 (diff)
downloadopensend-b28059d49afce8524361fa7597adcc9e108f4eab.tar.gz
Renamed folders to lowercase
Diffstat (limited to 'src/Serial.c')
-rw-r--r--src/Serial.c278
1 files changed, 278 insertions, 0 deletions
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;
+}