aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjaseg <jaseg@jaseg.net>2013-12-13 00:56:12 +0100
committerjaseg <jaseg@jaseg.net>2013-12-13 00:56:12 +0100
commit9b6d4fe5b8148bf183b17475d1f376b2f8743cfb (patch)
treefd2233c8cbdda8f57f9888df3a383636261993c7
downloadmatelight-9b6d4fe5b8148bf183b17475d1f376b2f8743cfb.tar.gz
matelight-9b6d4fe5b8148bf183b17475d1f376b2f8743cfb.tar.bz2
matelight-9b6d4fe5b8148bf183b17475d1f376b2f8743cfb.zip
Initial commit
-rw-r--r--.gitignore2
-rw-r--r--.gitmodules3
-rw-r--r--README.rst23
-rw-r--r--firmware/LICENSE18
-rw-r--r--firmware/Makefile94
-rw-r--r--firmware/main.c268
-rw-r--r--firmware/startup_gcc.c350
-rw-r--r--firmware/usb_bulk_structs.c179
-rw-r--r--firmware/usb_bulk_structs.h44
-rw-r--r--firmware/usb_dev_bulk.ld57
m---------stellaris0
11 files changed, 1038 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cce6215
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+firmware/gcc/*
+*.swp
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..501e36d
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "stellaris"]
+ path = stellaris
+ url = https://github.com/yuvadm/stellaris.git
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..9f835ec
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,23 @@
+Mate Light
+==========
+
+Objective
+---------
+
+
+Hardware Setup
+--------------
+
+
+Software
+--------
+
+
+Architecture
+~~~~~~~~~~~~
+
+
+Setup
+~~~~~
+
+
diff --git a/firmware/LICENSE b/firmware/LICENSE
new file mode 100644
index 0000000..a8ef53c
--- /dev/null
+++ b/firmware/LICENSE
@@ -0,0 +1,18 @@
+Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved.
+Copyright (c) 2013 jaseg <github@jaseg.net>. All rights reserved.
+Software License Agreement
+
+Texas Instruments (TI) is supplying this software for use solely and
+exclusively on TI's microcontroller products. The software is owned by
+TI and/or its suppliers, and is protected under applicable copyright
+laws. You may not combine this software with "viral" open-source
+software in order to form a larger program.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, FOR ANY REASON WHATSOEVER.
+
+This was part of revision 9453 of the EK-LM4F120XL Firmware Package.
diff --git a/firmware/Makefile b/firmware/Makefile
new file mode 100644
index 0000000..3aa39e1
--- /dev/null
+++ b/firmware/Makefile
@@ -0,0 +1,94 @@
+#******************************************************************************
+#
+# Makefile - Rules for building the USB device bulk example.
+#
+# Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved.
+# Software License Agreement
+#
+# Texas Instruments (TI) is supplying this software for use solely and
+# exclusively on TI's microcontroller products. The software is owned by
+# TI and/or its suppliers, and is protected under applicable copyright
+# laws. You may not combine this software with "viral" open-source
+# software in order to form a larger program.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+# NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+# NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+# CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+# DAMAGES, FOR ANY REASON WHATSOEVER.
+#
+# This is part of revision 9453 of the EK-LM4F120XL Firmware Package.
+#
+#******************************************************************************
+
+#
+# Defines the part type that this project uses.
+#
+PART=LM4F120H5QR
+
+#
+# Set the processor variant.
+#
+VARIANT=cm4f
+
+#
+# The base directory for StellarisWare.
+#
+ROOT=../stellaris
+
+#
+# Include the common make definitions.
+#
+include ${ROOT}/makedefs
+
+#
+# Where to find source files that do not live in this directory.
+#
+VPATH=
+VPATH+=../stellaris/utils
+
+#
+# Where to find header files that do not live in the source directory.
+#
+IPATH=../stellaris
+
+#
+# The default rule, which causes the USB device bulk example to be built.
+#
+all: ${COMPILER}
+all: ${COMPILER}/main.axf
+
+#
+# The rule to clean out all the build products.
+#
+clean:
+ @rm -rf ${COMPILER} ${wildcard *~}
+
+#
+# The rule to create the target directory.
+#
+${COMPILER}:
+ @mkdir -p ${COMPILER}
+
+#
+# Rules for building the USB device bulk example.
+#
+${COMPILER}/main.axf: ${COMPILER}/startup_${COMPILER}.o
+${COMPILER}/main.axf: ${COMPILER}/uartstdio.o
+${COMPILER}/main.axf: ${COMPILER}/usb_bulk_structs.o
+${COMPILER}/main.axf: ${COMPILER}/main.o
+${COMPILER}/main.axf: ${COMPILER}/ustdlib.o
+${COMPILER}/main.axf: ${ROOT}/usblib/${COMPILER}-cm4f/libusb-cm4f.a
+${COMPILER}/main.axf: ${ROOT}/driverlib/${COMPILER}-cm4f/libdriver-cm4f.a
+${COMPILER}/main.axf: usb_dev_bulk.ld
+SCATTERgcc_main=usb_dev_bulk.ld
+ENTRY_main=ResetISR
+CFLAGSgcc=-DTARGET_IS_BLIZZARD_RA1 -DUART_BUFFERED
+
+#
+# Include the automatically generated dependency files.
+#
+ifneq (${MAKECMDGOALS},clean)
+-include ${wildcard ${COMPILER}/*.d} __dummy__
+endif
diff --git a/firmware/main.c b/firmware/main.c
new file mode 100644
index 0000000..b1af4a5
--- /dev/null
+++ b/firmware/main.c
@@ -0,0 +1,268 @@
+/* Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved.
+ * Software License Agreement
+ *
+ * Texas Instruments (TI) is supplying this software for use solely and
+ * exclusively on TI's microcontroller products. The software is owned by
+ * TI and/or its suppliers, and is protected under applicable copyright
+ * laws. You may not combine this software with "viral" open-source
+ * software in order to form a larger program.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+ * NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+ * NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+ * CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+ * DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ * This is part of revision 9453 of the EK-LM4F120XL Firmware Package.
+ */
+
+#include "inc/hw_ints.h"
+#include "inc/hw_memmap.h"
+#include "inc/hw_types.h"
+#include "inc/hw_ssi.h"
+#include "driverlib/debug.h"
+#include "driverlib/fpu.h"
+#include "driverlib/gpio.h"
+#include "driverlib/interrupt.h"
+#include "driverlib/pin_map.h"
+#include "driverlib/sysctl.h"
+#include "driverlib/systick.h"
+#include "driverlib/timer.h"
+#include "driverlib/uart.h"
+#include "driverlib/rom.h"
+#include "driverlib/udma.h"
+#include "driverlib/ssi.h"
+#include "usblib/usblib.h"
+#include "usblib/usb-ids.h"
+#include "usblib/device/usbdevice.h"
+#include "usblib/device/usbdbulk.h"
+#include "utils/uartstdio.h"
+#include "utils/ustdlib.h"
+#include "usb_bulk_structs.h"
+
+#define CRATE_WIDTH 5
+#define CRATE_HEIGHT 4
+#define CRATES_X 4
+#define CRATES_Y 2
+#define BUS_COUNT 4
+#define BYTES_PER_PIXEL 3
+#define BUS_ROWS (CRATES_Y*CRATE_HEIGHT)
+#define BUS_COLUMNS (CRATES_X*CRATE_WIDTH)
+#define CRATES_PER_BUS (CRATES_X*CRATES_Y)
+#define CRATE_SIZE (CRATE_WIDTH*CRATE_HEIGHT)
+#define BUS_SIZE (CRATES_PER_BUS*CRATE_SIZE*BYTES_PER_PIXEL)
+unsigned const char const BOTTLE_MAP[CRATE_SIZE] = {
+ 0, 1, 2, 3, 4,
+ 19, 8, 7, 6, 5,
+ 18, 9, 10, 11, 12,
+ 17, 16, 15, 14, 13
+};
+
+unsigned const char const CRATE_MAP[CRATES_PER_BUS] = {
+ 6, 4, 2, 0,
+ 7, 5, 3, 1
+};
+
+#define SYSTICKS_PER_SECOND 100
+#define SYSTICK_PERIOD_MS (1000 / SYSTICKS_PER_SECOND)
+
+unsigned char framebuffer[BUS_COUNT*BUS_SIZE];
+/* Kick off DMA from RAM to SPI interfaces */
+void start_dma(void);
+unsigned long framebuffer_read(void *fb, unsigned long len);
+
+unsigned char ucControlTable[1024] __attribute__ ((aligned(1024)));
+
+volatile unsigned long g_ulSysTickCount = 0;
+
+#ifdef DEBUG
+unsigned long g_ulUARTRxErrors = 0;
+#endif
+
+//Debug output is available via UART0 if DEBUG is defined during build.
+#ifdef DEBUG
+//Map all debug print calls to UARTprintf in debug builds.
+#define DEBUG_PRINT UARTprintf
+#else
+//Compile out all debug print calls in release builds.
+#define DEBUG_PRINT while(0) ((int (*)(char *, ...))0)
+#endif
+
+volatile unsigned long g_ulFlags = 0;
+char *g_pcStatus;
+static volatile tBoolean g_bUSBConfigured = false;
+
+void SysTickIntHandler(void){
+ g_ulSysTickCount++;
+}
+
+unsigned long RxHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue, void *pvMsgData) {
+ switch(ulEvent) {
+ case USB_EVENT_CONNECTED:
+ g_bUSBConfigured = true;
+ UARTprintf("Host connected.\n");
+ USBBufferFlush(&g_sRxBuffer);
+ break;
+ case USB_EVENT_DISCONNECTED:
+ g_bUSBConfigured = false;
+ UARTprintf("Host disconnected.\n");
+ break;
+ case USB_EVENT_RX_AVAILABLE:
+ UARTprintf("Handling host data.\n\n");
+ return framebuffer_read(pvMsgData, ulMsgValue);
+ case USB_EVENT_SUSPEND:
+ case USB_EVENT_RESUME:
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+unsigned long framebuffer_read(void *fb, unsigned long len){
+ if(len != BUS_COUNT*BUS_COLUMNS*BUS_ROWS)
+ return 0;
+ for(unsigned int bus=0; bus<BUS_COUNT; bus++){
+ for(unsigned int x=0; x<BUS_COLUMNS; x++){
+ for(unsigned int y=0; x<BUS_ROWS; y++){
+ unsigned int crate = CRATE_MAP[x/CRATE_WIDTH + (y/CRATE_HEIGHT)*CRATES_X];
+ unsigned int bottle = BOTTLE_MAP[x%CRATE_WIDTH + (y%CRATE_HEIGHT)*CRATE_WIDTH];
+ //Copy r, g and b data
+ framebuffer[(bus*BUS_SIZE + crate*CRATE_SIZE + bottle)*3] =
+ ((unsigned char *)fb)[(bus*BUS_SIZE + y*BUS_COLUMNS + x)*3];
+ framebuffer[(bus*BUS_SIZE + crate*CRATE_SIZE + bottle)*3 + 1] =
+ ((unsigned char *)fb)[(bus*BUS_SIZE + y*BUS_COLUMNS + x)*3 + 1];
+ framebuffer[(bus*BUS_SIZE + crate*CRATE_SIZE + bottle)*3 + 2] =
+ ((unsigned char *)fb)[(bus*BUS_SIZE + y*BUS_COLUMNS + x)*3 + 2];
+ }
+ }
+ }
+ UARTprintf("Starting DMA.\n\n");
+ start_dma();
+ return len;
+}
+
+void start_dma(void){
+ ROM_SSIDMAEnable(SSI0_BASE, SSI_DMA_TX);
+ ROM_SSIDMAEnable(SSI1_BASE, SSI_DMA_TX);
+ ROM_SSIDMAEnable(SSI2_BASE, SSI_DMA_TX);
+ ROM_SSIDMAEnable(SSI3_BASE, SSI_DMA_TX);
+}
+
+int main(void){
+ /* Enable lazy stacking for interrupt handlers. This allows floating-point instructions to be used within interrupt
+ * handlers, but at the expense of extra stack usage. */
+ ROM_FPULazyStackingEnable();
+
+ //Set clock to PLL at 50MHz
+ ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
+ SYSCTL_XTAL_16MHZ);
+
+ //Configure UART0 pins
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
+ GPIOPinConfigure(GPIO_PA0_U0RX);
+ GPIOPinConfigure(GPIO_PA1_U0TX);
+ ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
+
+ //Enable the GPIO pins for the LED (PF2 & PF3).
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
+ ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3|GPIO_PIN_2);
+
+ UARTStdioInit(0);
+ UARTprintf("Booting...\n\n");
+
+ g_bUSBConfigured = false;
+
+ //Enable the GPIO peripheral used for USB, and configure the USB pins.
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
+ ROM_GPIOPinTypeUSBAnalog(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5);
+
+ //Enable the system tick.
+ ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / SYSTICKS_PER_SECOND);
+ ROM_SysTickIntEnable();
+ ROM_SysTickEnable();
+
+ //Configure USB
+ USBBufferInit((tUSBBuffer *)&g_sRxBuffer);
+ USBStackModeSet(0, USB_MODE_FORCE_DEVICE, 0);
+ USBDBulkInit(0, (tUSBDBulkDevice *)&g_sBulkDevice);
+
+ //Configure SSI0..3 for the ws2801's SPI-like protocol
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);
+
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
+ GPIOPinConfigure(GPIO_PA2_SSI0CLK);
+ GPIOPinConfigure(GPIO_PA5_SSI0TX);
+ ROM_GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_5);
+
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
+ GPIOPinConfigure(GPIO_PB4_SSI2CLK);
+ GPIOPinConfigure(GPIO_PB7_SSI2TX);
+ ROM_GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_7);
+
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
+ GPIOPinConfigure(GPIO_PD0_SSI3CLK);
+ GPIOPinConfigure(GPIO_PD3_SSI3TX);
+ ROM_GPIOPinTypeSSI(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_3);
+
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
+ GPIOPinConfigure(GPIO_PF2_SSI1CLK);
+ GPIOPinConfigure(GPIO_PF1_SSI1TX);
+ ROM_GPIOPinTypeSSI(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_3);
+
+ SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 2000000, 8);
+ SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 2000000, 8);
+ SSIConfigSetExpClk(SSI2_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 2000000, 8);
+ SSIConfigSetExpClk(SSI3_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 2000000, 8);
+
+ //Configure the µDMA controller for use by the SPI interface
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
+ ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
+ ROM_IntEnable(INT_UDMAERR); // Enable µDMA error interrupt
+ ROM_uDMAEnable();
+ ROM_uDMAControlBaseSet(ucControlTable);
+ //Put the µDMA attributes in a known state. These should already be disabled by default.
+ ROM_uDMAChannelAttributeDisable(UDMA_CH11_SSI0TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
+ ROM_uDMAChannelAttributeDisable(UDMA_CH11_SSI1TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
+ ROM_uDMAChannelAttributeDisable(UDMA_CH13_SSI2TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
+ ROM_uDMAChannelAttributeDisable(UDMA_CH15_SSI3TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
+ /* Set the USEBURST attribute for the uDMA UART TX channel. This will force the controller to always use a burst
+ * when transferring data from the TX buffer to the UART. This is somewhat more effecient bus usage than the
+ * default which allows single or burst transfers. */
+ ROM_uDMAChannelAttributeEnable(UDMA_CH11_SSI0TX, UDMA_ATTR_USEBURST);
+ ROM_uDMAChannelAttributeEnable(UDMA_CH11_SSI1TX, UDMA_ATTR_USEBURST);
+ ROM_uDMAChannelAttributeEnable(UDMA_CH13_SSI2TX, UDMA_ATTR_USEBURST);
+ ROM_uDMAChannelAttributeEnable(UDMA_CH15_SSI3TX, UDMA_ATTR_USEBURST);
+ /* Configure the SSI Tx µDMA Channel to transfer from RAM to TX FIFO. The arbitration size is set to 4, which
+ * matches the SSI TX FIFO µDMA trigger threshold. */
+ ROM_uDMAChannelControlSet(UDMA_CH11_SSI0TX, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4);
+ ROM_uDMAChannelTransferSet(UDMA_CH11_SSI0TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, framebuffer, (void *)(SSI0_BASE + SSI_O_DR), BUS_SIZE);
+ ROM_uDMAChannelEnable(UDMA_CH11_SSI0TX);
+
+ ROM_uDMAChannelControlSet(UDMA_CH11_SSI1TX, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4);
+ ROM_uDMAChannelTransferSet(UDMA_CH11_SSI1TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, framebuffer+BUS_SIZE, (void *)(SSI0_BASE + SSI_O_DR), BUS_SIZE);
+ ROM_uDMAChannelEnable(UDMA_CH11_SSI1TX);
+
+ ROM_uDMAChannelControlSet(UDMA_CH13_SSI2TX, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4);
+ ROM_uDMAChannelTransferSet(UDMA_CH13_SSI2TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, framebuffer+BUS_SIZE*2, (void *)(SSI0_BASE + SSI_O_DR), BUS_SIZE);
+ ROM_uDMAChannelEnable(UDMA_CH13_SSI2TX);
+
+ ROM_uDMAChannelControlSet(UDMA_CH15_SSI3TX, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4);
+ ROM_uDMAChannelTransferSet(UDMA_CH15_SSI3TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, framebuffer+BUS_SIZE*3, (void *)(SSI0_BASE + SSI_O_DR), BUS_SIZE);
+ ROM_uDMAChannelEnable(UDMA_CH15_SSI3TX);
+
+ //Enable the SSIs after configuring anything around them.
+ SSIEnable(SSI0_BASE);
+ SSIEnable(SSI1_BASE);
+ SSIEnable(SSI2_BASE);
+ SSIEnable(SSI3_BASE);
+
+ UARTprintf("Booted.\n");
+
+ while(1){
+ }
+}
diff --git a/firmware/startup_gcc.c b/firmware/startup_gcc.c
new file mode 100644
index 0000000..8d06bfb
--- /dev/null
+++ b/firmware/startup_gcc.c
@@ -0,0 +1,350 @@
+//*****************************************************************************
+//
+// startup_gcc.c - Startup code for use with GNU tools.
+//
+// Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 9453 of the EK-LM4F120XL Firmware Package.
+//
+//*****************************************************************************
+
+#include "inc/hw_nvic.h"
+#include "inc/hw_types.h"
+
+//*****************************************************************************
+//
+// Forward declaration of the default fault handlers.
+//
+//*****************************************************************************
+void ResetISR(void);
+static void NmiSR(void);
+static void FaultISR(void);
+static void IntDefaultHandler(void);
+
+//*****************************************************************************
+//
+// External declarations for the interrupt handlers used by the application.
+//
+//*****************************************************************************
+extern void SysTickIntHandler(void);
+extern void UARTStdioIntHandler(void);
+extern void USB0DeviceIntHandler(void);
+
+//*****************************************************************************
+//
+// The entry point for the application.
+//
+//*****************************************************************************
+extern int main(void);
+
+//*****************************************************************************
+//
+// Reserve space for the system stack.
+//
+//*****************************************************************************
+static unsigned long pulStack[256];
+
+//*****************************************************************************
+//
+// The vector table. Note that the proper constructs must be placed on this to
+// ensure that it ends up at physical address 0x0000.0000.
+//
+//*****************************************************************************
+__attribute__ ((section(".isr_vector")))
+void (* const g_pfnVectors[])(void) =
+{
+ (void (*)(void))((unsigned long)pulStack + sizeof(pulStack)),
+ // The initial stack pointer
+ ResetISR, // The reset handler
+ NmiSR, // The NMI handler
+ FaultISR, // The hard fault handler
+ IntDefaultHandler, // The MPU fault handler
+ IntDefaultHandler, // The bus fault handler
+ IntDefaultHandler, // The usage fault handler
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ IntDefaultHandler, // SVCall handler
+ IntDefaultHandler, // Debug monitor handler
+ 0, // Reserved
+ IntDefaultHandler, // The PendSV handler
+ SysTickIntHandler, // The SysTick handler
+ IntDefaultHandler, // GPIO Port A
+ IntDefaultHandler, // GPIO Port B
+ IntDefaultHandler, // GPIO Port C
+ IntDefaultHandler, // GPIO Port D
+ IntDefaultHandler, // GPIO Port E
+ UARTStdioIntHandler, // UART0 Rx and Tx
+ IntDefaultHandler, // UART1 Rx and Tx
+ IntDefaultHandler, // SSI0 Rx and Tx
+ IntDefaultHandler, // I2C0 Master and Slave
+ IntDefaultHandler, // PWM Fault
+ IntDefaultHandler, // PWM Generator 0
+ IntDefaultHandler, // PWM Generator 1
+ IntDefaultHandler, // PWM Generator 2
+ IntDefaultHandler, // Quadrature Encoder 0
+ IntDefaultHandler, // ADC Sequence 0
+ IntDefaultHandler, // ADC Sequence 1
+ IntDefaultHandler, // ADC Sequence 2
+ IntDefaultHandler, // ADC Sequence 3
+ IntDefaultHandler, // Watchdog timer
+ IntDefaultHandler, // Timer 0 subtimer A
+ IntDefaultHandler, // Timer 0 subtimer B
+ IntDefaultHandler, // Timer 1 subtimer A
+ IntDefaultHandler, // Timer 1 subtimer B
+ IntDefaultHandler, // Timer 2 subtimer A
+ IntDefaultHandler, // Timer 2 subtimer B
+ IntDefaultHandler, // Analog Comparator 0
+ IntDefaultHandler, // Analog Comparator 1
+ IntDefaultHandler, // Analog Comparator 2
+ IntDefaultHandler, // System Control (PLL, OSC, BO)
+ IntDefaultHandler, // FLASH Control
+ IntDefaultHandler, // GPIO Port F
+ IntDefaultHandler, // GPIO Port G
+ IntDefaultHandler, // GPIO Port H
+ IntDefaultHandler, // UART2 Rx and Tx
+ IntDefaultHandler, // SSI1 Rx and Tx
+ IntDefaultHandler, // Timer 3 subtimer A
+ IntDefaultHandler, // Timer 3 subtimer B
+ IntDefaultHandler, // I2C1 Master and Slave
+ IntDefaultHandler, // Quadrature Encoder 1
+ IntDefaultHandler, // CAN0
+ IntDefaultHandler, // CAN1
+ IntDefaultHandler, // CAN2
+ IntDefaultHandler, // Ethernet
+ IntDefaultHandler, // Hibernate
+ USB0DeviceIntHandler, // USB0
+ IntDefaultHandler, // PWM Generator 3
+ IntDefaultHandler, // uDMA Software Transfer
+ IntDefaultHandler, // uDMA Error
+ IntDefaultHandler, // ADC1 Sequence 0
+ IntDefaultHandler, // ADC1 Sequence 1
+ IntDefaultHandler, // ADC1 Sequence 2
+ IntDefaultHandler, // ADC1 Sequence 3
+ IntDefaultHandler, // I2S0
+ IntDefaultHandler, // External Bus Interface 0
+ IntDefaultHandler, // GPIO Port J
+ IntDefaultHandler, // GPIO Port K
+ IntDefaultHandler, // GPIO Port L
+ IntDefaultHandler, // SSI2 Rx and Tx
+ IntDefaultHandler, // SSI3 Rx and Tx
+ IntDefaultHandler, // UART3 Rx and Tx
+ IntDefaultHandler, // UART4 Rx and Tx
+ IntDefaultHandler, // UART5 Rx and Tx
+ IntDefaultHandler, // UART6 Rx and Tx
+ IntDefaultHandler, // UART7 Rx and Tx
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ IntDefaultHandler, // I2C2 Master and Slave
+ IntDefaultHandler, // I2C3 Master and Slave
+ IntDefaultHandler, // Timer 4 subtimer A
+ IntDefaultHandler, // Timer 4 subtimer B
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ IntDefaultHandler, // Timer 5 subtimer A
+ IntDefaultHandler, // Timer 5 subtimer B
+ IntDefaultHandler, // Wide Timer 0 subtimer A
+ IntDefaultHandler, // Wide Timer 0 subtimer B
+ IntDefaultHandler, // Wide Timer 1 subtimer A
+ IntDefaultHandler, // Wide Timer 1 subtimer B
+ IntDefaultHandler, // Wide Timer 2 subtimer A
+ IntDefaultHandler, // Wide Timer 2 subtimer B
+ IntDefaultHandler, // Wide Timer 3 subtimer A
+ IntDefaultHandler, // Wide Timer 3 subtimer B
+ IntDefaultHandler, // Wide Timer 4 subtimer A
+ IntDefaultHandler, // Wide Timer 4 subtimer B
+ IntDefaultHandler, // Wide Timer 5 subtimer A
+ IntDefaultHandler, // Wide Timer 5 subtimer B
+ IntDefaultHandler, // FPU
+ IntDefaultHandler, // PECI 0
+ IntDefaultHandler, // LPC 0
+ IntDefaultHandler, // I2C4 Master and Slave
+ IntDefaultHandler, // I2C5 Master and Slave
+ IntDefaultHandler, // GPIO Port M
+ IntDefaultHandler, // GPIO Port N
+ IntDefaultHandler, // Quadrature Encoder 2
+ IntDefaultHandler, // Fan 0
+ 0, // Reserved
+ IntDefaultHandler, // GPIO Port P (Summary or P0)
+ IntDefaultHandler, // GPIO Port P1
+ IntDefaultHandler, // GPIO Port P2
+ IntDefaultHandler, // GPIO Port P3
+ IntDefaultHandler, // GPIO Port P4
+ IntDefaultHandler, // GPIO Port P5
+ IntDefaultHandler, // GPIO Port P6
+ IntDefaultHandler, // GPIO Port P7
+ IntDefaultHandler, // GPIO Port Q (Summary or Q0)
+ IntDefaultHandler, // GPIO Port Q1
+ IntDefaultHandler, // GPIO Port Q2
+ IntDefaultHandler, // GPIO Port Q3
+ IntDefaultHandler, // GPIO Port Q4
+ IntDefaultHandler, // GPIO Port Q5
+ IntDefaultHandler, // GPIO Port Q6
+ IntDefaultHandler, // GPIO Port Q7
+ IntDefaultHandler, // GPIO Port R
+ IntDefaultHandler, // GPIO Port S
+ IntDefaultHandler, // PWM 1 Generator 0
+ IntDefaultHandler, // PWM 1 Generator 1
+ IntDefaultHandler, // PWM 1 Generator 2
+ IntDefaultHandler, // PWM 1 Generator 3
+ IntDefaultHandler // PWM 1 Fault
+};
+
+//*****************************************************************************
+//
+// The following are constructs created by the linker, indicating where the
+// the "data" and "bss" segments reside in memory. The initializers for the
+// for the "data" segment resides immediately following the "text" segment.
+//
+//*****************************************************************************
+extern unsigned long _etext;
+extern unsigned long _data;
+extern unsigned long _edata;
+extern unsigned long _bss;
+extern unsigned long _ebss;
+
+//*****************************************************************************
+//
+// This is the code that gets called when the processor first starts execution
+// following a reset event. Only the absolutely necessary set is performed,
+// after which the application supplied entry() routine is called. Any fancy
+// actions (such as making decisions based on the reset cause register, and
+// resetting the bits in that register) are left solely in the hands of the
+// application.
+//
+//*****************************************************************************
+void
+ResetISR(void)
+{
+ unsigned long *pulSrc, *pulDest;
+
+ //
+ // Copy the data segment initializers from flash to SRAM.
+ //
+ pulSrc = &_etext;
+ for(pulDest = &_data; pulDest < &_edata; )
+ {
+ *pulDest++ = *pulSrc++;
+ }
+
+ //
+ // Zero fill the bss segment.
+ //
+ __asm(" ldr r0, =_bss\n"
+ " ldr r1, =_ebss\n"
+ " mov r2, #0\n"
+ " .thumb_func\n"
+ "zero_loop:\n"
+ " cmp r0, r1\n"
+ " it lt\n"
+ " strlt r2, [r0], #4\n"
+ " blt zero_loop");
+
+ //
+ // Enable the floating-point unit. This must be done here to handle the
+ // case where main() uses floating-point and the function prologue saves
+ // floating-point registers (which will fault if floating-point is not
+ // enabled). Any configuration of the floating-point unit using DriverLib
+ // APIs must be done here prior to the floating-point unit being enabled.
+ //
+ // Note that this does not use DriverLib since it might not be included in
+ // this project.
+ //
+ HWREG(NVIC_CPAC) = ((HWREG(NVIC_CPAC) &
+ ~(NVIC_CPAC_CP10_M | NVIC_CPAC_CP11_M)) |
+ NVIC_CPAC_CP10_FULL | NVIC_CPAC_CP11_FULL);
+
+ //
+ // Call the application's entry point.
+ //
+ main();
+}
+
+//*****************************************************************************
+//
+// This is the code that gets called when the processor receives a NMI. This
+// simply enters an infinite loop, preserving the system state for examination
+// by a debugger.
+//
+//*****************************************************************************
+static void
+NmiSR(void)
+{
+ //
+ // Enter an infinite loop.
+ //
+ while(1)
+ {
+ }
+}
+
+//*****************************************************************************
+//
+// This is the code that gets called when the processor receives a fault
+// interrupt. This simply enters an infinite loop, preserving the system state
+// for examination by a debugger.
+//
+//*****************************************************************************
+static void
+FaultISR(void)
+{
+ //
+ // Enter an infinite loop.
+ //
+ while(1)
+ {
+ }
+}
+
+//*****************************************************************************
+//
+// This is the code that gets called when the processor receives an unexpected
+// interrupt. This simply enters an infinite loop, preserving the system state
+// for examination by a debugger.
+//
+//*****************************************************************************
+static void
+IntDefaultHandler(void)
+{
+ //
+ // Go into an infinite loop.
+ //
+ while(1)
+ {
+ }
+}
diff --git a/firmware/usb_bulk_structs.c b/firmware/usb_bulk_structs.c
new file mode 100644
index 0000000..d7501bd
--- /dev/null
+++ b/firmware/usb_bulk_structs.c
@@ -0,0 +1,179 @@
+//*****************************************************************************
+//
+// usb_bulk_structs.c - Data structures defining this bulk USB device.
+//
+// Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 9453 of the EK-LM4F120XL Firmware Package.
+//
+//*****************************************************************************
+
+#include "inc/hw_types.h"
+#include "driverlib/usb.h"
+#include "usblib/usblib.h"
+#include "usblib/usb-ids.h"
+#include "usblib/device/usbdevice.h"
+#include "usblib/device/usbdbulk.h"
+#include "usb_bulk_structs.h"
+
+//*****************************************************************************
+//
+// The languages supported by this device.
+//
+//*****************************************************************************
+const unsigned char g_pLangDescriptor[] =
+{
+ 4,
+ USB_DTYPE_STRING,
+ USBShort(USB_LANG_EN_US)
+};
+
+//*****************************************************************************
+//
+// The manufacturer string.
+//
+//*****************************************************************************
+const unsigned char g_pManufacturerString[] =
+{
+ (12 + 1) * 2,
+ USB_DTYPE_STRING,
+ 'G', 0, 'o', 0, 'l', 0, 'd', 0, ' ', 0, '&', 0, ' ', 0, 'A', 0, 'p', 0,
+ 'p', 0, 'l', 0, 'e', 0
+};
+
+//*****************************************************************************
+//
+// The product string.
+//
+//*****************************************************************************
+const unsigned char g_pProductString[] =
+{
+ (10 + 1) * 2,
+ USB_DTYPE_STRING,
+ 'M', 0, 'a', 0, 't', 0, 'e', 0, ' ', 0, 'L', 0, 'i', 0, 'g', 0, 'h', 0,
+ 't', 0
+};
+
+//*****************************************************************************
+//
+// The serial number string.
+//
+//*****************************************************************************
+const unsigned char g_pSerialNumberString[] =
+{
+ (8 + 1) * 2,
+ USB_DTYPE_STRING,
+ '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '3', 0, '2', 0
+};
+
+//*****************************************************************************
+//
+// The data interface description string.
+//
+//*****************************************************************************
+const unsigned char g_pDataInterfaceString[] =
+{
+ (19 + 1) * 2,
+ USB_DTYPE_STRING,
+ 'B', 0, 'u', 0, 'l', 0, 'k', 0, ' ', 0, 'D', 0, 'a', 0, 't', 0,
+ 'a', 0, ' ', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0,
+ 'a', 0, 'c', 0, 'e', 0
+};
+
+//*****************************************************************************
+//
+// The configuration description string.
+//
+//*****************************************************************************
+const unsigned char g_pConfigString[] =
+{
+ (23 + 1) * 2,
+ USB_DTYPE_STRING,
+ 'B', 0, 'u', 0, 'l', 0, 'k', 0, ' ', 0, 'D', 0, 'a', 0, 't', 0,
+ 'a', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0, 'f', 0, 'i', 0, 'g', 0,
+ 'u', 0, 'r', 0, 'a', 0, 't', 0, 'i', 0, 'o', 0, 'n', 0
+};
+
+//*****************************************************************************
+//
+// The descriptor string table.
+//
+//*****************************************************************************
+const unsigned char * const g_pStringDescriptors[] =
+{
+ g_pLangDescriptor,
+ g_pManufacturerString,
+ g_pProductString,
+ g_pSerialNumberString,
+ g_pDataInterfaceString,
+ g_pConfigString
+};
+
+#define NUM_STRING_DESCRIPTORS (sizeof(g_pStringDescriptors) / \
+ sizeof(unsigned char *))
+
+//*****************************************************************************
+//
+// The bulk device initialization and customization structures. In this case,
+// we are using USBBuffers between the bulk device class driver and the
+// application code. The function pointers and callback data values are set
+// to insert a buffer in each of the data channels, transmit and receive.
+//
+// With the buffer in place, the bulk channel callback is set to the relevant
+// channel function and the callback data is set to point to the channel
+// instance data. The buffer, in turn, has its callback set to the application
+// function and the callback data set to our bulk instance structure.
+//
+//*****************************************************************************
+tBulkInstance g_sBulkInstance;
+
+extern const tUSBBuffer g_sRxBuffer;
+
+const tUSBDBulkDevice g_sBulkDevice =
+{
+ USB_VID_STELLARIS,
+ USB_PID_BULK,
+ 500,
+ USB_CONF_ATTR_SELF_PWR,
+ USBBufferEventCallback,
+ (void *)&g_sRxBuffer,
+ USBBufferEventCallback,
+ (void *)0,
+ g_pStringDescriptors,
+ NUM_STRING_DESCRIPTORS,
+ &g_sBulkInstance
+};
+
+//*****************************************************************************
+//
+// Receive buffer (from the USB perspective).
+//
+//*****************************************************************************
+unsigned char g_pucUSBRxBuffer[BULK_BUFFER_SIZE];
+unsigned char g_pucRxBufferWorkspace[USB_BUFFER_WORKSPACE_SIZE];
+const tUSBBuffer g_sRxBuffer =
+{
+ false, // This is a receive buffer.
+ RxHandler, // pfnCallback
+ (void *)&g_sBulkDevice, // Callback data is our device pointer.
+ USBDBulkPacketRead, // pfnTransfer
+ USBDBulkRxPacketAvailable, // pfnAvailable
+ (void *)&g_sBulkDevice, // pvHandle
+ g_pucUSBRxBuffer, // pcBuffer
+ BULK_BUFFER_SIZE, // ulBufferSize
+ g_pucRxBufferWorkspace // pvWorkspace
+};
diff --git a/firmware/usb_bulk_structs.h b/firmware/usb_bulk_structs.h
new file mode 100644
index 0000000..f8abe03
--- /dev/null
+++ b/firmware/usb_bulk_structs.h
@@ -0,0 +1,44 @@
+//*****************************************************************************
+//
+// usb_bulk_structs.h - Data structures defining this bulk USB device.
+//
+// Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 9453 of the EK-LM4F120XL Firmware Package.
+//
+//*****************************************************************************
+
+#ifndef _USB_BULK_STRUCTS_H_
+#define _USB_BULK_STRUCTS_H_
+
+//*****************************************************************************
+//
+// The size of the transmit and receive buffers used. 256 is chosen pretty
+// much at random though the buffer should be at least twice the size of
+// a maximum-sized USB packet.
+//
+//*****************************************************************************
+#define BULK_BUFFER_SIZE 256
+
+extern unsigned long RxHandler(void *pvCBData, unsigned long ulEvent,
+ unsigned long ulMsgValue, void *pvMsgData);
+
+extern const tUSBBuffer g_sRxBuffer;
+extern const tUSBDBulkDevice g_sBulkDevice;
+extern unsigned char g_pucUSBRxBuffer[];
+
+#endif
diff --git a/firmware/usb_dev_bulk.ld b/firmware/usb_dev_bulk.ld
new file mode 100644
index 0000000..119dcbf
--- /dev/null
+++ b/firmware/usb_dev_bulk.ld
@@ -0,0 +1,57 @@
+/******************************************************************************
+ *
+ * usb_dev_bulk.ld - Linker configuration file for usb_dev_bulk.
+ *
+ * Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved.
+ * Software License Agreement
+ *
+ * Texas Instruments (TI) is supplying this software for use solely and
+ * exclusively on TI's microcontroller products. The software is owned by
+ * TI and/or its suppliers, and is protected under applicable copyright
+ * laws. You may not combine this software with "viral" open-source
+ * software in order to form a larger program.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+ * NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+ * NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+ * CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+ * DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ * This is part of revision 9453 of the EK-LM4F120XL Firmware Package.
+ *
+ *****************************************************************************/
+
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
+ SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
+}
+
+SECTIONS
+{
+ .text :
+ {
+ _text = .;
+ KEEP(*(.isr_vector))
+ *(.text*)
+ *(.rodata*)
+ _etext = .;
+ } > FLASH
+
+ .data : AT(ADDR(.text) + SIZEOF(.text))
+ {
+ _data = .;
+ *(vtable)
+ *(.data*)
+ _edata = .;
+ } > SRAM
+
+ .bss :
+ {
+ _bss = .;
+ *(.bss*)
+ *(COMMON)
+ _ebss = .;
+ } > SRAM
+}
diff --git a/stellaris b/stellaris
new file mode 160000
+Subproject 81a4be30dd1f008c7df6bd853b4d93c292fdc7c