From 2f64ad5efccf511e53f0e94de96865c3d0884b7e Mon Sep 17 00:00:00 2001 From: Starport75 Date: Wed, 14 Jun 2023 21:12:58 -0500 Subject: [PATCH] Almost working SPI --- include/LinkGPIO.h | 82 ++++++++++++++++++++++++++++++++++++++++ include/gameboy_colour.h | 6 ++- source/debug.cpp | 1 + source/main.cpp | 4 ++ 4 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 include/LinkGPIO.h diff --git a/include/LinkGPIO.h b/include/LinkGPIO.h new file mode 100644 index 0000000..ca97511 --- /dev/null +++ b/include/LinkGPIO.h @@ -0,0 +1,82 @@ +#ifndef LINK_GPIO_H +#define LINK_GPIO_H + +// -------------------------------------------------------------------------- +// A General Purpose Input-Output handler for the Link Port. +// -------------------------------------------------------------------------- +// Usage: +// - 1) Include this header in your main.cpp file and add: +// LinkGPIO* linkGPIO = new LinkGPIO(); +// - 2) Initialize the library with: +// linkGPIO->reset(); +// - 3) Write pins by using: +// linkGPIO->setMode(LinkGPIO::Pin::SD, LinkGPIO::Direction::OUTPUT); +// linkGPIO->writePin(LinkGPIO::Pin::SD, true); +// - 4) Read pins by using: +// linkGPIO->setMode(LinkGPIO::Pin::SC, LinkGPIO::Direction::INPUT); +// bool isHigh = linkGPIO->readPin(LinkGPIO::Pin::SC); +// - 5) Subscribe to SI falling: +// linkGPIO->setSIInterrupts(true); +// // (when SI changes from high to low, an IRQ will be generated) +// -------------------------------------------------------------------------- +// `setMode` restrictions: +// - always set the SI terminal to an input! +// -------------------------------------------------------------------------- + +#include + +#define LINK_GPIO_RCNT_GENERAL_PURPOSE (1 << 15) +#define LINK_GPIO_SIOCNT_GENERAL_PURPOSE 0 +#define LINK_GPIO_BIT_SI_INTERRUPT 8 +#define LINK_GPIO_GET(REG, BIT) ((REG >> BIT) & 1) +#define LINK_GPIO_SET(REG, BIT, DATA) \ + if (DATA) \ + LINK_GPIO_SET_HIGH(REG, BIT); \ + else \ + LINK_GPIO_SET_LOW(REG, BIT); +#define LINK_GPIO_SET_HIGH(REG, BIT) REG |= 1 << BIT +#define LINK_GPIO_SET_LOW(REG, BIT) REG &= ~(1 << BIT) + +static volatile char LINK_GPIO_VERSION[] = "LinkGPIO/v5.0.2"; + +const u8 LINK_GPIO_DATA_BITS[] = {2, 3, 1, 0}; +const u8 LINK_GPIO_DIRECTION_BITS[] = {6, 7, 5, 4}; + +class LinkGPIO { + public: + enum Pin { SI, SO, SD, SC }; + enum Direction { INPUT, OUTPUT }; + + void reset() { + REG_RCNT = LINK_GPIO_RCNT_GENERAL_PURPOSE; + REG_SIOCNT = LINK_GPIO_SIOCNT_GENERAL_PURPOSE; + } + + void setMode(Pin pin, Direction direction) { + if (pin == Pin::SI && Direction::OUTPUT) + return; // (disabled for safety reasons) + + LINK_GPIO_SET(REG_RCNT, LINK_GPIO_DIRECTION_BITS[pin], + direction == Direction::OUTPUT); + } + + Direction getMode(Pin pin) { + return Direction(LINK_GPIO_GET(REG_RCNT, LINK_GPIO_DIRECTION_BITS[pin])); + } + + bool readPin(Pin pin) { + return (REG_RCNT & (1 << LINK_GPIO_DATA_BITS[pin])) != 0; + } + + void writePin(Pin pin, bool isHigh) { + LINK_GPIO_SET(REG_RCNT, LINK_GPIO_DATA_BITS[pin], isHigh); + } + + void setSIInterrupts(bool isEnabled) { + LINK_GPIO_SET(REG_RCNT, LINK_GPIO_BIT_SI_INTERRUPT, isEnabled); + } +}; + +extern LinkGPIO* linkGPIO; + +#endif // LINK_GPIO_H diff --git a/include/gameboy_colour.h b/include/gameboy_colour.h index 60f21d8..1b528fb 100644 --- a/include/gameboy_colour.h +++ b/include/gameboy_colour.h @@ -4,7 +4,9 @@ #define GAMEBOY_COLOUR_H_ #include - +#include +#include "LinkGPIO.h" +/* #define LINK_SPI_NO_DATA 0xffffffff #define LINK_SPI_SIOCNT_NORMAL 0 #define LINK_SPI_BIT_CLOCK 0 @@ -20,11 +22,13 @@ #define LINK_SPI_SET_LOW(REG, BIT) REG &= ~(1 << BIT) #define LINK_SPI_SET(REG, BIT, VALUE) VALUE ? LINK_SPI_SET_HIGH(REG, BIT) : LINK_SPI_SET_LOW(REG, BIT) +*/ void setup(); byte handleIncomingByte(byte in); void transferBit(void); void loop(); +std::string outHexStr(vu8 inputNum); #endif /* GAMEBOY_COLOUR_H_ */ diff --git a/source/debug.cpp b/source/debug.cpp index 3040dc7..f5190fd 100644 --- a/source/debug.cpp +++ b/source/debug.cpp @@ -2,6 +2,7 @@ #include #include "mirror.h" #include "gba_flash.h" +#include "debug.h" char arr[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; diff --git a/source/main.cpp b/source/main.cpp index b970c4f..6929580 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -8,6 +8,7 @@ #include "LinkSPI.h" #include "gb_link.h" #include "gameboy_colour.h" +#include "LinkGPIO.h" // This file is autogenerated from the file in the graphics folder #include "metr.h" @@ -76,6 +77,9 @@ void load_sprite(void) int main(void) { + + linkGPIO->reset(); + REG_DISPCNT = DCNT_MODE0 | DCNT_BG0 | DCNT_OBJ | DCNT_OBJ_1D; tte_init_se_default(0, BG_CBB(0) | BG_SBB(31));