GameBoy Advance Multiboot & RPC

Dependencies:   mbed-rpc mbed

Files at this revision

API Documentation at this revision

Comitter:
akkera102
Date:
Tue Dec 09 08:58:06 2014 +0000
Commit message:
GameBoy Advance Multiboot & Dumper

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
mbed-rpc.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
multiboot.cpp Show annotated file Show diff for this revision Revisions of this file
multiboot.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 147f4cedc929 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Dec 09 08:58:06 2014 +0000
@@ -0,0 +1,78 @@
+#include "main.h"
+#include "mbed_rpc.h"
+#include "multiboot.h"
+
+static Serial pc(USBTX, USBRX);
+
+int main(void)
+{
+    if(MultiBoot("/local/test.gba") == 1)
+    {
+        SystemError("MultiBoot", 1);
+    }
+
+    RpcDigitalOut myled1(LED1, "myled1");
+    RpcDigitalOut myled2(LED2, "myled2");
+
+    int var = 0;
+    RPCVariable<int> _var(&var, "var");
+
+    uint32_t r, cnt;
+    char buf[256], outbuf[256];
+ 
+    pc.printf("RPC GBA start\n");
+
+    for(;;)
+    {
+        WaitSPI32(0x0, 0x00010000, "Wait start signature");
+
+        outbuf[0] = '\0';
+        cnt = 0;
+
+        while((r = WriteSPI32NoDebug(0x0)) != 0x00020000)
+        {
+            *(uint32_t*)(&buf[cnt]) = r;
+            cnt += 4;
+        }
+
+        RPC::call(buf, outbuf);
+        pc.printf("buf:[%s]\n", buf);
+        pc.printf("out:[%s]\n", outbuf);
+
+        if(IsReadVariable(buf) == true)
+        {
+            WriteSPI32NoDebug(atoi(outbuf));
+        }
+    }
+}
+
+bool IsReadVariable(const char* request)
+{
+    if(request == NULL)
+    {
+        return false;
+    }
+
+    Arguments args(request);
+
+    if(args.obj_name == NULL || args.method_name == NULL)
+    {
+        return false;
+    }
+    if(strcmp(args.method_name, "read") != 0)
+    {
+        return false;
+    }
+
+    return true;
+}
+
+void SystemError(char* str, uint32_t hex)
+{
+    pc.printf("[Err][0x%x] %s\n", hex, str);
+
+    for(;;)
+    {
+        wait(1);
+    }
+}
diff -r 000000000000 -r 147f4cedc929 main.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.h	Tue Dec 09 08:58:06 2014 +0000
@@ -0,0 +1,9 @@
+#ifndef MAIN_H
+#define MAIN_H
+ 
+#include "mbed.h"
+
+bool IsReadVariable(const char* request);
+void SystemError(char* str, uint32_t hex);
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r 147f4cedc929 mbed-rpc.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rpc.lib	Tue Dec 09 08:58:06 2014 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/okini3939/code/mbed-rpc/#ddd4f57351e2
diff -r 000000000000 -r 147f4cedc929 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Dec 09 08:58:06 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/031413cf7a89
\ No newline at end of file
diff -r 000000000000 -r 147f4cedc929 multiboot.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multiboot.cpp	Tue Dec 09 08:58:06 2014 +0000
@@ -0,0 +1,171 @@
+//  mbed GBA Loader - Boot up a GameBoy Advance using Multiboot (no cart req.)
+//  
+//  Ken Kaarvik    kkaarvik@yahoo.com    Nov 13, 2010
+//  akkera102                            Nov 08, 2014(modified)
+//
+//  mbed(LPC1768)   gba serial port(color)
+//  p1-0V           6-GND (blue)
+//  p5-mosi         3-SI  (orange)
+//  p6-miso         2-SO  (red)
+//  p7-sck          5-SC  (green)
+//
+//  The GBA file that you wish to load into the GBA is stored on the mbed's local file system.
+//  Apply power to the mbed (or reset) before turning on the GBA.
+
+#include "multiboot.h"
+
+static LocalFileSystem local("local");
+static Serial pc(USBTX, USBRX);
+static SPI spi(p5, p6, p7);
+
+
+uint32_t WriteSPI32(uint32_t w, char* msg)
+{
+    uint32_t r = WriteSPI32NoDebug(w);
+
+    pc.printf("0x%08x 0x%08x  ; %s\n",r , w, msg);
+    return  r;
+}
+
+uint32_t WriteSPI32NoDebug(uint32_t w)
+{
+    uint16_t w1 = w >> 16;
+    uint16_t w2 = w & 0xffff;
+
+    uint32_t r;
+    r = spi.write(w1) << 16;
+    r = spi.write(w2) | r;
+    
+    return r;
+}
+
+void WaitSPI32(uint32_t w, uint32_t comp, char* msg)
+{
+    pc.printf("%s 0x%08x\n", msg, comp);
+    uint32_t r;
+
+    do
+    {
+        r = WriteSPI32NoDebug(w);
+        wait(0.01);
+
+    } while(r != comp);
+}
+
+int MultiBoot(char* filename) 
+{
+    spi.format(16, 3);
+    spi.frequency(100000); // 100 kHz
+
+
+    FILE *fp = fopen(filename, "rb");
+    if(fp == NULL)
+    {
+        pc.printf("Err: Can't open file\n");
+        return 1;
+    }
+
+    fseek(fp, 0L, SEEK_END);
+    long fsize = (ftell(fp) + 0x0f) & 0xfffffff0;
+
+    if(fsize > 0x40000)
+    {
+        pc.printf("Err: Max file size 256kB\n");
+        return 1;
+    }
+
+    fseek(fp, 0L, SEEK_SET);
+    long fcnt = 0;
+
+
+    uint32_t r, w, w2;
+    int i, bit;
+
+    WaitSPI32(0x00006202, 0x72026202, "Looking for GBA");
+
+    r = WriteSPI32(0x00006202, "Found GBA");
+    r = WriteSPI32(0x00006102, "Recognition OK");
+
+    pc.printf("Send Header(NoDebug)\n");
+    for(i=0; i<=0x5f; i++)
+    {
+        w = getc(fp);
+        w = getc(fp) << 8 | w;
+        fcnt += 2;
+
+        r = WriteSPI32NoDebug(w);
+    }
+
+    r = WriteSPI32(0x00006200, "Transfer of header data complete");
+    r = WriteSPI32(0x00006202, "Exchange master/slave info again");
+
+    r = WriteSPI32(0x000063d1, "Send palette data");
+    r = WriteSPI32(0x000063d1, "Send palette data, receive 0x73hh****");  
+
+    uint32_t m = ((r & 0x00ff0000) >>  8) + 0xffff00d1;
+    uint32_t h = ((r & 0x00ff0000) >> 16) + 0xf;
+
+    r = WriteSPI32((((r >> 16) + 0xf) & 0xff) | 0x00006400, "Send handshake data");
+    r = WriteSPI32((fsize - 0x190) / 4, "Send length info, receive seed 0x**cc****");
+
+    uint32_t f = (((r & 0x00ff0000) >> 8) + h) | 0xffff0000;
+    uint32_t c = 0x0000c387;
+
+
+    pc.printf("Send encrypted data(NoDebug)\n");
+
+    while(fcnt < fsize)
+    {
+        w = getc(fp);
+        w = getc(fp) <<  8 | w;
+        w = getc(fp) << 16 | w;
+        w = getc(fp) << 24 | w;
+
+        w2 = w;
+
+        for(bit=0; bit<32; bit++)
+        {
+            if((c ^ w) & 0x01)
+            {
+                c = (c >> 1) ^ 0x0000c37b;
+            }
+            else
+            {
+                c = c >> 1;
+            }
+
+            w = w >> 1;
+        }
+
+        m = (0x6f646573 * m) + 1;
+        WriteSPI32NoDebug(w2 ^ ((~(0x02000000 + fcnt)) + 1) ^m ^0x43202f2f);
+
+        fcnt = fcnt + 4;
+    }
+    fclose(fp);
+
+
+    for(bit=0; bit<32; bit++)
+    {
+        if((c ^ f) & 0x01)
+        {
+            c =( c >> 1) ^ 0x0000c37b;
+        }
+        else
+        {
+            c = c >> 1;
+        }
+
+        f = f >> 1;
+    }
+
+    WaitSPI32(0x00000065, 0x00750065, "Wait for GBA to respond with CRC");
+
+    r = WriteSPI32(0x00000066, "GBA ready with CRC");
+    r = WriteSPI32(c,          "Let's exchange CRC!");
+
+    pc.printf("CRC ...hope they match!\n");
+    pc.printf("MulitBoot done\n");
+
+    return 0;
+}
diff -r 000000000000 -r 147f4cedc929 multiboot.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multiboot.h	Tue Dec 09 08:58:06 2014 +0000
@@ -0,0 +1,13 @@
+#ifndef MULTIBOOT_H
+#define MULTIBOOT_H
+ 
+#include "mbed.h"
+
+uint32_t WriteSPI32(uint32_t w, char* msg);
+uint32_t WriteSPI32NoDebug(uint32_t w);
+void     WaitSPI32(uint32_t w, uint32_t comp, char* msg);
+
+int      MultiBoot(char* filename);
+
+
+#endif