Part 5: Appliance Control with The Link Port

The Link Port may be used in one of four different modes. One of these modes is UART (Universal Asynchronous Receiver/Transmitter) which converts the link port into a standard serial port using the RS-232 serial communication protocol. Below is a table of the physical layout of the port:

Colour Pin# Pin Name UART Role Voltage (logic 1)
1 VCC
Red 2 SO SerialOut Tx 3.31V
Orange 3 SI SerialIn Rx 3.31V
Brown 4 SD SerialData RTS 3.31V
Green 5 SC SerialClock CTS 3.31V
Blue 6 GND

GBA official link cable. Taken from http://www.robmeerman.co.uk/project/gba.

In order to simplify access to the serial port using the devkitPro toolchain include the following statement at the beginning of your code:

#include <gba_sio.h>

The following are handy definitions you can include in your code in order to simplify the UART configuration of the GBA's Link Port:

//---------------------------------------------------------------------------------
// definitions and global variables
//---------------------------------------------------------------------------------
#define SIO_9600    0x0000
#define SIO_38400   0x0001
#define SIO_57600   0x0002
#define SIO_115200  0x0003
#define SIO_DL8     0x0080
#define SIO_TXE     0x0400
#define SIO_RXE     0x0800
#define SIO_TXF     0x0010
#define SIO_RXF     0x0020
#define SIO_ERF     0x0040
#define SIO_CTS     0x0004
#define SIO_UART    0x3000

Below is a sample UART Initialization routine for the Link Port:

//---------------------------------------------------------------------------------
void InitUART(word BAUD) {
//---------------------------------------------------------------------------------

    /**********************  UART Mode ******************************

                                 R R R
    F E D C  B A 9 8  7 6 5 4  3 2 1 0
    X I M M  U T A F  L E R S  P C B B

    0-1 (B) = Baud rate [00=9600,01=38400,10=57600,11=115200]
    2   (C) = CTS Flag (0 - Send always, 1- Send only when SC = LOW)
    3   (P) = Parity Control (0 - Even, 1 - Odd)
    4   (S) = Send Data Flag (0 - Not full, 1 - Full)
    5   (R) = Receive Data Flag (0 - Not empty, 1 - Empty)
    6   (E) = Error (1 on error)
    7   (L) = Data Length (0 - 7 bits, 1 - 8 bits)
    8   (F) = FIFO Enable Flag
    9   (A) = Parity Enable Flag
    10  (T) = Send Enable Flag
    11  (U) = Receieve Enable Flag
    C-D (M) = Comm Mode [8bit=00,32bit=01,Multiplayer=10,UART=11]
    E   (I) = Interrupt (0 - Disable, 1 - IRQ when bits 4,5, or 6 become set)
    ****************************************************************/

    // UART: enable send, receive & interrupt, 8 bits, no parity @9600bps
    //REG_SIOCNT=SIO_UART + SIO_TXE + SIO_RXE + SIO_IRQ + SIO_DL8 + SIO_NOPAR + SIO_9600;

    // The user should only be choosing the speed

    // Stick a character in the data register. This stops the GBA from transmitting a character as soon as it goes into UART mode (?!?)
    REG_SIODATA8 = 'A';

    // Now to go into UART mode
    REG_RCNT = 0;       // General IO (REG_BASE + 0x128)
    REG_SIOCNT = 0;     // Serial control (REG_BASE + 0x134)
    REG_SIOCNT = BAUD | /*SIO_CTS |*/ SIO_DL8 | SIO_TXE | SIO_RXE | SIO_UART;

    // Set the receive data flag to empty (ready to receive)
    REG_SIOCNT = REG_SIOCNT | SIO_RXF;

    // With any luck, we should now be able to talk to a PC.

}

Finally, we have the receiving and transmitting routines:

//---------------------------------------------------------------------------------
void UART_TX(byte CHAR) {
//---------------------------------------------------------------------------------
    while(REG_SIOCNT & SIO_TXF);    // Wait for empty transmit buffer
    REG_SIODATA8 = CHAR;            // Bung your byte into the data register
}

//---------------------------------------------------------------------------------
byte UART_RX() {
//---------------------------------------------------------------------------------
    char c;
    // We're using CTS so we must send a LO on the SD terminal to show we're ready
    //REG_RCNT = REG_RCNT & (0x0020 ^ 0xFFFF);

    // Wait until we have a full byte (The recv data flag will go to 0)
    //while(REG_SIOCNT & SIO_RXF);

    c = REG_SIODATA8;   // Read the character in the data register

    // Set the receive data flag to empty (ready to receive)
    REG_SIOCNT = REG_SIOCNT | SIO_RXF;

    return c;       // Return the character in the data register
}

You can also check Robert Meerman's pages (http://www.robmeerman.co.uk/project/gba) where you cah find full details and code for implementing a USB PC data link.

<< Part 4: The ARM Memory Map
Back to OpenEADL Tutorials