aboutsummaryrefslogtreecommitdiffstats
path: root/boards
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2014-07-09 18:47:59 +1000
committerinmarket <andrewh@inmarket.com.au>2014-07-09 18:47:59 +1000
commit6dea259ea2dd0afc4b610961e211d77460cfd0c6 (patch)
tree225a157a5ac0c7cf8d4e1b451b47075a57e3110b /boards
parentab9ce99647965d0d3e9ea65ea92ad694c8b8ee1b (diff)
downloaduGFX-6dea259ea2dd0afc4b610961e211d77460cfd0c6.tar.gz
uGFX-6dea259ea2dd0afc4b610961e211d77460cfd0c6.tar.bz2
uGFX-6dea259ea2dd0afc4b610961e211d77460cfd0c6.zip
Example added for FreeRTOS on Raspberry Pi
Diffstat (limited to 'boards')
-rw-r--r--boards/base/RaspberryPi/example-FreeRTOS/Drivers/bcm2835_intc.h45
-rw-r--r--boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.c134
-rw-r--r--boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.h48
-rw-r--r--boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.c166
-rw-r--r--boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.h25
-rw-r--r--boards/base/RaspberryPi/example-FreeRTOS/Drivers/mmio.h24
-rw-r--r--boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.c125
-rw-r--r--boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.h25
-rw-r--r--boards/base/RaspberryPi/example-FreeRTOS/FreeRTOSConfig.h139
-rw-r--r--boards/base/RaspberryPi/example-FreeRTOS/Makefile73
-rw-r--r--boards/base/RaspberryPi/example-FreeRTOS/main.c82
-rw-r--r--boards/base/RaspberryPi/example-FreeRTOS/raspberrypi.ld70
-rw-r--r--boards/base/RaspberryPi/example-FreeRTOS/startup.s102
13 files changed, 1058 insertions, 0 deletions
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/bcm2835_intc.h b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/bcm2835_intc.h
new file mode 100644
index 00000000..9f87b88e
--- /dev/null
+++ b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/bcm2835_intc.h
@@ -0,0 +1,45 @@
+#ifndef _BCM2835_INTC_H_
+#define _BCM2835_INTC_H_
+
+//#include "bcm2835.h"
+
+#define BCM2835_INTC_TOTAL_IRQ 64 + 8
+
+#define BCM2835_BASE_INTC (0x2000B200)
+#define BCM2835_INTC_IRQ_BASIC (BCM2835_BASE_INTC + 0x00)
+#define BCM2835_IRQ_PENDING1 (BCM2835_BASE_INTC + 0x04)
+#define BCM2835_IRQ_PENDING2 (BCM2835_BASE_INTC + 0x08)
+#define BCM2835_IRQ_FIQ_CTRL (BCM2835_BASE_INTC + 0x0C)
+#define BCM2835_IRQ_ENABLE1 (BCM2835_BASE_INTC + 0x10)
+#define BCM2835_IRQ_ENABLE2 (BCM2835_BASE_INTC + 0x14)
+#define BCM2835_IRQ_ENABLE_BASIC (BCM2835_BASE_INTC + 0x18)
+#define BCM2835_IRQ_DISABLE1 (BCM2835_BASE_INTC + 0x1C)
+#define BCM2835_IRQ_DISABLE2 (BCM2835_BASE_INTC + 0x20)
+#define BCM2835_IRQ_DISABLE_BASIC (BCM2835_BASE_INTC + 0x24)
+
+
+
+
+#define BCM2835_IRQ_ID_AUX 29
+#define BCM2835_IRQ_ID_SPI_SLAVE 43
+#define BCM2835_IRQ_ID_PWA0 45
+#define BCM2835_IRQ_ID_PWA1 46
+#define BCM2835_IRQ_ID_SMI 48
+#define BCM2835_IRQ_ID_GPIO_0 49
+#define BCM2835_IRQ_ID_GPIO_1 50
+#define BCM2835_IRQ_ID_GPIO_2 51
+#define BCM2835_IRQ_ID_GPIO_3 52
+#define BCM2835_IRQ_ID_I2C 53
+#define BCM2835_IRQ_ID_SPI 54
+#define BCM2835_IRQ_ID_PCM 55
+#define BCM2835_IRQ_ID_UART 57
+
+
+#define BCM2835_IRQ_ID_TIMER_0 64
+#define BCM2835_IRQ_ID_MAILBOX_0 65
+#define BCM2835_IRQ_ID_DOORBELL_0 66
+#define BCM2835_IRQ_ID_DOORBELL_1 67
+#define BCM2835_IRQ_ID_GPU0_HALTED 68
+
+
+#endif
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.c b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.c
new file mode 100644
index 00000000..485de897
--- /dev/null
+++ b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.c
@@ -0,0 +1,134 @@
+/**
+ * Quick and very Dirty GPIO API.
+ *
+ **/
+
+#include "gpio.h"
+
+typedef struct {
+ unsigned long GPFSEL[6]; ///< Function selection registers.
+ unsigned long Reserved_1;
+ unsigned long GPSET[2];
+ unsigned long Reserved_2;
+ unsigned long GPCLR[2];
+ unsigned long Reserved_3;
+ unsigned long GPLEV[2];
+ unsigned long Reserved_4;
+ unsigned long GPEDS[2];
+ unsigned long Reserved_5;
+ unsigned long GPREN[2];
+ unsigned long Reserved_6;
+ unsigned long GPFEN[2];
+ unsigned long Reserved_7;
+ unsigned long GPHEN[2];
+ unsigned long Reserved_8;
+ unsigned long GPLEN[2];
+ unsigned long Reserved_9;
+ unsigned long GPAREN[2];
+ unsigned long Reserved_A;
+ unsigned long GPAFEN[2];
+ unsigned long Reserved_B;
+ unsigned long GPPUD[1];
+ unsigned long GPPUDCLK[2];
+ //Ignoring the reserved and test bytes
+} BCM2835_GPIO_REGS;
+
+volatile BCM2835_GPIO_REGS * const pRegs = (BCM2835_GPIO_REGS *) (0x20200000);
+
+
+void SetGpioFunction(unsigned int pinNum, unsigned int funcNum) {
+
+ int offset = pinNum / 10;
+
+ unsigned long val = pRegs->GPFSEL[offset]; // Read in the original register value.
+
+ int item = pinNum % 10;
+ val &= ~(0x7 << (item * 3));
+ val |= ((funcNum & 0x7) << (item * 3));
+ pRegs->GPFSEL[offset] = val;
+}
+
+void SetGpioDirection(unsigned int pinNum, enum GPIO_DIR dir) {
+ SetGpioFunction(pinNum,dir);
+}
+
+void SetGpio(unsigned int pinNum, unsigned int pinVal) {
+ unsigned long offset=pinNum/32;
+ unsigned long mask=(1<<(pinNum%32));
+
+ if(pinVal) {
+ pRegs->GPSET[offset]|=mask;
+ } else {
+ pRegs->GPCLR[offset]|=mask;
+ }
+}
+
+int ReadGpio(unsigned int pinNum) {
+ return ((pRegs->GPLEV[pinNum/32])>>(pinNum%32))&1;
+}
+
+void EnableGpioDetect(unsigned int pinNum, enum DETECT_TYPE type)
+{
+ unsigned long mask=(1<<pinNum);
+ unsigned long offset=pinNum/32;
+
+ switch(type) {
+ case DETECT_RISING:
+ pRegs->GPREN[offset]|=mask;
+ break;
+ case DETECT_FALLING:
+ pRegs->GPFEN[offset]|=mask;
+ break;
+ case DETECT_HIGH:
+ pRegs->GPHEN[offset]|=mask;
+ break;
+ case DETECT_LOW:
+ pRegs->GPLEN[offset]|=mask;
+ break;
+ case DETECT_RISING_ASYNC:
+ pRegs->GPAREN[offset]|=mask;
+ break;
+ case DETECT_FALLING_ASYNC:
+ pRegs->GPAFEN[offset]|=mask;
+ break;
+ case DETECT_NONE:
+ break;
+ }
+}
+
+void DisableGpioDetect(unsigned int pinNum, enum DETECT_TYPE type)
+{
+ unsigned long mask=~(1<<(pinNum%32));
+ unsigned long offset=pinNum/32;
+
+ switch(type) {
+ case DETECT_RISING:
+ pRegs->GPREN[offset]&=mask;
+ break;
+ case DETECT_FALLING:
+ pRegs->GPFEN[offset]&=mask;
+ break;
+ case DETECT_HIGH:
+ pRegs->GPHEN[offset]&=mask;
+ break;
+ case DETECT_LOW:
+ pRegs->GPLEN[offset]&=mask;
+ break;
+ case DETECT_RISING_ASYNC:
+ pRegs->GPAREN[offset]&=mask;
+ break;
+ case DETECT_FALLING_ASYNC:
+ pRegs->GPAFEN[offset]&=mask;
+ break;
+ case DETECT_NONE:
+ break;
+ }
+}
+
+void ClearGpioInterrupt(unsigned int pinNum)
+{
+ unsigned long mask=(1<<(pinNum%32));
+ unsigned long offset=pinNum/32;
+
+ pRegs->GPEDS[offset]=mask;
+}
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.h b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.h
new file mode 100644
index 00000000..fa459707
--- /dev/null
+++ b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.h
@@ -0,0 +1,48 @@
+#ifndef _GPIO_H_
+#define _GPIO_H_
+
+/* GPIO event detect types */
+enum DETECT_TYPE {
+ DETECT_NONE,
+ DETECT_RISING,
+ DETECT_FALLING,
+ DETECT_HIGH,
+ DETECT_LOW,
+ DETECT_RISING_ASYNC,
+ DETECT_FALLING_ASYNC
+};
+
+/* GPIO pull up or down states */
+enum PULL_STATE {
+ PULL_DISABLE,
+ PULL_UP,
+ PULL_DOWN,
+ PULL_RESERVED
+};
+
+/* Pin data direction */
+enum GPIO_DIR {
+ GPIO_IN,
+ GPIO_OUT
+};
+
+/* GPIO pin setup */
+void SetGpioFunction (unsigned int pinNum, unsigned int funcNum);
+/* A simple wrapper around SetGpioFunction */
+void SetGpioDirection (unsigned int pinNum, enum GPIO_DIR dir);
+
+/* Set GPIO output level */
+void SetGpio (unsigned int pinNum, unsigned int pinVal);
+
+/* Read GPIO pin level */
+int ReadGpio (unsigned int pinNum);
+
+/* GPIO pull up/down resistor control function (NOT YET IMPLEMENTED) */
+int PudGpio (unsigned int pinNum, enum PULL_STATE state);
+
+/* Interrupt related functions */
+void EnableGpioDetect (unsigned int pinNum, enum DETECT_TYPE type);
+void DisableGpioDetect (unsigned int pinNum, enum DETECT_TYPE type);
+void ClearGpioInterrupt (unsigned int pinNum);
+
+#endif
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.c b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.c
new file mode 100644
index 00000000..9908b7c4
--- /dev/null
+++ b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.c
@@ -0,0 +1,166 @@
+/**
+ * Integrated Interrupt Controller for RaspberryPi.
+ * @author James Walmsley <james@fullfat-fs.co.uk>
+ **/
+
+#include "interrupts.h"
+#include "bcm2835_intc.h"
+
+static INTERRUPT_VECTOR g_VectorTable[BCM2835_INTC_TOTAL_IRQ];
+
+
+typedef struct {
+ unsigned long IRQBasic; // Pending 0
+ unsigned long Pending1;
+ unsigned long Pending2;
+ unsigned long FIQCtrl;
+ unsigned long Enable1;
+ unsigned long Enable2;
+ unsigned long EnableBasic;
+ unsigned long Disable1;
+ unsigned long Disable2;
+ unsigned long DisableBasic;
+} BCM2835_INTC_REGS;
+
+static volatile BCM2835_INTC_REGS * const pRegs = (BCM2835_INTC_REGS *) (BCM2835_BASE_INTC);
+
+/**
+ * Enables all IRQ's in the CPU's CPSR register.
+ **/
+static void irqEnable() {
+ __asm volatile("mrs r0,cpsr"); // Read in the cpsr register.
+ __asm volatile("bic r0,r0,#0x80"); // Clear bit 8, (0x80) -- Causes IRQs to be enabled.
+ __asm volatile("msr cpsr_c, r0"); // Write it back to the CPSR register
+}
+
+static void irqDisable() {
+ __asm volatile("mrs r0,cpsr"); // Read in the cpsr register.
+ __asm volatile("orr r0,r0,#0x80"); // Set bit 8, (0x80) -- Causes IRQs to be disabled.
+ __asm volatile("msr cpsr_c, r0"); // Write it back to the CPSR register.
+
+}
+
+#define clz(a) \
+ ({ unsigned long __value, __arg = (a); \
+ asm ("clz\t%0, %1": "=r" (__value): "r" (__arg)); \
+ __value; })
+
+/**
+ * This is the global IRQ handler on this platform!
+ * It is based on the assembler code found in the Broadcom datasheet.
+ *
+ **/
+void irqHandler() {
+ register unsigned long ulMaskedStatus;
+ register unsigned long irqNumber;
+
+ ulMaskedStatus = pRegs->IRQBasic;
+
+ /* Bits 7 through 0 in IRQBasic represent interrupts 64-71 */
+ if (ulMaskedStatus & 0xFF) {
+ irqNumber=64 + 31;
+ }
+
+ /* Bit 8 in IRQBasic indicates interrupts in Pending1 (interrupts 31-0) */
+ else if(ulMaskedStatus & 0x100) {
+ ulMaskedStatus = pRegs->Pending1;
+ irqNumber = 0 + 31;
+ }
+
+ /* Bit 9 in IRQBasic indicates interrupts in Pending2 (interrupts 63-32) */
+ else if(ulMaskedStatus & 0x200) {
+ ulMaskedStatus = pRegs->Pending2;
+ irqNumber = 32 + 31;
+ }
+
+ else {
+ // No interrupt avaialbe, so just return.
+ return;
+ }
+
+ /* Keep only least significant bit, in case multiple interrupts have occured */
+ ulMaskedStatus&=-ulMaskedStatus;
+ /* Some magic to determine number of interrupt to serve */
+ irqNumber=irqNumber-clz(ulMaskedStatus);
+ /* Call interrupt handler */
+ g_VectorTable[irqNumber].pfnHandler(irqNumber, g_VectorTable[irqNumber].pParam);
+}
+
+
+static void stubHandler(int nIRQ, void *pParam) {
+ /**
+ * Actually if we get here, we should probably disable the IRQ,
+ * otherwise we could lock up this system, as there is nothing to
+ * ackknowledge the interrupt.
+ **/
+}
+
+int InitInterruptController() {
+ int i;
+ for(i = 0; i < BCM2835_INTC_TOTAL_IRQ; i++) {
+ g_VectorTable[i].pfnHandler = stubHandler;
+ g_VectorTable[i].pParam = (void *) 0;
+ }
+ return 0;
+}
+
+
+
+int RegisterInterrupt(int nIRQ, FN_INTERRUPT_HANDLER pfnHandler, void *pParam) {
+ if(nIRQ<0 || nIRQ>71)
+ return -1;
+
+ irqDisable();
+ {
+ g_VectorTable[nIRQ].pfnHandler = pfnHandler;
+ g_VectorTable[nIRQ].pParam = pParam;
+ }
+ irqEnable();
+ return 0;
+}
+
+int EnableInterrupt(int nIRQ) {
+ /* Datasheet says "All other bits are unaffected", and I'm counting on that. */
+ unsigned int mask=1<<(nIRQ%32);
+
+ if(nIRQ >=0 && nIRQ <=31) {
+ pRegs->Enable1 = mask;
+ } else
+ if(nIRQ >=32 && nIRQ <=63){
+ pRegs->Enable2 = mask;
+ } else
+ if(nIRQ >= 64 && nIRQ <= 71) { // Basic IRQ enables
+ pRegs->EnableBasic = mask;
+ } else
+ return -1;
+
+ return 0;
+}
+
+int DisableInterrupt(int nIRQ) {
+ /* Datasheet says "All other bits are unaffected", and I'm counting on that. */
+ unsigned int mask=1<<(nIRQ%32);
+
+ if(nIRQ >=0 && nIRQ <=31) {
+ pRegs->Disable1 = mask;
+ } else
+ if(nIRQ >=32 && nIRQ <=63){
+ pRegs->Disable2 = mask;
+ } else
+ if(nIRQ >= 64 && nIRQ <= 71) {
+ pRegs->DisableBasic = mask;
+ } else
+ return -1;
+
+ return 0;
+}
+
+int EnableInterrupts() {
+ irqEnable();
+ return 0;
+}
+
+int DisableInterrupts() {
+ irqDisable();
+ return 0;
+}
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.h b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.h
new file mode 100644
index 00000000..d09353a4
--- /dev/null
+++ b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.h
@@ -0,0 +1,25 @@
+/**
+ * Tiny Interrupt Manager
+ *
+ * @author James Walmsley <james@fullfat-fs.co.uk>
+ * This code is licensed under the GNU GPLv3 license.
+ **/
+
+#ifndef _INTERRUPTS_H_
+#define _INTERRUPTS_H_
+
+typedef void (*FN_INTERRUPT_HANDLER)(int nIRQ, void *pParam);
+
+typedef struct {
+ FN_INTERRUPT_HANDLER pfnHandler; ///< Function that handles this IRQn
+ void *pParam; ///< A special parameter that the use can pass to the IRQ.
+} INTERRUPT_VECTOR;
+
+int InitInterruptController ();
+int RegisterInterrupt (int nIRQ, FN_INTERRUPT_HANDLER pfnHandler, void *pParam);
+int EnableInterrupt (int nIRQ);
+int DisableInterrupt (int nIRQ);
+int EnableInterrupts ();
+int DisableInterrupts ();
+
+#endif
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/mmio.h b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/mmio.h
new file mode 100644
index 00000000..89bea700
--- /dev/null
+++ b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/mmio.h
@@ -0,0 +1,24 @@
+/* mmio.h - access to MMIO registers */
+
+#ifndef MMIO_H
+#define MMIO_H
+
+#include <stdint.h>
+
+// write to MMIO register
+static inline void mmio_write(uint32_t reg, uint32_t data) {
+ uint32_t *ptr = (uint32_t*)reg;
+ asm volatile("str %[data], [%[reg]]"
+ : : [reg]"r"(ptr), [data]"r"(data));
+}
+
+// read from MMIO register
+static inline uint32_t mmio_read(uint32_t reg) {
+ uint32_t *ptr = (uint32_t*)reg;
+ uint32_t data;
+ asm volatile("ldr %[data], [%[reg]]"
+ : [data]"=r"(data) : [reg]"r"(ptr));
+ return data;
+}
+
+#endif // #ifndef MMIO_H
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.c b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.c
new file mode 100644
index 00000000..92f837e7
--- /dev/null
+++ b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.c
@@ -0,0 +1,125 @@
+/* uart.c - UART initialization & communication */
+/* Reference material:
+ * http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
+ * Chapter 13: UART
+ */
+
+#include <stdint.h>
+#include <mmio.h>
+#include <uart.h>
+
+enum {
+ // The GPIO registers base address.
+ GPIO_BASE = 0x20200000,
+
+ // The offsets for reach register.
+
+ // Controls actuation of pull up/down to ALL GPIO pins.
+ GPPUD = (GPIO_BASE + 0x94),
+
+ // Controls actuation of pull up/down for specific GPIO pin.
+ GPPUDCLK0 = (GPIO_BASE + 0x98),
+
+ // The base address for UART.
+ UART0_BASE = 0x20201000,
+
+ // The offsets for reach register for the UART.
+ UART0_DR = (UART0_BASE + 0x00),
+ UART0_RSRECR = (UART0_BASE + 0x04),
+ UART0_FR = (UART0_BASE + 0x18),
+ UART0_ILPR = (UART0_BASE + 0x20),
+ UART0_IBRD = (UART0_BASE + 0x24),
+ UART0_FBRD = (UART0_BASE + 0x28),
+ UART0_LCRH = (UART0_BASE + 0x2C),
+ UART0_CR = (UART0_BASE + 0x30),
+ UART0_IFLS = (UART0_BASE + 0x34),
+ UART0_IMSC = (UART0_BASE + 0x38),
+ UART0_RIS = (UART0_BASE + 0x3C),
+ UART0_MIS = (UART0_BASE + 0x40),
+ UART0_ICR = (UART0_BASE + 0x44),
+ UART0_DMACR = (UART0_BASE + 0x48),
+ UART0_ITCR = (UART0_BASE + 0x80),
+ UART0_ITIP = (UART0_BASE + 0x84),
+ UART0_ITOP = (UART0_BASE + 0x88),
+ UART0_TDR = (UART0_BASE + 0x8C),
+};
+
+/*
+ * delay function
+ * int32_t delay: number of cycles to delay
+ *
+ * This just loops <delay> times in a way that the compiler
+ * wont optimize away.
+ */
+static void delay(int32_t count) {
+ asm volatile("__delay_%=: subs %[count], %[count], #1; bne __delay_%=\n"
+ : : [count]"r"(count) : "cc");
+}
+
+/*
+ * Initialize UART0.
+ */
+void uart_init() {
+ // Disable UART0.
+ mmio_write(UART0_CR, 0x00000000);
+ // Setup the GPIO pin 14 && 15.
+
+ // Disable pull up/down for all GPIO pins & delay for 150 cycles.
+ mmio_write(GPPUD, 0x00000000);
+ delay(150);
+
+ // Disable pull up/down for pin 14,15 & delay for 150 cycles.
+ mmio_write(GPPUDCLK0, (1 << 14) | (1 << 15));
+ delay(150);
+
+ // Write 0 to GPPUDCLK0 to make it take effect.
+ mmio_write(GPPUDCLK0, 0x00000000);
+
+ // Clear pending interrupts.
+ mmio_write(UART0_ICR, 0x7FF);
+
+ // Set integer & fractional part of baud rate.
+ // Divider = UART_CLOCK/(16 * Baud)
+ // Fraction part register = (Fractional part * 64) + 0.5
+ // UART_CLOCK = 3000000; Baud = 115200.
+
+ // Divider = 3000000/(16 * 115200) = 1.627 = ~1.
+ // Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40.
+ mmio_write(UART0_IBRD, 1);
+ mmio_write(UART0_FBRD, 40);
+
+ // Enable FIFO & 8 bit data transmissio (1 stop bit, no parity).
+ mmio_write(UART0_LCRH, (1 << 4) | (1 << 5) | (1 << 6));
+
+ // Mask all interrupts.
+ mmio_write(UART0_IMSC, (1 << 1) | (1 << 4) | (1 << 5) |
+ (1 << 6) | (1 << 7) | (1 << 8) |
+ (1 << 9) | (1 << 10));
+
+ // Enable UART0, receive & transfer part of UART.
+ mmio_write(UART0_CR, (1 << 0) | (1 << 8) | (1 << 9));
+}
+
+/*
+ * Transmit a byte via UART0.
+ * uint8_t Byte: byte to send.
+ */
+void uart_putc(uint8_t byte) {
+ // wait for UART to become ready to transmit
+ while (1) {
+ if (!(mmio_read(UART0_FR) & (1 << 5))) {
+ break;
+ }
+ }
+ mmio_write(UART0_DR, byte);
+}
+
+/*
+ * print a string to the UART one character at a time
+ * const char *str: 0-terminated string
+ */
+void uart_puts(const char *str) {
+ while (*str) {
+ uart_putc(*str++);
+ }
+}
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.h b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.h
new file mode 100644
index 00000000..fe7f64aa
--- /dev/null
+++ b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.h
@@ -0,0 +1,25 @@
+/* uart.h - UART initialization & communication */
+
+#ifndef UART_H
+#define UART_H
+
+#include <stdint.h>
+
+/*
+ * Initialize UART0.
+ */
+void uart_init();
+
+/*
+ * Transmit a byte via UART0.
+ * uint8_t Byte: byte to send.
+ */
+void uart_putc(uint8_t byte);
+
+/*
+ * print a string to the UART one character at a time
+ * const char *str: 0-terminated string
+ */
+void uart_puts(const char *str);
+
+#endif // #ifndef UART_H
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/FreeRTOSConfig.h b/boards/base/RaspberryPi/example-FreeRTOS/FreeRTOSConfig.h
new file mode 100644
index 00000000..c2477416
--- /dev/null
+++ b/boards/base/RaspberryPi/example-FreeRTOS/FreeRTOSConfig.h
@@ -0,0 +1,139 @@
+/*
+ FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
+ All rights reserved
+
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
+
+ ***************************************************************************
+ * *
+ * FreeRTOS provides completely free yet professionally developed, *
+ * robust, strictly quality controlled, supported, and cross *
+ * platform software that has become a de facto standard. *
+ * *
+ * Help yourself get started quickly and support the FreeRTOS *
+ * project by purchasing a FreeRTOS tutorial book, reference *
+ * manual, or both from: http://www.FreeRTOS.org/Documentation *
+ * *
+ * Thank you! *
+ * *
+ ***************************************************************************
+
+ This file is part of the FreeRTOS distribution.
+
+ FreeRTOS is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License (version 2) as published by the
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
+
+ >>! NOTE: The modification to the GPL is included to allow you to distribute
+ >>! a combined work that includes FreeRTOS without being obliged to provide
+ >>! the source code for proprietary components outside of the FreeRTOS
+ >>! kernel.
+
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. Full license text is available from the following
+ link: http://www.freertos.org/a00114.html
+
+ 1 tab == 4 spaces!
+
+ ***************************************************************************
+ * *
+ * Having a problem? Start by reading the FAQ "My application does *
+ * not run, what could be wrong?" *
+ * *
+ * http://www.FreeRTOS.org/FAQHelp.html *
+ * *
+ ***************************************************************************
+
+ http://www.FreeRTOS.org - Documentation, books, training, latest versions,
+ license and Real Time Engineers Ltd. contact details.
+
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.
+
+ http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
+ Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
+ licenses offer ticketed support, indemnification and middleware.
+
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety
+ engineered and independently SIL3 certified version for use in safety and
+ mission critical applications that require provable dependability.
+
+ 1 tab == 4 spaces!
+*/
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
+#define configCPU_CLOCK_HZ ( ( unsigned long ) 24000000 )
+#define configPERIPHERAL_CLOCK_HZ ( 40000000UL )
+#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
+#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
+#define configISR_STACK_SIZE ( 250 )
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 4096 ) )
+#define configMAX_TASK_NAME_LEN ( 16 )
+#define configUSE_TRACE_FACILITY 0
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_MUTEXES 1
+#define configCHECK_FOR_STACK_OVERFLOW 3
+#define configQUEUE_REGISTRY_SIZE 0
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_MALLOC_FAILED_HOOK 0
+#define configUSE_APPLICATION_TASK_TAG 1
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configGENERATE_RUN_TIME_STATS 0
+
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
+
+/* Set the following definitions to 1 to include the API function, or zero
+to exclude the API function. */
+
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskCleanUpResources 0
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 1
+#define INCLUDE_eTaskGetState 1
+
+
+/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255
+(lowest) to 0 (1?) (highest). */
+#define configKERNEL_INTERRUPT_PRIORITY 255
+/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
+See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */
+
+
+/* This is the value being used as per the ST library which permits 16
+priority values, 0 to 15. This must correspond to the
+configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest
+NVIC value of 255. */
+#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15
+
+#endif /* FREERTOS_CONFIG_H */
+
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Makefile b/boards/base/RaspberryPi/example-FreeRTOS/Makefile
new file mode 100644
index 00000000..c1751204
--- /dev/null
+++ b/boards/base/RaspberryPi/example-FreeRTOS/Makefile
@@ -0,0 +1,73 @@
+# build environment
+PREFIX ?= /your compiler path/gcc-arm-none-eabi-4_8-2014q1
+ARCH ?= $(PREFIX)/bin/arm-none-eabi
+
+CC = ${ARCH}-gcc
+CPP = ${ARCH}-g++
+AS = ${ARCH}-as
+LD = ${ARCH}-ld
+AR = ${ARCH}-ar
+OBJCOPY = ${ARCH}-objcopy
+
+PLATFORM = raspi
+LINKER_SCRIPT = raspberrypi.ld
+
+CFLAGS = -march=armv6z -g -Wall -Wextra
+ASFLAGS = -g
+
+CFLAGS_FOR_TARGET = #-mcpu=arm1176jzf-s
+ASFLAGS_FOR_TARGET = #-mcpu=arm1176jzf-s
+LDFLAGS = #--error-unresolved-symbols
+
+GFXLIB := ../uGFX
+include $(GFXLIB)/gfx.mk
+include $(GFXLIB)/drivers/gdisp/framebuffer/driver.mk
+
+OSLIB := ../FreeRTOS
+MODULES := $(OSLIB)/Source/portable/GCC/RaspberryPi
+MODULES += $(OSLIB)/Source/portable/MemMang
+MODULES += $(OSLIB)/Source
+MODULES += Drivers
+
+SRC_DIR := $(MODULES)
+INC_DIR := $(addsuffix /include,$(SRC_DIR))
+BUILD_DIR := $(addsuffix /build,$(SRC_DIR))
+
+INCLUDEDIRS := $(OSLIB)/Source/portable/GCC/RaspberryPi
+INCLUDEDIRS += $(OSLIB)/Source/include
+INCLUDEDIRS += Drivers
+INCLUDEDIRS += $(GFXINC)
+
+INCLUDES := $(addprefix -I,$(INCLUDEDIRS))
+
+ASRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.s))
+AOBJ := $(ASRC:.s=.o)
+CSRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c))
+CSRC += $(GFXSRC)
+COBJ := $(CSRC:.c=.o)
+
+vpath %.c $(SRC_DIR)
+vpath %.cpp $(SRC_DIR)
+vpath %.s $(SRC_DIR)
+
+%.o: %.c
+ $(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) -c -o $*.o $<
+
+%.o: %.s
+ $(AS) $(ASFLAGS_FOR_TARGET) $(INCLUDES) $(ASFLAGS) -o $*.o $<
+
+OBJ = $(AOBJ) $(COBJ)
+
+bin/kernel.img: bin/kernel.elf
+ ${OBJCOPY} -O binary $< $@
+
+bin/kernel.elf: LDFLAGS += -L "$(PREFIX)/lib/gcc/arm-none-eabi/4.8.3" -lgcc
+bin/kernel.elf: LDFLAGS += -L "$(PREFIX)/arm-none-eabi/lib" -lc
+bin/kernel.elf: $(OBJ)
+ ${LD} $(OBJ) -Map bin/kernel.map -o $@ -T $(LINKER_SCRIPT) ${LDFLAGS}
+
+clean:
+ rm -f bin/*.elf bin/*.img bin/*.map $(OBJ)
+
+
+
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/main.c b/boards/base/RaspberryPi/example-FreeRTOS/main.c
new file mode 100644
index 00000000..3a64a7bb
--- /dev/null
+++ b/boards/base/RaspberryPi/example-FreeRTOS/main.c
@@ -0,0 +1,82 @@
+#include <FreeRTOS.h>
+#include <task.h>
+
+#include "Drivers/interrupts.h"
+
+#include "gfx.h"
+
+static void displayTask(void *pvParameters) {
+ coord_t width, height;
+ // Get the screen size
+ width = gdispGetWidth();
+ height = gdispGetHeight();
+
+ // Code Here
+ gdispDrawBox(10, 10, width/2, height/2, Yellow);
+ gdispFillArea(width/2, height/2, width/2-10, height/2-10, Blue);
+ gdispDrawLine(5, 30, width-50, height-40, Red);
+
+ while(1)
+ {
+ vTaskDelay(1000);
+ }
+
+ return;
+}
+
+/**
+ * This is the systems main entry, some call it a boot thread.
+ *
+ * -- Absolutely nothing wrong with this being called main(), just it doesn't have
+ * -- the same prototype as you'd see in a linux program.
+ **/
+int main(void) {
+
+ DisableInterrupts();
+ InitInterruptController();
+
+ // Initialize and clear the display
+ gfxInit();
+
+ xTaskCreate(displayTask,
+ (portCHAR *)"Display Task",
+ 128,
+ NULL,
+ 0,
+ NULL);
+
+ vTaskStartScheduler();
+
+ /*
+ * We should never get here, but just in case something goes wrong,
+ * we'll place the CPU into a safe loop.
+ */
+ while(1) {
+ ;
+ }
+
+ return 0;
+}
+
+void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
+{
+ ( void ) pcTaskName;
+ ( void ) pxTask;
+
+ /* Run time task stack overflow checking is performed if
+ configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is
+ called if a task stack overflow is detected. Note the system/interrupt
+ stack is not checked. */
+ taskDISABLE_INTERRUPTS();
+ for( ;; );
+}
+/*-----------------------------------------------------------*/
+
+void vApplicationTickHook( void )
+{
+ /* This function will be called by each tick interrupt if
+ configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
+ added here, but the tick hook is called from an interrupt context, so
+ code must not attempt to block, and only the interrupt safe FreeRTOS API
+ functions can be used (those that end in FromISR()). */
+}
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/raspberrypi.ld b/boards/base/RaspberryPi/example-FreeRTOS/raspberrypi.ld
new file mode 100644
index 00000000..ece588b5
--- /dev/null
+++ b/boards/base/RaspberryPi/example-FreeRTOS/raspberrypi.ld
@@ -0,0 +1,70 @@
+/**
+ * BlueThunder Linker Script for the raspberry Pi!
+ *
+ *
+ *
+ **/
+MEMORY
+{
+ RESERVED (r) : ORIGIN = 0x00000000, LENGTH = 32K
+ INIT_RAM (rwx) : ORIGIN = 0x00008000, LENGTH = 32K
+ RAM (rwx) : ORIGIN = 0x00010000, LENGTH = 128M
+}
+
+ENTRY(_start)
+
+SECTIONS {
+ /*
+ * Our init section allows us to place the bootstrap code at address 0x8000
+ *
+ * This is where the Graphics processor forces the ARM to start execution.
+ * However the interrupt vector code remains at 0x0000, and so we must copy the correct
+ * branch instructions to 0x0000 - 0x001C in order to get the processor to handle interrupts.
+ *
+ */
+ .init : {
+ KEEP(*(.init))
+ } > INIT_RAM = 0
+
+ .module_entries : {
+ __module_entries_start = .;
+ KEEP(*(.module_entries))
+ KEEP(*(.module_entries.*))
+ __module_entries_end = .;
+ __module_entries_size = SIZEOF(.module_entries);
+ } > INIT_RAM
+
+
+ /**
+ * This is the main code section, it is essentially of unlimited size. (128Mb).
+ *
+ **/
+ .text : {
+ *(.text)
+ } > RAM
+
+ /*
+ * Next we put the data.
+ */
+ .data : {
+ *(.data)
+ } > RAM
+
+ .bss :
+ {
+ __bss_start = .;
+ *(.bss)
+ *(.bss.*)
+ __bss_end = .;
+ } > RAM
+
+ /**
+ * Place HEAP here???
+ **/
+
+ /**
+ * Stack starts at the top of the RAM, and moves down!
+ **/
+ _estack = ORIGIN(RAM) + LENGTH(RAM);
+}
+
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/startup.s b/boards/base/RaspberryPi/example-FreeRTOS/startup.s
new file mode 100644
index 00000000..286f396c
--- /dev/null
+++ b/boards/base/RaspberryPi/example-FreeRTOS/startup.s
@@ -0,0 +1,102 @@
+.extern system_init
+.extern __bss_start
+.extern __bss_end
+.extern vFreeRTOS_ISR
+.extern vPortYieldProcessor
+.extern DisableInterrupts
+.extern main
+ .section .init
+ .globl _start
+;;
+_start:
+ ;@ All the following instruction should be read as:
+ ;@ Load the address at symbol into the program counter.
+
+ ldr pc,reset_handler ;@ Processor Reset handler -- we will have to force this on the raspi!
+ ;@ Because this is the first instruction executed, of cause it causes an immediate branch into reset!
+
+ ldr pc,undefined_handler ;@ Undefined instruction handler -- processors that don't have thumb can emulate thumb!
+ ldr pc,swi_handler ;@ Software interrupt / TRAP (SVC) -- system SVC handler for switching to kernel mode.
+ ldr pc,prefetch_handler ;@ Prefetch/abort handler.
+ ldr pc,data_handler ;@ Data abort handler/
+ ldr pc,unused_handler ;@ -- Historical from 26-bit addressing ARMs -- was invalid address handler.
+ ldr pc,irq_handler ;@ IRQ handler
+ ldr pc,fiq_handler ;@ Fast interrupt handler.
+
+ ;@ Here we create an exception address table! This means that reset/hang/irq can be absolute addresses
+reset_handler: .word reset
+undefined_handler: .word undefined_instruction
+swi_handler: .word vPortYieldProcessor
+prefetch_handler: .word prefetch_abort
+data_handler: .word data_abort
+unused_handler: .word unused
+irq_handler: .word vFreeRTOS_ISR
+fiq_handler: .word fiq
+
+reset:
+ ;@ In the reset handler, we need to copy our interrupt vector table to 0x0000, its currently at 0x8000
+
+ mov r0,#0x8000 ;@ Store the source pointer
+ mov r1,#0x0000 ;@ Store the destination pointer.
+
+ ;@ Here we copy the branching instructions
+ ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load multiple values from indexed address. ; Auto-increment R0
+ stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store multiple values from the indexed address. ; Auto-increment R1
+
+ ;@ So the branches get the correct address we also need to copy our vector table!
+ ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load from 4*n of regs (8) as R0 is now incremented.
+ stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store this extra set of data.
+
+
+ ;@ Set up the various STACK pointers for different CPU modes
+ ;@ (PSR_IRQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS)
+ mov r0,#0xD2
+ msr cpsr_c,r0
+ mov sp,#0x8000
+
+ ;@ (PSR_FIQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS)
+ mov r0,#0xD1
+ msr cpsr_c,r0
+ mov sp,#0x4000
+
+ ;@ (PSR_SVC_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS)
+ mov r0,#0xD3
+ msr cpsr_c,r0
+ mov sp,#0x8000000
+
+ ldr r0, =__bss_start
+ ldr r1, =__bss_end
+
+ mov r2, #0
+
+zero_loop:
+ cmp r0,r1
+ it lt
+ strlt r2,[r0], #4
+ blt zero_loop
+
+ bl DisableInterrupts
+
+
+ ;@ mov sp,#0x1000000
+ b main ;@ We're ready?? Lets start main execution!
+ .section .text
+
+undefined_instruction:
+ b undefined_instruction
+
+prefetch_abort:
+ b prefetch_abort
+
+data_abort:
+ b data_abort
+
+unused:
+ b unused
+
+fiq:
+ b fiq
+
+hang:
+ b hang
+