The first video game for the mbed video game console. The code utilizes the SimpleLib package developed by thomas@soete.org. For more information about the project and if you'd like to download the schematics and PCB design visit http://www.mbedgc.com/

Dependencies:   mbed

Committer:
jp
Date:
Sat Jul 09 15:47:27 2011 +0000
Revision:
0:31cd577d85a4
Initial release of Snake for the mbed Game Console.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jp 0:31cd577d85a4 1 /*
jp 0:31cd577d85a4 2 * Copyright or � or Copr. 2010, Thomas SOETE
jp 0:31cd577d85a4 3 *
jp 0:31cd577d85a4 4 * Author e-mail: thomas@soete.org
jp 0:31cd577d85a4 5 * Library website : http://mbed.org/users/Alkorin/libraries/SimpleLib/
jp 0:31cd577d85a4 6 *
jp 0:31cd577d85a4 7 * This software is governed by the CeCILL license under French law and
jp 0:31cd577d85a4 8 * abiding by the rules of distribution of free software. You can use,
jp 0:31cd577d85a4 9 * modify and/ or redistribute the software under the terms of the CeCILL
jp 0:31cd577d85a4 10 * license as circulated by CEA, CNRS and INRIA at the following URL
jp 0:31cd577d85a4 11 * "http://www.cecill.info".
jp 0:31cd577d85a4 12 *
jp 0:31cd577d85a4 13 * As a counterpart to the access to the source code and rights to copy,
jp 0:31cd577d85a4 14 * modify and redistribute granted by the license, users are provided only
jp 0:31cd577d85a4 15 * with a limited warranty and the software's author, the holder of the
jp 0:31cd577d85a4 16 * economic rights, and the successive licensors have only limited
jp 0:31cd577d85a4 17 * liability.
jp 0:31cd577d85a4 18 *
jp 0:31cd577d85a4 19 * In this respect, the user's attention is drawn to the risks associated
jp 0:31cd577d85a4 20 * with loading, using, modifying and/or developing or reproducing the
jp 0:31cd577d85a4 21 * software by the user in light of its specific status of free software,
jp 0:31cd577d85a4 22 * that may mean that it is complicated to manipulate, and that also
jp 0:31cd577d85a4 23 * therefore means that it is reserved for developers and experienced
jp 0:31cd577d85a4 24 * professionals having in-depth computer knowledge. Users are therefore
jp 0:31cd577d85a4 25 * encouraged to load and test the software's suitability as regards their
jp 0:31cd577d85a4 26 * requirements in conditions enabling the security of their systems and/or
jp 0:31cd577d85a4 27 * data to be ensured and, more generally, to use and operate it in the
jp 0:31cd577d85a4 28 * same conditions as regards security.
jp 0:31cd577d85a4 29 *
jp 0:31cd577d85a4 30 * The fact that you are presently reading this means that you have had
jp 0:31cd577d85a4 31 * knowledge of the CeCILL license and that you accept its terms.
jp 0:31cd577d85a4 32 */
jp 0:31cd577d85a4 33
jp 0:31cd577d85a4 34 #ifndef __SIMPLELIB_SERIAL_H__
jp 0:31cd577d85a4 35 #define __SIMPLELIB_SERIAL_H__
jp 0:31cd577d85a4 36
jp 0:31cd577d85a4 37 #include "mbed_globals.h"
jp 0:31cd577d85a4 38 #include "interrupts.h"
jp 0:31cd577d85a4 39
jp 0:31cd577d85a4 40 /**********************************
jp 0:31cd577d85a4 41 * Simple Serial Managment *
jp 0:31cd577d85a4 42 **********************************
jp 0:31cd577d85a4 43 * The interrupt handler is : *
jp 0:31cd577d85a4 44 * SERIAL_INTERRUPT_HANDLER(void) *
jp 0:31cd577d85a4 45 * UART0 : Serial over USB *
jp 0:31cd577d85a4 46 * UART1 : TX p13, RX p14 *
jp 0:31cd577d85a4 47 * UART2 : TX p28, RX p27 *
jp 0:31cd577d85a4 48 * UART3 : TX p9, RX p10 *
jp 0:31cd577d85a4 49 **********************************/
jp 0:31cd577d85a4 50
jp 0:31cd577d85a4 51 /** Registers **/
jp 0:31cd577d85a4 52 // Serial port (Choose UARTn (0,1,2,3))
jp 0:31cd577d85a4 53 #define UART_NUMBER UART0
jp 0:31cd577d85a4 54 #define UART_BASE TOKENPASTE2(LPC_,UART_NUMBER)
jp 0:31cd577d85a4 55
jp 0:31cd577d85a4 56 // Peripheral Clock Selection registers (See 4.7.3 p56)
jp 0:31cd577d85a4 57 #define UART0_PCLK_REG (LPC_SC->PCLKSEL0)
jp 0:31cd577d85a4 58 #define UART1_PCLK_REG (LPC_SC->PCLKSEL0)
jp 0:31cd577d85a4 59 #define UART2_PCLK_REG (LPC_SC->PCLKSEL1)
jp 0:31cd577d85a4 60 #define UART3_PCLK_REG (LPC_SC->PCLKSEL1)
jp 0:31cd577d85a4 61 #define UART_PCLK_REG TOKENPASTE2(UART_NUMBER,_PCLK_REG)
jp 0:31cd577d85a4 62
jp 0:31cd577d85a4 63 #define UART0_PCLK_OFFSET 6
jp 0:31cd577d85a4 64 #define UART1_PCLK_OFFSET 8
jp 0:31cd577d85a4 65 #define UART2_PCLK_OFFSET 16
jp 0:31cd577d85a4 66 #define UART3_PCLK_OFFSET 18
jp 0:31cd577d85a4 67 #define UART_PCLK_OFFSET TOKENPASTE2(UART_NUMBER,_PCLK_OFFSET)
jp 0:31cd577d85a4 68
jp 0:31cd577d85a4 69 #define UART0_PCLK ((LPC_SC->PCLKSEL0 >> 6) & 0x03)
jp 0:31cd577d85a4 70 #define UART1_PCLK ((LPC_SC->PCLKSEL0 >> 8) & 0x03)
jp 0:31cd577d85a4 71 #define UART2_PCLK ((LPC_SC->PCLKSEL1 >> 16) & 0x03)
jp 0:31cd577d85a4 72 #define UART3_PCLK ((LPC_SC->PCLKSEL1 >> 18) & 0x03)
jp 0:31cd577d85a4 73 #define UART_PCLK TOKENPASTE2(UART_NUMBER,_PCLK)
jp 0:31cd577d85a4 74
jp 0:31cd577d85a4 75 // Pin Function Select register (See 8.5.1-8 p108)
jp 0:31cd577d85a4 76 #define UART0RX_PINSEL_REG (LPC_PINCON->PINSEL0)
jp 0:31cd577d85a4 77 #define UART1RX_PINSEL_REG (LPC_PINCON->PINSEL1)
jp 0:31cd577d85a4 78 #define UART2RX_PINSEL_REG (LPC_PINCON->PINSEL0)
jp 0:31cd577d85a4 79 #define UART3RX_PINSEL_REG (LPC_PINCON->PINSEL0)
jp 0:31cd577d85a4 80 #define UARTRX_PINSEL_REG TOKENPASTE2(UART_NUMBER,RX_PINSEL_REG)
jp 0:31cd577d85a4 81
jp 0:31cd577d85a4 82 #define UART0TX_PINSEL_REG (LPC_PINCON->PINSEL0)
jp 0:31cd577d85a4 83 #define UART1TX_PINSEL_REG (LPC_PINCON->PINSEL0)
jp 0:31cd577d85a4 84 #define UART2TX_PINSEL_REG (LPC_PINCON->PINSEL0)
jp 0:31cd577d85a4 85 #define UART3TX_PINSEL_REG (LPC_PINCON->PINSEL0)
jp 0:31cd577d85a4 86 #define UARTTX_PINSEL_REG TOKENPASTE2(UART_NUMBER,TX_PINSEL_REG)
jp 0:31cd577d85a4 87
jp 0:31cd577d85a4 88 #define UART0RX_PINSEL_OFFSET 6
jp 0:31cd577d85a4 89 #define UART1RX_PINSEL_OFFSET 0
jp 0:31cd577d85a4 90 #define UART2RX_PINSEL_OFFSET 22
jp 0:31cd577d85a4 91 #define UART3RX_PINSEL_OFFSET 2
jp 0:31cd577d85a4 92 #define UARTRX_PINSEL_OFFSET TOKENPASTE2(UART_NUMBER,RX_PINSEL_OFFSET)
jp 0:31cd577d85a4 93
jp 0:31cd577d85a4 94 #define UART0TX_PINSEL_OFFSET 4
jp 0:31cd577d85a4 95 #define UART1TX_PINSEL_OFFSET 30
jp 0:31cd577d85a4 96 #define UART2TX_PINSEL_OFFSET 20
jp 0:31cd577d85a4 97 #define UART3TX_PINSEL_OFFSET 0
jp 0:31cd577d85a4 98 #define UARTTX_PINSEL_OFFSET TOKENPASTE2(UART_NUMBER,TX_PINSEL_OFFSET)
jp 0:31cd577d85a4 99
jp 0:31cd577d85a4 100 #define UART0_PINSEL_VALUE 1U
jp 0:31cd577d85a4 101 #define UART1_PINSEL_VALUE 1U
jp 0:31cd577d85a4 102 #define UART2_PINSEL_VALUE 1U
jp 0:31cd577d85a4 103 #define UART3_PINSEL_VALUE 2U
jp 0:31cd577d85a4 104 #define UART_PINSEL_VALUE TOKENPASTE2(UART_NUMBER,_PINSEL_VALUE)
jp 0:31cd577d85a4 105
jp 0:31cd577d85a4 106 /** Interrupt handlers **/
jp 0:31cd577d85a4 107 #define SERIAL_INTERRUPT_HANDLER EXTERN_C void __IRQ TOKENPASTE2(UART_NUMBER,_IRQHandler)
jp 0:31cd577d85a4 108
jp 0:31cd577d85a4 109 /** Bits **/
jp 0:31cd577d85a4 110 // RBR Interrupt Enable (UnIER, 14.4.4 p302)
jp 0:31cd577d85a4 111 #define RBR_INT_BIT 0
jp 0:31cd577d85a4 112 // Receiver Data Ready (UnLSR, 14.4.8 p306)
jp 0:31cd577d85a4 113 #define RDR_BIT 0
jp 0:31cd577d85a4 114 // Transmitter Holding Register Empty (UnLSR, 14.4.8 p306)
jp 0:31cd577d85a4 115 #define THRE_BIT 5
jp 0:31cd577d85a4 116 // RBR Interrupt Enable (UnIER, 14.4.4 p302)
jp 0:31cd577d85a4 117 #define SERIAL_INT_RX 1
jp 0:31cd577d85a4 118 // THRE Interrupt Enable (UnIER, 14.4.4 p302)
jp 0:31cd577d85a4 119 #define SERIAL_INT_TX 2
jp 0:31cd577d85a4 120 // Divisor Latch Access Bit (UnLCR, 14.4.7 p306)
jp 0:31cd577d85a4 121 #define DLA_BIT 7
jp 0:31cd577d85a4 122 // Power Control for Peripherals (PCONP, 4.8.7.1 p63)
jp 0:31cd577d85a4 123 #define UART0_PCONP_BIT 3
jp 0:31cd577d85a4 124 #define UART1_PCONP_BIT 4
jp 0:31cd577d85a4 125 #define UART2_PCONP_BIT 24
jp 0:31cd577d85a4 126 #define UART3_PCONP_BIT 25
jp 0:31cd577d85a4 127
jp 0:31cd577d85a4 128 /** Macros **/
jp 0:31cd577d85a4 129 #define SERIAL_PUTCHAR(c) do { \
jp 0:31cd577d85a4 130 while (GET_BIT_VALUE(UART_BASE->LSR, THRE_BIT) == 0); \
jp 0:31cd577d85a4 131 UART_BASE->THR = c; \
jp 0:31cd577d85a4 132 } while(0)
jp 0:31cd577d85a4 133
jp 0:31cd577d85a4 134 #define SERIAL_DATA_TO_READ() (GET_BIT_VALUE(UART_BASE->LSR, RDR_BIT) == 1)
jp 0:31cd577d85a4 135
jp 0:31cd577d85a4 136 #define SERIAL_GETCHAR() (UART_BASE->RBR)
jp 0:31cd577d85a4 137
jp 0:31cd577d85a4 138 // Enable interrupt for RX or TX (SERIAL_INT_RX and SERIAL_INT_TX)
jp 0:31cd577d85a4 139 #define SERIAL_ENABLE_INTERRUPT(value) do { \
jp 0:31cd577d85a4 140 UART_BASE->IER = value; \
jp 0:31cd577d85a4 141 ENABLE_INTERRUPT(TOKENPASTE2(UART_NUMBER,_IRQn)); \
jp 0:31cd577d85a4 142 } while(0)
jp 0:31cd577d85a4 143
jp 0:31cd577d85a4 144 extern __INLINE void SERIAL_INIT()
jp 0:31cd577d85a4 145 {
jp 0:31cd577d85a4 146 // Enable UARTn
jp 0:31cd577d85a4 147 SET_BIT_VALUE(LPC_SC->PCONP, TOKENPASTE2(UART_NUMBER,_PCONP_BIT) , 1);
jp 0:31cd577d85a4 148 // Enable FIFO and reset RX/TX FIFO (See 14.4.6 p305)
jp 0:31cd577d85a4 149 UART_BASE->FCR = 0x07;
jp 0:31cd577d85a4 150 // 8-bits, No Parity, 1 stop bit (See 14.4.7 p306)
jp 0:31cd577d85a4 151 UART_BASE->LCR = 0x03;
jp 0:31cd577d85a4 152 // Set CCLK as Peripheral Clock for UART (96MHz with mbed library)
jp 0:31cd577d85a4 153 UART_PCLK_REG = (UART_PCLK_REG & (~(3UL << UART_PCLK_OFFSET))) | (1U << UART_PCLK_OFFSET);
jp 0:31cd577d85a4 154 // Define Pin's functions as UART
jp 0:31cd577d85a4 155 UARTRX_PINSEL_REG = (UARTRX_PINSEL_REG & (~(3U << UARTRX_PINSEL_OFFSET))) | (UART_PINSEL_VALUE << UARTRX_PINSEL_OFFSET);
jp 0:31cd577d85a4 156 UARTTX_PINSEL_REG = (UARTTX_PINSEL_REG & (~(3U << UARTTX_PINSEL_OFFSET))) | (UART_PINSEL_VALUE << UARTTX_PINSEL_OFFSET);
jp 0:31cd577d85a4 157 }
jp 0:31cd577d85a4 158
jp 0:31cd577d85a4 159 // See 14.4.5 p303
jp 0:31cd577d85a4 160 extern __INLINE int SERIAL_CHECK_INTERRUPT(void) {
jp 0:31cd577d85a4 161 uint32_t serialStatus = UART_BASE->IIR;
jp 0:31cd577d85a4 162
jp 0:31cd577d85a4 163 if (serialStatus & 1) // IntStatus, 1 = No Interrupt is pending.
jp 0:31cd577d85a4 164 return 0;
jp 0:31cd577d85a4 165
jp 0:31cd577d85a4 166 serialStatus = (serialStatus >> 1) & 0x3; // IntId, 2 = More than threshold data to read, 6 = Some caracters to read
jp 0:31cd577d85a4 167 if (serialStatus != 2 && serialStatus != 6)
jp 0:31cd577d85a4 168 return 0;
jp 0:31cd577d85a4 169
jp 0:31cd577d85a4 170 return 1;
jp 0:31cd577d85a4 171 }
jp 0:31cd577d85a4 172
jp 0:31cd577d85a4 173 extern __INLINE void SERIAL_SETBAUD(unsigned int baud) {
jp 0:31cd577d85a4 174 // Peripheral Clock Selection register bit values (See Table 42, p57)
jp 0:31cd577d85a4 175 uint16_t divisorValue = (SystemCoreClock / 16 / baud);
jp 0:31cd577d85a4 176 #if 0
jp 0:31cd577d85a4 177 // Peripheral Clock for UART is set to CCLK in SERIAL_INIT. Divisor is then 1.
jp 0:31cd577d85a4 178 // Else, use code below
jp 0:31cd577d85a4 179 static int divisors[4] = { 4, 1, 2, 8 };
jp 0:31cd577d85a4 180 uint16_t divisorValue = ((SystemCoreClock / 16 / baud) / divisors[UART_PCLK]);
jp 0:31cd577d85a4 181 #endif
jp 0:31cd577d85a4 182
jp 0:31cd577d85a4 183 UART_BASE->LCR |= (1 << DLA_BIT);
jp 0:31cd577d85a4 184 UART_BASE->DLM = (uint8_t) (divisorValue >> 8);
jp 0:31cd577d85a4 185 UART_BASE->DLL = (uint8_t) divisorValue;
jp 0:31cd577d85a4 186 UART_BASE->LCR &= ~(1 << DLA_BIT);
jp 0:31cd577d85a4 187 }
jp 0:31cd577d85a4 188
jp 0:31cd577d85a4 189 #endif