├── .ccsproject
├── .cproject
├── .project
├── README.md
├── Release
└── CSR_USB-SPI_TivaC_Launchpad.bin
├── csrspi.c
├── csrspi.h
├── main.c
├── startup_ccs.c
├── tm4c123gh6pm.cmd
├── usb_structs.c
└── usb_structs.h
/.ccsproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
49 |
50 |
56 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
78 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
138 |
139 |
145 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
167 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | CSR_USB-SPI_TivaC_Launchpad
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
15 | full,incremental,
16 |
17 |
18 |
19 |
20 |
21 | com.ti.ccstudio.core.ccsNature
22 | org.eclipse.cdt.core.cnature
23 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
24 | org.eclipse.cdt.core.ccnature
25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
26 |
27 |
28 |
29 | utils/uartstdio.c
30 | 1
31 | SW_ROOT/utils/uartstdio.c
32 |
33 |
34 | utils/ustdlib.c
35 | 1
36 | SW_ROOT/utils/ustdlib.c
37 |
38 |
39 |
40 |
41 | ORIGINAL_PROJECT_ROOT
42 | file:/F:/devtools/tiva/Tivaware2/examples/boards/ek-tm4c123gxl/usb_dev_serial/ccs/
43 |
44 |
45 | SW_ROOT
46 | $%7BPARENT-5-ORIGINAL_PROJECT_ROOT%7D
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | CsrUsbSpiDevice-Tiva
2 | ===
3 | Description
4 | ---
5 | This is a reverse engineered re-implementation of CSR's USB<->SPI Converter on a TI Stellaris Launchpad. It is compatible with CSR's own drivers and BlueSuite tools, and should work on any BlueCore chip that supports programming through SPI.
6 |
7 | Original version by Frans-Willem for original Stellaris Launchpad - https://github.com/Frans-Willem/CsrUsbSpiDeviceRE
8 |
9 | Minor tweaks to build under TivaWare Launchpad part # EK-TM4C123GXL by Richard Aplin, Dec2013
10 | Turbo mode (which may or may not work for you; YMMV) by Rich also.
11 |
12 | Disclaimer
13 | ---
14 | I make no guarantees about this code. For me it worked, but it might not for you. If you break your BlueCore module or anything else by using this software this is your own responsibility.
15 |
16 | How to use
17 | ---
18 | * Get a TI Tiva C Launchpad (EK-TM4C123GXL, $12 at time of writing)
19 |
20 | * Connect your BlueCore module. 3.3v -> 3.3v, GND -> GND, PC4 -> SPI_CSB, PC5 -> SPI_MOSI, PC6 -> SPI_MISO, PC7 -> SPI_CLK. (PC4 - PC7 are located on the second column from the right)
21 |
22 | EITHER Build from source:
23 | * Install from TI site: TivaWare, TI's Code Composer (free with the launchpad)
24 | * Import this project into Code composer as usual.
25 | * Ensure SW_ROOT is set to your TivaWare directory in *both* of these locations:
26 | * Project -> Properties -> Resource -> Linked Resources -> Path Variables -> SW_ROOT
27 | * Window -> Preferences -> C/C++ -> Build -> Environment -> SW_ROOT.
28 | * Build using Project -> Build Project
29 | * Connect your Tiva C Launchpad with the microUSB port at the top (next to power select), and set power select to DEBUG.
30 | * Debug using Run -> Debug
31 | * When paused on main, do Run -> Resume
32 |
33 | OR just flash the supplied binary using LM Flash Programmer:
34 | * Run LM Flash Programmer (in TI toolkit), plug in Launchpad
35 | * On "Configuration" tab select TM4C123G Launchpad
36 | * On "Program" tab select the bin file Release\CSR_USB-SPI_TivaC_Launchpad.bin (included in this project)
37 | * Hit Program, you're done.
38 |
39 | FINALLY
40 | * Plug in "device" microUSB port to a host computer with CSR BlueSuite (or Bluelab) installed.
41 | * Device should be recognized, Drivers can be found at csrsupport.com (needs registration), underBrowse category tree -> Bluetooth PC Software/Tools -> USB-SPI Converter.
42 | * Use any of the BlueSuite or BlueLabs tools to play with your bluecore module! (BlueSuite can be found on CSRSupport.com under Browser category tree -> Bluetooth PC Software/Tools -> Current BlueSuite Development Tools)
43 | * Green led will light up during reading, Red during writing, Blue when using BCCMD's.
44 |
45 | Optional Turbo mode
46 | ---
47 | This is a hack. If you hold down the LEFT button on the launchpad when booting (i.e. when you first plug it in to USB after programming, or when hitting reset button) the SPI interface will run without any delays for flash page read/writes. This makes it *much* faster - standard mode takes 65sec to read 8mbit, turbo mode takes 25 seconds. If you want to use this speedup, you should ensure it works reliably on your CSR device; use BlueFlash to "dump" whatever is in flash, then Erase the whole chip, then reprogram from the dump.
48 | Turbo mode works fine for me (on a BlueCore4-EXT) but YMMV.
49 |
50 | Notes
51 | ---
52 | * The SPI clock may not be accurate (certainly not in Turbo mode)
53 | * The code was written to match CSR's original firmware as closely as possible, it might not be the most efficient way to things on the Stellaris.
54 | * If something does or does not work, let me know (Frans-Willem)
55 |
56 | TODO
57 | ---
58 | * Clean up: The code works, but should still be cleaned up, and some bits aren't fully reverse engineered yet (e.g. the BCCMD timeout)
59 | * Refactor/rewrite: The code as it is now is as close to CSR's code as I could get, but it's not the most readable. I intend to refactor this at some point (maybe in a different project) to make it more readable and portable to other platforms.
60 |
61 | Original code - and all the hard work - by Frans-Willem Dec2012; minor hacks and porting to TivaWare by Richard Aplin, Dec2013
62 |
--------------------------------------------------------------------------------
/Release/CSR_USB-SPI_TivaC_Launchpad.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raplin/CsrUsbSpiDeviceRE/b16d899565eee6a9a45f5a4c5c506ade42ca509c/Release/CSR_USB-SPI_TivaC_Launchpad.bin
--------------------------------------------------------------------------------
/csrspi.c:
--------------------------------------------------------------------------------
1 | /*
2 | * csrspi.c
3 | *
4 | * Created on: 2 jan. 2013
5 | * Author: Frans-Willem,
6 | * very small tweaks by Richard Aplin, Frans did all the hard work :-)
7 | */
8 | #include
9 | #include
10 | #include "inc/hw_ints.h"
11 | #include "inc/hw_memmap.h"
12 | #include "inc/hw_types.h"
13 | #include "driverlib/sysctl.h"
14 | #include "driverlib/rom.h"
15 | #include "driverlib/gpio.h"
16 |
17 | #define PIN_CS GPIO_PIN_4 //Equivalent of pin 0x1 in CSR code
18 | #define PIN_MISO GPIO_PIN_6 //Equivalent of pin 0x2 in CSR code
19 | #define PIN_MOSI GPIO_PIN_5 //Equivalent of pin 0x4 in CSR code
20 | #define PIN_CLK GPIO_PIN_7 //Equivalent of pin 0x8 in CSR code
21 | #define PIN_UNK GPIO_PIN_3 //Equivalent to pin 0x10 in CSR code
22 | #define PIN_ALL_OUT PIN_CS|PIN_MOSI|PIN_CLK|PIN_UNK
23 | #define PIN_ALL_IN PIN_MISO
24 | #define PORT_BASE GPIO_PORTC_BASE
25 |
26 | #define SET_CS() GPIOPinWrite(PORT_BASE, PIN_CS, PIN_CS)
27 | #define CLR_CS() GPIOPinWrite(PORT_BASE, PIN_CS, 0)
28 | #define SET_CLK() GPIOPinWrite(PORT_BASE, PIN_CLK, PIN_CLK)
29 | #define CLR_CLK() GPIOPinWrite(PORT_BASE, PIN_CLK, 0)
30 | #define SET_MOSI() GPIOPinWrite(PORT_BASE, PIN_MOSI, PIN_MOSI)
31 | #define CLR_MOSI() GPIOPinWrite(PORT_BASE, PIN_MOSI, 0)
32 | #define GET_MISO() GPIOPinRead(PORT_BASE, PIN_MISO)
33 |
34 |
35 | unsigned short g_nSpeed = 393;
36 | unsigned short g_nReadBits = 0;
37 | unsigned short g_nWriteBits = 0;
38 | unsigned short g_nBcA = 0;
39 | unsigned short g_nBcB = 0;
40 | unsigned short g_nUseSpecialRead = 0;
41 | unsigned short g_nFastSpiMode=0;
42 |
43 | void CsrInit() {
44 | //Initialize Port B
45 | SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
46 | GPIOPinTypeGPIOOutput(PORT_BASE, PIN_ALL_OUT);
47 | GPIOPadConfigSet(PORT_BASE, PIN_MISO, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
48 | }
49 |
50 | void CsrSpiEnableFastMode(void)
51 | {
52 | //Richard Aplin tweak for super fast flashing (optional; test it with BlueFlash first!)
53 | //Enabled by holding down left button on Launchpad board when it's powered up
54 | //Without this, BlueFlash does about 2sectors/sec (65sec to dump 8mbits)
55 | //WITH this it does about 5/sec (26sec to dump 8mbit)
56 | //Works fine for me, but...
57 | //TEST ON YOUR OWN CHIP WITH BLUEFLASH DUMP/ERASE/VERIFY BEFORE REGULAR USE
58 | g_nFastSpiMode=1;
59 | }
60 |
61 |
62 | void CsrSpiDelay() {
63 | int kHz;
64 |
65 | if (g_nSpeed==4 && g_nFastSpiMode) return; //if usb host has specified 'fast' mode (Setspeed 0x0004) use practically no delay - works fine for me, but YMMV!
66 |
67 | kHz = 1000000 / (126 * g_nSpeed + 434);
68 | //Used to be 3000
69 | ROM_SysCtlDelay((SysCtlClockGet()/6000)/kHz);
70 | }
71 |
72 | //Equivalent of function at 022D
73 | void CsrSpiStart() {
74 | //022D
75 | //Unsets all outputs pins, sets unk and cs.
76 | GPIOPinWrite(PORT_BASE, PIN_ALL_OUT, PIN_UNK | PIN_CS);
77 | CsrSpiDelay();
78 | //0239
79 | GPIOPinWrite(PORT_BASE, PIN_ALL_OUT, PIN_UNK | PIN_CS | PIN_CLK);
80 | CsrSpiDelay();
81 | //023C
82 | GPIOPinWrite(PORT_BASE, PIN_ALL_OUT, PIN_UNK | PIN_CS);
83 | CsrSpiDelay();
84 | //023F
85 | GPIOPinWrite(PORT_BASE, PIN_ALL_OUT, PIN_UNK | PIN_CS | PIN_CLK);
86 | CsrSpiDelay();
87 | //0242
88 | GPIOPinWrite(PORT_BASE, PIN_ALL_OUT, PIN_UNK | PIN_CS);
89 | CsrSpiDelay();
90 | //0245
91 | GPIOPinWrite(PORT_BASE, PIN_ALL_OUT, PIN_UNK);
92 | CsrSpiDelay();
93 | //0247
94 | return;
95 | }
96 |
97 | //Equivalent of function at 0248
98 | void CsrSpiStop() {
99 | //Clears MOSI and CLK, sets CS and UNK
100 | GPIOPinWrite(PORT_BASE, PIN_ALL_OUT, PIN_UNK|PIN_CS);
101 | }
102 |
103 | //Equivalent of function at 0250
104 | //R10 is number of bits
105 | //R0 is what to send?
106 | //Normally R7 and R8 hold the first and second delay function, but I opted for a bool instead
107 | void CsrSpiSendBits(unsigned int nData, unsigned int nBits) {
108 | //CsrTransfer(nData, (1<<(nBits-1)));
109 | //return;
110 | unsigned char nClkLow = 0; //R2
111 | unsigned char nClkHigh = PIN_CLK; //R3
112 | nData <<= 24 - nBits; //Could've gone with 32, but hey, who cares
113 | while (nBits--) {
114 | GPIOPinWrite(PORT_BASE, PIN_CLK|PIN_MOSI|PIN_CS, nClkLow);
115 | if (nData & 0x800000) nClkHigh |= PIN_MOSI;
116 | nClkLow = nClkHigh - PIN_CLK;
117 | CsrSpiDelay();
118 | GPIOPinWrite(PORT_BASE, PIN_MOSI|PIN_CS, nClkHigh);
119 | GPIOPinWrite(PORT_BASE, PIN_CLK|PIN_MOSI|PIN_CS, nClkHigh);
120 | CsrSpiDelay();
121 | nClkHigh = PIN_CLK;
122 | nData <<= 1;
123 | }
124 | }
125 |
126 | //Equivalent of function at 0263
127 | //nBits = R10?
128 | unsigned int CsrSpiReadBits(unsigned int nBits) {
129 | //return CsrTransfer(0, (1<<(nBits-1)));
130 | unsigned int nRetval = 0;
131 | //CSR code disables interrupts here
132 | while (nBits--) {
133 | GPIOPinWrite(PORT_BASE, PIN_CLK, 0);
134 | CsrSpiDelay();
135 | nRetval <<= 1;
136 | GPIOPinWrite(PORT_BASE, PIN_CLK, PIN_CLK);
137 | CsrSpiDelay();
138 | if (GPIOPinRead(PORT_BASE, PIN_MISO))
139 | nRetval |= 1;
140 | }
141 | //CSR code re-enables interrupts here
142 | return nRetval & 0xFFFF;
143 | }
144 |
145 | //Equivalent of function at 0279
146 | int CsrSpiReadBasic(unsigned short nAddress, unsigned short nLength, unsigned short *pnOutput) {
147 | nLength--; //Do one loop less, last word is read differently
148 | CsrSpiStart();
149 | unsigned int nCommand = ((g_nReadBits | 3) << 16) | nAddress;
150 | unsigned int nControl;
151 | CsrSpiSendBits(nCommand, 24);
152 | /*
153 | * Inbetween these commands is an if-statement with some high-speed optimizations for if the spi delay = 0
154 | */
155 | nControl = CsrSpiReadBits(16);
156 | if (nControl != ((nCommand >> 8) & 0xFFFF)) {
157 | //In CSR's code, this is at the bottom, 02B7
158 | CsrSpiStart(); //Not sure why we call this again
159 | CsrSpiStop();
160 | return 0;
161 | }
162 | //Loop at 296 - 029B
163 | while (nLength--) {
164 | *(pnOutput++)=CsrSpiReadBits(16);
165 | }
166 | //From 19D to 2A2 some more speed optimized code that we don't need
167 | unsigned short nLast = CsrSpiReadBits(15);
168 | GPIOPinWrite(PORT_BASE, PIN_CLK, 0);
169 | CsrSpiDelay(); CsrSpiDelay(); CsrSpiDelay(); CsrSpiDelay();
170 | nLast <<= 1;
171 | if (GPIOPinRead(PORT_BASE, PIN_MISO))
172 | nLast |= 1;
173 | *(pnOutput++) = nLast;
174 | CsrSpiStart(); //Not sure why we call this again
175 | CsrSpiStop();
176 | return 1;
177 | }
178 |
179 | //Equivalent of function at 02BB
180 | int CsrSpiRead(unsigned short nAddress, unsigned short nLength, unsigned short *pnOutput) {
181 | int nRet = 1;
182 | if (!g_nUseSpecialRead)
183 | return CsrSpiReadBasic(nAddress,nLength,pnOutput);
184 | nLength--;
185 | nRet &= CsrSpiReadBasic(nAddress, nLength, pnOutput);
186 | g_nReadBits |= 0x20;
187 | nRet &= CsrSpiReadBasic(nAddress + nLength, 1, &pnOutput[nLength]);
188 | g_nReadBits &= ~0x20;
189 | return nRet;
190 | }
191 |
192 | //Equivalent of 02CE
193 | void CsrSpiWrite(unsigned short nAddress, unsigned short nLength, unsigned short *pnInput) {
194 | CsrSpiStart();
195 | // Some speed optimizing code from 02D2 to 02D8
196 | unsigned int nCommand = ((g_nWriteBits | 2) << 16) | nAddress;
197 | CsrSpiSendBits(nCommand, 24);
198 | while (nLength--)
199 | CsrSpiSendBits(*(pnInput++), 16);
200 | CsrSpiStart();
201 | CsrSpiStop();
202 | }
203 |
204 | int CsrSpiIsStopped() {
205 | unsigned short nOldSpeed = g_nSpeed;
206 | g_nSpeed += 32;
207 | CsrSpiStart();
208 | g_nSpeed = nOldSpeed;
209 | unsigned char nRead = GPIOPinRead(PORT_BASE, PIN_MISO);
210 | CsrSpiStop();
211 | if (nRead) return 1;
212 | return 0;
213 | }
214 |
215 | //0x47F
216 | //R1 seems to be used as return value
217 | int CsrSpiBcOperation(unsigned short nOperation /* R2 */) {
218 | unsigned short var0, var1 = 0;
219 | int i;
220 | CsrSpiRead(g_nBcA, 1, &var0);
221 | CsrSpiWrite(g_nBcB, 1, &nOperation);
222 | CsrSpiWrite(g_nBcA, 1, &var0);
223 | for (i=0; i<30; i++) {
224 | CsrSpiRead(g_nBcB, 1, &var1);
225 | if (nOperation != var1)
226 | return var1;
227 | }
228 | return var1;
229 | }
230 |
231 | int CsrSpiBcCmd(unsigned short nLength, unsigned short *pnData) {
232 | unsigned short var1,var2;
233 | int i;
234 | if (CsrSpiBcOperation(0x7) != 0)
235 | return 0;
236 | CsrSpiWrite(g_nBcB + 1, 1, &nLength);
237 | if (CsrSpiBcOperation(0x1) != 2)
238 | return 0;
239 | if (!CsrSpiRead(g_nBcB + 2, 1, &var1))
240 | return 0;
241 | CsrSpiWrite(var1, nLength, pnData);
242 | CsrSpiBcOperation(0x4);
243 | for (i=0; i<30; i++) {
244 | if (CsrSpiRead(g_nBcB, 1, &var2) && var2 == 0x6) {
245 | CsrSpiRead(var1, nLength, pnData);
246 | CsrSpiBcOperation(0x7);
247 | return 1;
248 | }
249 | }
250 | return 0;
251 | }
252 | /*
253 | void CsrReset() {
254 | SET_CS(); CsrDelay();
255 | SET_CLK(); CsrDelay();
256 | CLR_CLK(); CsrDelay();
257 | SET_CLK(); CsrDelay();
258 | CLR_CLK(); CsrDelay();
259 | }
260 |
261 | void CsrStart() {
262 | CsrReset();
263 | CLR_CS(); CsrDelay();
264 | }
265 |
266 | void CsrStop() {
267 | SET_CS();
268 | }
269 |
270 | unsigned int CsrTransfer(unsigned int nInput, unsigned int msb) {
271 | unsigned int nOutput = 0;
272 | while (msb) {
273 | if (nInput & msb) SET_MOSI();
274 | else CLR_MOSI();
275 | msb >>= 1;
276 | CsrDelay();
277 | SET_CLK();
278 | CsrDelay();
279 | nOutput <<= 1;
280 | if (GET_MISO()) nOutput |= 1;
281 | CLR_CLK();
282 | }
283 | return nOutput;
284 | }
285 |
286 | int CsrRead(unsigned short nAddress, unsigned short nLength, unsigned short *pnOutput) {
287 | unsigned int nCommand;
288 | unsigned int nControl;
289 | nCommand = 3 | (g_nReadBits & ~3);
290 | CsrStart();
291 | CsrTransfer(nCommand, 0x80);
292 | CsrTransfer(nAddress, 0x8000);
293 | nControl = CsrTransfer(0, 0x8000);
294 | unsigned int nExpected = ((nCommand & 0xFF) << 8) | ((nAddress >> 8) & 0xFF);
295 | //UARTprintf("Expected: %04X, Control: %04X\n",nExpected,nControl);
296 | if (nExpected != nControl) {
297 | CsrStop();
298 | return 0;
299 | }
300 | while (nLength--) {
301 | *(pnOutput++) = CsrTransfer(0, 0x8000);
302 | }
303 | CsrStop();
304 | return 1;
305 | }
306 |
307 | int CsrWrite(unsigned short nAddress, unsigned short nLength, unsigned short *pnInput) {
308 | unsigned int nCommand;
309 | nCommand = 2;
310 | CsrStart();
311 | CsrTransfer(nCommand, 0x80);
312 | CsrTransfer(nAddress, 0x8000);
313 | while (nLength--)
314 | CsrTransfer(*(pnInput++), 0x8000);
315 | CsrStop();
316 | return 1;
317 | }
318 |
319 | int CsrStopped() {
320 | unsigned int nControl, nCheck;
321 | CsrStart();
322 | nCheck = CsrTransfer(3, 0x80);
323 | CsrTransfer(0xFF9A, 0x8000);
324 | nControl = CsrTransfer(0, 0x8000);
325 | if (nControl != 0x3FF) {
326 | return -1;
327 | }
328 | return (nCheck ? 1 : 0);
329 | }*/
330 |
--------------------------------------------------------------------------------
/csrspi.h:
--------------------------------------------------------------------------------
1 | /*
2 | * csrspi.h
3 | *
4 | * Created on: 2 jan. 2013
5 | * Author: Frans-Willem
6 | */
7 |
8 | #ifndef CSRSPI_H_
9 | #define CSRSPI_H_
10 |
11 | extern unsigned short g_nSpeed;
12 | extern unsigned short g_nReadBits;
13 | extern unsigned short g_nWriteBits;
14 | extern unsigned short g_nBcA;
15 | extern unsigned short g_nBcB;
16 |
17 | void CsrInit();
18 | int CsrSpiRead(unsigned short nAddress, unsigned short nLength, unsigned short *pnOutput);
19 | void CsrSpiWrite(unsigned short nAddress, unsigned short nLength, unsigned short *pnInput);
20 | int CsrSpiIsStopped();
21 | int CsrSpiBcOperation(unsigned short nOperation);
22 | int CsrSpiBcCmd(unsigned short nLength, unsigned short *pnData);
23 | void CsrSpiEnableFastMode(void);
24 | #endif /* CSRSPI_H_ */
25 |
--------------------------------------------------------------------------------
/main.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Frans-Willem
3 | * Minor tweak for Tivaware compatibility by Richard Aplin, Dec2013
4 | *
5 | * This version runs on TI Tiva C series Launchpad - part # TM4C123G , costs USD$12 at time of writing, CSR dongle costs ~$250
6 | *
7 | * Connect:
8 | *
9 | *
10 | */
11 |
12 | //two new includes for Tivaware types
13 | #include
14 | #include
15 |
16 | #include "inc/hw_ints.h"
17 | #include "inc/hw_memmap.h"
18 | #include "inc/hw_types.h"
19 | #include "driverlib/debug.h"
20 | #include "driverlib/fpu.h"
21 | #include "driverlib/gpio.h"
22 | #include "driverlib/interrupt.h"
23 | #include "driverlib/pin_map.h"
24 | #include "driverlib/sysctl.h"
25 | #include "driverlib/systick.h"
26 | #include "driverlib/timer.h"
27 | #include "driverlib/uart.h"
28 | #include "driverlib/rom.h"
29 | #include "usblib/usblib.h"
30 | #include "usblib/usb-ids.h"
31 | #include "usblib/device/usbdevice.h"
32 | #include "usblib/device/usbdbulk.h"
33 | #include "utils/uartstdio.h"
34 | #include "utils/ustdlib.h"
35 | #include "usb_structs.h"
36 | #include "csrspi.h"
37 |
38 |
39 | #define SYSCTL_PERIPH_LEDS SYSCTL_PERIPH_GPIOF
40 | #define GPIO_PORT_LEDS_BASE GPIO_PORTF_BASE
41 | #define GPIO_PIN_LED_R GPIO_PIN_1
42 | #define GPIO_PIN_LED_G GPIO_PIN_3
43 | #define GPIO_PIN_LED_B GPIO_PIN_2
44 |
45 | #define BUTTONS_GPIO_PERIPH SYSCTL_PERIPH_GPIOF
46 | #define BUTTONS_GPIO_BASE GPIO_PORTF_BASE
47 | #define NUM_BUTTONS 2
48 | #define LEFT_BUTTON GPIO_PIN_4
49 | #define RIGHT_BUTTON GPIO_PIN_0
50 | #define ALL_BUTTONS (LEFT_BUTTON | RIGHT_BUTTON)
51 |
52 | #define BUFFER_SIZE 1024
53 |
54 | #define CPU_CLOCK_100MHZ //else 80mhz, both work for me
55 |
56 | //#define PRINT_PROTOCOL 1 //debug info
57 |
58 | //typedef unsigned int size_t; //removed for tivaware
59 |
60 | unsigned char pReceiveBuffer[BUFFER_SIZE];
61 | volatile size_t nReceiveLength;
62 | volatile int bReceiving = 1;
63 |
64 | unsigned char pTransmitBuffer[BUFFER_SIZE];
65 | volatile size_t nTransmitLength;
66 | volatile size_t nTransmitOffset;
67 | volatile int bTransmitting = 0;
68 |
69 | #define MODE_SPI 0
70 | #define MODE_JTAG 0xFFFF;
71 | unsigned short g_nMode = MODE_SPI;
72 |
73 | #define CMD_READ 0x0100
74 | #define CMD_WRITE 0x0200
75 | #define CMD_SETSPEED 0x0300
76 | #define CMD_GETSTOPPED 0x0400
77 | #define CMD_GETSPEED 0x0500
78 | #define CMD_UPDATE 0x0600
79 | #define CMD_GETSERIAL 0x0700
80 | #define CMD_GETVERSION 0x0800
81 | #define CMD_SETMODE 0x0900
82 | #define CMD_SETBITS 0x0F00
83 | #define CMD_BCCMDINIT 0x4000
84 | #define CMD_BCCMD 0x4100
85 |
86 | void WriteWord(unsigned char *szOffset, unsigned short n) {
87 | szOffset[1] = n & 0xFF;
88 | szOffset[0] = (n >> 8) & 0xFF;
89 | }
90 |
91 | unsigned short ReadWord(unsigned char *szOffset) {
92 | return (szOffset[0] << 8) | szOffset[1];
93 | }
94 |
95 | void TransmitWord(unsigned short n) {
96 | if (nTransmitLength + 2 < BUFFER_SIZE) {
97 | WriteWord(&pTransmitBuffer[nTransmitLength], n);
98 | nTransmitLength += 2;
99 | }
100 | }
101 |
102 | void TransmitDWord(unsigned int n) {
103 | TransmitWord((n >> 16) & 0xFFFF);
104 | TransmitWord(n & 0xFFFF);
105 | }
106 |
107 | int CmdRead(unsigned short nAddress, unsigned short nLength);
108 | int CmdWrite(unsigned short nAddress, unsigned short nLength, unsigned char *pData);
109 | int CmdSetSpeed(unsigned short nSpeed);
110 | int CmdGetStopped();
111 | int CmdGetSpeed();
112 | int CmdUpdate();
113 | int CmdGetSerial();
114 | int CmdGetVersion();
115 | int CmdSetMode(unsigned short nMode);
116 | int CmdSetBits(unsigned short nWhich, unsigned short nValue);
117 | void CmdBcCmdInit(unsigned short nA, unsigned short nB);
118 | int CmdBcCmd(unsigned short nLength, unsigned char *pData);
119 |
120 | void TransmitCallback() {
121 | size_t nPacket;
122 | if (bTransmitting) {
123 | nPacket = nTransmitLength - nTransmitOffset;
124 | if (nPacket > 64)
125 | nPacket = 64;
126 | USBDBulkPacketWrite((void *)&g_sBulkDevice, &pTransmitBuffer[nTransmitOffset], nPacket, true);
127 | nTransmitOffset += nPacket;
128 | if (nPacket < 64)
129 | bTransmitting = 0;
130 | }
131 | }
132 | void StartTransmit() {
133 | nTransmitOffset = 0;
134 | bTransmitting = 1;
135 | if (USBDBulkTxPacketAvailable((void *)&g_sBulkDevice))
136 | TransmitCallback();
137 | }
138 | void WaitTransmit() {
139 | while (bTransmitting);
140 | nTransmitLength = nTransmitOffset = 0;
141 | }
142 |
143 |
144 | //*****************************************************************************
145 | //
146 | // Configure the UART and its pins. This must be called before UARTprintf().
147 | // (Tivaware tweak)
148 | //*****************************************************************************
149 | void
150 | ConfigureUART(void)
151 | {
152 | //
153 | // Enable the GPIO Peripheral used by the UART.
154 | //
155 | ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
156 |
157 | //
158 | // Enable UART0
159 | //
160 | ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
161 |
162 | //
163 | // Configure GPIO Pins for UART mode.
164 | //
165 | ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
166 | ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
167 | ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
168 |
169 | //
170 | // Use the internal 16MHz oscillator as the UART clock source.
171 | //
172 | UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
173 |
174 | //
175 | // Initialize the UART for console I/O.
176 | //
177 | UARTStdioConfig(0, 115200, 16000000);
178 | }
179 |
180 | void InitButtons(void)
181 | {
182 | // Set each of the button GPIO pins as an input with a pull-up.
183 | ROM_GPIODirModeSet(BUTTONS_GPIO_BASE, ALL_BUTTONS, GPIO_DIR_MODE_IN);
184 | ROM_GPIOPadConfigSet(BUTTONS_GPIO_BASE, ALL_BUTTONS,
185 | GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
186 | }
187 |
188 | /*
189 | * main.c
190 | */
191 | void main(void) {
192 | size_t nOffset;
193 | unsigned short nCommand, nArgs[4];
194 | uint32_t buttons;
195 |
196 | #ifndef CPU_CLOCK_100MHZ
197 | //Set Clock at 80MHz
198 | ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
199 | #else
200 | //Hey what the hell, let's run at 100Mhz, why not?
201 | ROM_SysCtlClockSet(SYSCTL_SYSDIV_2 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
202 | #endif
203 | //Enable UART on Port A
204 | ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
205 | GPIOPinConfigure(GPIO_PA0_U0RX);
206 | GPIOPinConfigure(GPIO_PA1_U0TX);
207 | ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
208 | //Do some output!
209 | ConfigureUART(); //UARTStdioInit(0); tivaware tweak
210 | UARTprintf("CSR USB-SPI Emulator for Tiva Launchpad by Frans-Willem 2012,\n tweaked by Richard Aplin 2013\n");
211 |
212 | UARTprintf("CPU Clock %dMhz\n",SysCtlClockGet()/1000000);
213 |
214 | //Csr SPI init
215 | CsrInit();
216 | UARTprintf("CSR initialized\n");
217 |
218 | //Status LEDs Init
219 | SysCtlPeripheralEnable(SYSCTL_PERIPH_LEDS);
220 | InitButtons();
221 | GPIOPinTypeGPIOOutput(GPIO_PORT_LEDS_BASE, GPIO_PIN_LED_R|GPIO_PIN_LED_G|GPIO_PIN_LED_B);
222 | GPIOPinWrite(GPIO_PORT_LEDS_BASE, GPIO_PIN_LED_R|GPIO_PIN_LED_G|GPIO_PIN_LED_B, 0);
223 | UARTprintf("LEDs initialized\n");
224 |
225 | //check for left button (NOT) being held down on boot for FAST mode
226 | buttons=ROM_GPIOPinRead(BUTTONS_GPIO_BASE, LEFT_BUTTON);
227 | if (!buttons){
228 | UARTprintf("FAST SPI mode enabled - test reliability with BlueFlash before using!\n");
229 | CsrSpiEnableFastMode();
230 | }else{
231 | UARTprintf("Regular (slow) SPI mode enabled\n");
232 | }
233 |
234 | //USB init?
235 | ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
236 | ROM_GPIOPinTypeUSBAnalog(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5);
237 |
238 | USBStackModeSet(0, eUSBModeForceDevice, 0); //tivaware tweak
239 | USBDBulkInit(0, (tUSBDBulkDevice *)&g_sBulkDevice);
240 | UARTprintf("Waiting for host...\n");
241 |
242 | while (1) {
243 | while (bReceiving); //Wait until we're ready receiving data
244 | if (nReceiveLength == 0) {
245 | UARTprintf("Empty packet...\n");
246 | } else {
247 | WaitTransmit();
248 | if (pReceiveBuffer[0] != '\0') {
249 | UARTprintf("Invalid start byte\n");
250 | } else {
251 | nOffset = 1;
252 | while (nReceiveLength >= nOffset + 2) {
253 | nCommand = ReadWord(&pReceiveBuffer[nOffset]);
254 | nOffset += 2;
255 | switch (nCommand) {
256 | case CMD_READ:
257 | if (nReceiveLength < nOffset + 4) {
258 | UARTprintf("Too few arguments to read\n");
259 | } else {
260 | nArgs[0] = ReadWord(&pReceiveBuffer[nOffset]);
261 | nOffset += 2;
262 | nArgs[1] = ReadWord(&pReceiveBuffer[nOffset]);
263 | nOffset += 2;
264 | #if PRINT_PROTOCOL
265 | UARTprintf("CMD_READ %04x %04x\n",nArgs[0],nArgs[1]);
266 | #endif
267 | CmdRead(nArgs[0], nArgs[1]);
268 | }
269 | break;
270 | case CMD_WRITE:
271 | if (nReceiveLength < nOffset + 4) {
272 | UARTprintf("Too few arguments to write\n");
273 | } else {
274 | nArgs[0] = ReadWord(&pReceiveBuffer[nOffset]);
275 | nOffset += 2;
276 | nArgs[1] = ReadWord(&pReceiveBuffer[nOffset]);
277 | nOffset += 2;
278 | if (nReceiveLength < nOffset + (nArgs[1] * 2)) {
279 | UARTprintf("Too few arguments to write\n");
280 | } else {
281 | #if PRINT_PROTOCOL
282 | UARTprintf("CMD_WRITE %04x %04x\n",nArgs[0],nArgs[1]);
283 | #endif
284 | CmdWrite(nArgs[0], nArgs[1], &pReceiveBuffer[nOffset]);
285 | nOffset+=nArgs[1] * 2;
286 | }
287 | }
288 | break;
289 | case CMD_SETSPEED:
290 | if (nReceiveLength < nOffset + 2) {
291 | UARTprintf("Too few arguments to set speed\n");
292 | } else {
293 | nArgs[0] = ReadWord(&pReceiveBuffer[nOffset]);
294 | nOffset += 2;
295 | #if PRINT_PROTOCOL
296 | UARTprintf("CMD_SETSPEED %04x\n",nArgs[0]);
297 | #endif
298 | CmdSetSpeed(nArgs[0]);
299 | }
300 | break;
301 | case CMD_GETSTOPPED:
302 | CmdGetStopped();
303 | break;
304 | case CMD_GETSPEED:
305 | CmdGetSpeed();
306 | break;
307 | case CMD_UPDATE:
308 | #if PRINT_PROTOCOL
309 | UARTprintf("CMD_UPDATE\n");
310 | #endif
311 | CmdUpdate();
312 | break;
313 | case CMD_GETSERIAL:
314 | CmdGetSerial();
315 | break;
316 | case CMD_GETVERSION:
317 | CmdGetVersion();
318 | break;
319 | case CMD_SETMODE:
320 | if (nReceiveLength < nOffset + 2) {
321 | UARTprintf("Too few arguments to set mode\n");
322 | } else {
323 | nArgs[0] = ReadWord(&pReceiveBuffer[nOffset]);
324 | nOffset += 2;
325 | #if PRINT_PROTOCOL
326 | UARTprintf("CMD_SETMODE %04x\n",nArgs[0]);
327 | #endif
328 | CmdSetMode(nArgs[0]);
329 | }
330 | break;
331 | case CMD_SETBITS:
332 | if (nReceiveLength < nOffset + 4) {
333 | UARTprintf("Too few arguments to set bits\n");
334 | } else {
335 | nArgs[0] = ReadWord(&pReceiveBuffer[nOffset]);
336 | nOffset += 2;
337 | nArgs[1] = ReadWord(&pReceiveBuffer[nOffset]);
338 | nOffset += 2;
339 | #if PRINT_PROTOCOL
340 | UARTprintf("CMD_SETBITS %04x %04x\n",nArgs[0],nArgs[1]);
341 | #endif
342 | CmdSetBits(nArgs[0], nArgs[1]);
343 | }
344 | break;
345 | case CMD_BCCMDINIT:
346 | if (nReceiveLength < nOffset + 4) {
347 | UARTprintf("Too few arguments to init bccmd\n");
348 | } else {
349 | nArgs[0] = ReadWord(&pReceiveBuffer[nOffset]);
350 | nOffset += 2;
351 | nArgs[1] = ReadWord(&pReceiveBuffer[nOffset]);
352 | nOffset += 2;
353 | #if PRINT_PROTOCOL
354 | UARTprintf("CMD_BCCMDINIT %04x %04x\n",nArgs[0],nArgs[1]);
355 | #endif
356 | CmdBcCmdInit(nArgs[0], nArgs[1]);
357 | }
358 | break;
359 | case CMD_BCCMD:
360 | if (nReceiveLength < nOffset + 2) {
361 | UARTprintf("Too few arguments to bccmd\n");
362 | } else {
363 | nArgs[0] = ReadWord(&pReceiveBuffer[nOffset]);
364 | nOffset += 2;
365 | if (nReceiveLength < nOffset + (nArgs[0] * 2)) {
366 | UARTprintf("Too few arguments to bccmd\n");
367 | } else {
368 | #if PRINT_PROTOCOL
369 | UARTprintf("CMD_BCCMD %04x\n",nArgs[0]);
370 | #endif
371 | CmdBcCmd(nArgs[0], &pReceiveBuffer[nOffset]);
372 | nOffset+=nArgs[0] * 2;
373 | }
374 | }
375 | break;
376 | default:
377 | UARTprintf("Unknown command: %04X", nCommand);
378 | nOffset = nReceiveLength;
379 | continue;
380 | }
381 | nOffset += 2; //Read the two inbetween bytes
382 | }
383 | }
384 | if (nTransmitLength)
385 | StartTransmit();
386 | }
387 |
388 | //Get ready for the next packet
389 | nReceiveLength = 0;
390 | bReceiving = 1;
391 | }
392 | }
393 |
394 | uint32_t TxHandler(void *pvi32CBData, uint32_t ulEvent,
395 | uint32_t ulMsgValue, void *pvMsgData)
396 | /*unsigned long
397 | TxHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue,
398 | void *pvMsgData)*/
399 | {
400 | if(ulEvent == USB_EVENT_TX_COMPLETE)
401 | {
402 | TransmitCallback();
403 | }
404 | return(0);
405 | }
406 |
407 | unsigned short pCsrBuffer[1024];
408 |
409 |
410 | int CmdRead(unsigned short nAddress, unsigned short nLength) {
411 | unsigned short *pCurrent;
412 | GPIOPinWrite(GPIO_PORT_LEDS_BASE, GPIO_PIN_LED_G, GPIO_PIN_LED_G);
413 | if (g_nMode == MODE_SPI && nLength < 1024 && CsrSpiRead(nAddress,nLength,pCsrBuffer)) {
414 | GPIOPinWrite(GPIO_PORT_LEDS_BASE, GPIO_PIN_LED_G, 0);
415 | TransmitWord(CMD_READ);
416 | TransmitWord(nAddress);
417 | TransmitWord(nLength);
418 | pCurrent = pCsrBuffer;
419 | while (nLength--) {
420 | TransmitWord(*(pCurrent++));
421 | }
422 | } else {
423 | GPIOPinWrite(GPIO_PORT_LEDS_BASE, GPIO_PIN_LED_G, 0);
424 | UARTprintf("Read Failed\n");
425 | TransmitWord(CMD_READ + 1);
426 | TransmitWord(nAddress);
427 | TransmitWord(nLength);
428 | while (nLength--)
429 | TransmitWord(0);
430 | }
431 | return 1;
432 | }
433 | int CmdWrite(unsigned short nAddress, unsigned short nLength, unsigned char *pData) {
434 | if (nLength > 1024 || g_nMode != MODE_SPI)
435 | return 0;
436 | unsigned short i;
437 | for (i = 0; i < nLength; i++) {
438 | pCsrBuffer[i] = ReadWord(&pData[i * 2]);
439 | }
440 | GPIOPinWrite(GPIO_PORT_LEDS_BASE, GPIO_PIN_LED_R, GPIO_PIN_LED_R);
441 | CsrSpiWrite(nAddress, nLength, pCsrBuffer);
442 | GPIOPinWrite(GPIO_PORT_LEDS_BASE, GPIO_PIN_LED_R, 0);
443 | return 1;
444 | }
445 | int CmdSetSpeed(unsigned short nSpeed) {
446 | g_nSpeed = nSpeed;
447 | return 1;
448 | }
449 | int CmdGetStopped() {
450 | TransmitWord(CMD_GETSTOPPED);
451 | TransmitWord(g_nMode != MODE_SPI || CsrSpiIsStopped()); //TODO
452 | return 1;
453 | }
454 | int CmdGetSpeed() {
455 | TransmitWord(CMD_GETSPEED);
456 | TransmitWord(g_nSpeed);
457 | return 1;
458 | }
459 | int CmdUpdate() {
460 | return 1;
461 | }
462 | int CmdGetSerial() {
463 | TransmitWord(CMD_GETSERIAL);
464 | TransmitDWord(31337);
465 | return 1;
466 | }
467 | int CmdGetVersion() {
468 | TransmitWord(CMD_GETVERSION);
469 | TransmitWord(0x119);
470 | return 1;
471 | }
472 | int CmdSetMode(unsigned short nMode) {
473 | g_nMode = nMode;
474 | return 1;
475 | }
476 | int CmdSetBits(unsigned short nWhich, unsigned short nValue) {
477 | if (nWhich) g_nWriteBits = nValue;
478 | else g_nReadBits = nValue;
479 | return 1;
480 | }
481 |
482 | void CmdBcCmdInit(unsigned short nA, unsigned short nB) {
483 | UARTprintf("BCCMD Init: %04X %04X\n", nA, nB);
484 | g_nBcA = nA;
485 | g_nBcB = nB;
486 | }
487 |
488 | int CmdBcCmd(unsigned short nLength, unsigned char *pData) {
489 | unsigned short i;
490 | //UARTprintf("BCCMD input:\n");
491 | for (i = 0; i < nLength; i++) {
492 | pCsrBuffer[i] = ReadWord(&pData[i*2]);
493 | }
494 | GPIOPinWrite(GPIO_PORT_LEDS_BASE, GPIO_PIN_LED_B, GPIO_PIN_LED_B);
495 | if (CsrSpiBcCmd(nLength, pCsrBuffer)) {
496 | TransmitWord(CMD_BCCMD);
497 | } else {
498 | TransmitWord(CMD_BCCMD + 1);
499 | }
500 | GPIOPinWrite(GPIO_PORT_LEDS_BASE, GPIO_PIN_LED_B, 0);
501 | TransmitWord(nLength);
502 | for (i=0; i BUFFER_SIZE) {
531 | UARTprintf("Buffer overflow\n");
532 | return 0;
533 | }
534 | nReceiveLength += USBDBulkPacketRead((void *)&g_sBulkDevice, &pReceiveBuffer[nReceiveLength], ulMsgValue, true);
535 | if (ulMsgValue < 64) {
536 | bReceiving = 0;
537 | }
538 | return ulMsgValue;
539 | }
540 | return 0;
541 | }
542 | case USB_EVENT_SUSPEND:
543 | case USB_EVENT_RESUME:
544 | {
545 | break;
546 | }
547 | default:
548 | {
549 | break;
550 | }
551 | }
552 |
553 | return(0);
554 | }
555 |
--------------------------------------------------------------------------------
/startup_ccs.c:
--------------------------------------------------------------------------------
1 | //*****************************************************************************
2 | //
3 | // startup_ccs.c - Startup code for use with TI's Code Composer Studio.
4 | //
5 | // Copyright (c) 2012-2013 Texas Instruments Incorporated. All rights reserved.
6 | // Software License Agreement
7 | //
8 | // Texas Instruments (TI) is supplying this software for use solely and
9 | // exclusively on TI's microcontroller products. The software is owned by
10 | // TI and/or its suppliers, and is protected under applicable copyright
11 | // laws. You may not combine this software with "viral" open-source
12 | // software in order to form a larger program.
13 | //
14 | // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
15 | // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
16 | // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 | // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
18 | // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
19 | // DAMAGES, FOR ANY REASON WHATSOEVER.
20 | //
21 | // This is part of revision 1.0 of the EK-TM4C123GXL Firmware Package.
22 | //
23 | //*****************************************************************************
24 |
25 | #include
26 | #include "inc/hw_nvic.h"
27 | #include "inc/hw_types.h"
28 |
29 | //*****************************************************************************
30 | //
31 | // Forward declaration of the default fault handlers.
32 | //
33 | //*****************************************************************************
34 | void ResetISR(void);
35 | static void NmiSR(void);
36 | static void FaultISR(void);
37 | static void IntDefaultHandler(void);
38 |
39 | //*****************************************************************************
40 | //
41 | // External declaration for the reset handler that is to be called when the
42 | // processor is started
43 | //
44 | //*****************************************************************************
45 | extern void _c_int00(void);
46 |
47 | //*****************************************************************************
48 | //
49 | // Linker variable that marks the top of the stack.
50 | //
51 | //*****************************************************************************
52 | extern uint32_t __STACK_TOP;
53 |
54 | //*****************************************************************************
55 | //
56 | // External declarations for the interrupt handlers used by the application.
57 | //
58 | //*****************************************************************************
59 | extern void SysTickIntHandler(void);
60 | //extern void USBUARTIntHandler(void);
61 | extern void USB0DeviceIntHandler(void);
62 |
63 | extern void UARTStdioIntHandler(void);
64 |
65 |
66 | //*****************************************************************************
67 | //
68 | // The vector table. Note that the proper constructs must be placed on this to
69 | // ensure that it ends up at physical address 0x0000.0000 or at the start of
70 | // the program if located at a start address other than 0.
71 | //
72 | //*****************************************************************************
73 | #pragma DATA_SECTION(g_pfnVectors, ".intvecs")
74 | void (* const g_pfnVectors[])(void) =
75 | {
76 | (void (*)(void))((uint32_t)&__STACK_TOP),
77 | // The initial stack pointer
78 | ResetISR, // The reset handler
79 | NmiSR, // The NMI handler
80 | FaultISR, // The hard fault handler
81 | IntDefaultHandler, // The MPU fault handler
82 | IntDefaultHandler, // The bus fault handler
83 | IntDefaultHandler, // The usage fault handler
84 | 0, // Reserved
85 | 0, // Reserved
86 | 0, // Reserved
87 | 0, // Reserved
88 | IntDefaultHandler, // SVCall handler
89 | IntDefaultHandler, // Debug monitor handler
90 | 0, // Reserved
91 | IntDefaultHandler, // The PendSV handler
92 | IntDefaultHandler, // The SysTick handler
93 | IntDefaultHandler, // GPIO Port A
94 | IntDefaultHandler, // GPIO Port B
95 | IntDefaultHandler, // GPIO Port C
96 | IntDefaultHandler, // GPIO Port D
97 | IntDefaultHandler, // GPIO Port E
98 | UARTStdioIntHandler, // UART0 Rx and Tx
99 | IntDefaultHandler, // UART1 Rx and Tx
100 | IntDefaultHandler, // SSI0 Rx and Tx
101 | IntDefaultHandler, // I2C0 Master and Slave
102 | IntDefaultHandler, // PWM Fault
103 | IntDefaultHandler, // PWM Generator 0
104 | IntDefaultHandler, // PWM Generator 1
105 | IntDefaultHandler, // PWM Generator 2
106 | IntDefaultHandler, // Quadrature Encoder 0
107 | IntDefaultHandler, // ADC Sequence 0
108 | IntDefaultHandler, // ADC Sequence 1
109 | IntDefaultHandler, // ADC Sequence 2
110 | IntDefaultHandler, // ADC Sequence 3
111 | IntDefaultHandler, // Watchdog timer
112 | IntDefaultHandler, // Timer 0 subtimer A
113 | IntDefaultHandler, // Timer 0 subtimer B
114 | IntDefaultHandler, // Timer 1 subtimer A
115 | IntDefaultHandler, // Timer 1 subtimer B
116 | IntDefaultHandler, // Timer 2 subtimer A
117 | IntDefaultHandler, // Timer 2 subtimer B
118 | IntDefaultHandler, // Analog Comparator 0
119 | IntDefaultHandler, // Analog Comparator 1
120 | IntDefaultHandler, // Analog Comparator 2
121 | IntDefaultHandler, // System Control (PLL, OSC, BO)
122 | IntDefaultHandler, // FLASH Control
123 | IntDefaultHandler, // GPIO Port F
124 | IntDefaultHandler, // GPIO Port G
125 | IntDefaultHandler, // GPIO Port H
126 | IntDefaultHandler, // UART2 Rx and Tx
127 | IntDefaultHandler, // SSI1 Rx and Tx
128 | IntDefaultHandler, // Timer 3 subtimer A
129 | IntDefaultHandler, // Timer 3 subtimer B
130 | IntDefaultHandler, // I2C1 Master and Slave
131 | IntDefaultHandler, // Quadrature Encoder 1
132 | IntDefaultHandler, // CAN0
133 | IntDefaultHandler, // CAN1
134 | IntDefaultHandler, // CAN2
135 | 0, // Reserved
136 | IntDefaultHandler, // Hibernate
137 | USB0DeviceIntHandler, // USB0
138 | IntDefaultHandler, // PWM Generator 3
139 | IntDefaultHandler, // uDMA Software Transfer
140 | IntDefaultHandler, // uDMA Error
141 | IntDefaultHandler, // ADC1 Sequence 0
142 | IntDefaultHandler, // ADC1 Sequence 1
143 | IntDefaultHandler, // ADC1 Sequence 2
144 | IntDefaultHandler, // ADC1 Sequence 3
145 | 0, // Reserved
146 | 0, // Reserved
147 | IntDefaultHandler, // GPIO Port J
148 | IntDefaultHandler, // GPIO Port K
149 | IntDefaultHandler, // GPIO Port L
150 | IntDefaultHandler, // SSI2 Rx and Tx
151 | IntDefaultHandler, // SSI3 Rx and Tx
152 | IntDefaultHandler, // UART3 Rx and Tx
153 | IntDefaultHandler, // UART4 Rx and Tx
154 | IntDefaultHandler, // UART5 Rx and Tx
155 | IntDefaultHandler, // UART6 Rx and Tx
156 | IntDefaultHandler, // UART7 Rx and Tx
157 | 0, // Reserved
158 | 0, // Reserved
159 | 0, // Reserved
160 | 0, // Reserved
161 | IntDefaultHandler, // I2C2 Master and Slave
162 | IntDefaultHandler, // I2C3 Master and Slave
163 | IntDefaultHandler, // Timer 4 subtimer A
164 | IntDefaultHandler, // Timer 4 subtimer B
165 | 0, // Reserved
166 | 0, // Reserved
167 | 0, // Reserved
168 | 0, // Reserved
169 | 0, // Reserved
170 | 0, // Reserved
171 | 0, // Reserved
172 | 0, // Reserved
173 | 0, // Reserved
174 | 0, // Reserved
175 | 0, // Reserved
176 | 0, // Reserved
177 | 0, // Reserved
178 | 0, // Reserved
179 | 0, // Reserved
180 | 0, // Reserved
181 | 0, // Reserved
182 | 0, // Reserved
183 | 0, // Reserved
184 | 0, // Reserved
185 | IntDefaultHandler, // Timer 5 subtimer A
186 | IntDefaultHandler, // Timer 5 subtimer B
187 | IntDefaultHandler, // Wide Timer 0 subtimer A
188 | IntDefaultHandler, // Wide Timer 0 subtimer B
189 | IntDefaultHandler, // Wide Timer 1 subtimer A
190 | IntDefaultHandler, // Wide Timer 1 subtimer B
191 | IntDefaultHandler, // Wide Timer 2 subtimer A
192 | IntDefaultHandler, // Wide Timer 2 subtimer B
193 | IntDefaultHandler, // Wide Timer 3 subtimer A
194 | IntDefaultHandler, // Wide Timer 3 subtimer B
195 | IntDefaultHandler, // Wide Timer 4 subtimer A
196 | IntDefaultHandler, // Wide Timer 4 subtimer B
197 | IntDefaultHandler, // Wide Timer 5 subtimer A
198 | IntDefaultHandler, // Wide Timer 5 subtimer B
199 | IntDefaultHandler, // FPU
200 | 0, // Reserved
201 | 0, // Reserved
202 | IntDefaultHandler, // I2C4 Master and Slave
203 | IntDefaultHandler, // I2C5 Master and Slave
204 | IntDefaultHandler, // GPIO Port M
205 | IntDefaultHandler, // GPIO Port N
206 | IntDefaultHandler, // Quadrature Encoder 2
207 | 0, // Reserved
208 | 0, // Reserved
209 | IntDefaultHandler, // GPIO Port P (Summary or P0)
210 | IntDefaultHandler, // GPIO Port P1
211 | IntDefaultHandler, // GPIO Port P2
212 | IntDefaultHandler, // GPIO Port P3
213 | IntDefaultHandler, // GPIO Port P4
214 | IntDefaultHandler, // GPIO Port P5
215 | IntDefaultHandler, // GPIO Port P6
216 | IntDefaultHandler, // GPIO Port P7
217 | IntDefaultHandler, // GPIO Port Q (Summary or Q0)
218 | IntDefaultHandler, // GPIO Port Q1
219 | IntDefaultHandler, // GPIO Port Q2
220 | IntDefaultHandler, // GPIO Port Q3
221 | IntDefaultHandler, // GPIO Port Q4
222 | IntDefaultHandler, // GPIO Port Q5
223 | IntDefaultHandler, // GPIO Port Q6
224 | IntDefaultHandler, // GPIO Port Q7
225 | IntDefaultHandler, // GPIO Port R
226 | IntDefaultHandler, // GPIO Port S
227 | IntDefaultHandler, // PWM 1 Generator 0
228 | IntDefaultHandler, // PWM 1 Generator 1
229 | IntDefaultHandler, // PWM 1 Generator 2
230 | IntDefaultHandler, // PWM 1 Generator 3
231 | IntDefaultHandler // PWM 1 Fault
232 | };
233 |
234 | //*****************************************************************************
235 | //
236 | // This is the code that gets called when the processor first starts execution
237 | // following a reset event. Only the absolutely necessary set is performed,
238 | // after which the application supplied entry() routine is called. Any fancy
239 | // actions (such as making decisions based on the reset cause register, and
240 | // resetting the bits in that register) are left solely in the hands of the
241 | // application.
242 | //
243 | //*****************************************************************************
244 | void
245 | ResetISR(void)
246 | {
247 | //
248 | // Jump to the CCS C initialization routine. This will enable the
249 | // floating-point unit as well, so that does not need to be done here.
250 | //
251 | __asm(" .global _c_int00\n"
252 | " b.w _c_int00");
253 | }
254 |
255 | //*****************************************************************************
256 | //
257 | // This is the code that gets called when the processor receives a NMI. This
258 | // simply enters an infinite loop, preserving the system state for examination
259 | // by a debugger.
260 | //
261 | //*****************************************************************************
262 | static void
263 | NmiSR(void)
264 | {
265 | //
266 | // Enter an infinite loop.
267 | //
268 | while(1)
269 | {
270 | }
271 | }
272 |
273 | //*****************************************************************************
274 | //
275 | // This is the code that gets called when the processor receives a fault
276 | // interrupt. This simply enters an infinite loop, preserving the system state
277 | // for examination by a debugger.
278 | //
279 | //*****************************************************************************
280 | static void
281 | FaultISR(void)
282 | {
283 | //
284 | // Enter an infinite loop.
285 | //
286 | while(1)
287 | {
288 | }
289 | }
290 |
291 | //*****************************************************************************
292 | //
293 | // This is the code that gets called when the processor receives an unexpected
294 | // interrupt. This simply enters an infinite loop, preserving the system state
295 | // for examination by a debugger.
296 | //
297 | //*****************************************************************************
298 | static void
299 | IntDefaultHandler(void)
300 | {
301 | //
302 | // Go into an infinite loop.
303 | //
304 | while(1)
305 | {
306 | }
307 | }
308 |
--------------------------------------------------------------------------------
/tm4c123gh6pm.cmd:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | *
3 | * Default Linker Command file for the Texas Instruments TM4C123GH6PM
4 | *
5 | * This is derived from revision 10691 of the TivaWare Library.
6 | *
7 | *****************************************************************************/
8 |
9 | --retain=g_pfnVectors
10 |
11 | MEMORY
12 | {
13 | FLASH (RX) : origin = 0x00000000, length = 0x00040000
14 | SRAM (RWX) : origin = 0x20000000, length = 0x00008000
15 | }
16 |
17 | /* The following command line options are set as part of the CCS project. */
18 | /* If you are building using the command line, or for some reason want to */
19 | /* define them here, you can uncomment and modify these lines as needed. */
20 | /* If you are using CCS for building, it is probably better to make any such */
21 | /* modifications in your CCS project and leave this file alone. */
22 | /* */
23 | /* --heap_size=0 */
24 | /* --stack_size=256 */
25 | /* --library=rtsv7M4_T_le_eabi.lib */
26 |
27 | /* Section allocation in memory */
28 |
29 | SECTIONS
30 | {
31 | .intvecs: > 0x00000000
32 | .text : > FLASH
33 | .const : > FLASH
34 | .cinit : > FLASH
35 | .pinit : > FLASH
36 | .init_array : > FLASH
37 |
38 | .vtable : > 0x20000000
39 | .data : > SRAM
40 | .bss : > SRAM
41 | .sysmem : > SRAM
42 | .stack : > SRAM
43 | }
44 |
45 | __STACK_TOP = __stack + 512;
46 |
--------------------------------------------------------------------------------
/usb_structs.c:
--------------------------------------------------------------------------------
1 | /*
2 | * usb_structs.c
3 | *
4 | * Created on: 31 dec. 2012
5 | * Author: Frans-Willem
6 | * Minor tweak for Tivaware compatibility by Richard Aplin, Dec2013
7 | */
8 | #include //tivaware tweak
9 | #include
10 |
11 | #include "inc/hw_types.h"
12 | #include "driverlib/usb.h"
13 | #include "usblib/usblib.h"
14 | #include "usblib/usb-ids.h"
15 | #include "usblib/device/usbdevice.h"
16 | #include "usblib/device/usbdbulk.h"
17 | #include "usb_structs.h"
18 |
19 | const unsigned char g_pLangDescriptor[] =
20 | {
21 | 4,
22 | USB_DTYPE_STRING,
23 | USBShort(USB_LANG_EN_US)
24 | };
25 |
26 | const unsigned char g_pManufacturerString[] =
27 | {
28 | (23 + 1) * 2,
29 | USB_DTYPE_STRING,
30 | 'C',0,'a',0,'m',0,'b',0,'r',0,'i',0,'d',0,'g',0,'e',0,' ',0,'S',0,'i',0,'l',0,'i',0,'c',0,'o',0,'n',0,' ',0,'R',0,'a',0,'d',0,'i',0,'o',0
31 | };
32 | const unsigned char g_pProductString[] =
33 | {
34 | (14 + 1) * 2,
35 | USB_DTYPE_STRING,
36 | 'C',0,'S',0,'R',0,' ',0,'P',0,'r',0,'o',0,'g',0,'r',0,'a',0,'m',0,'m',0,'e',0,'r',0
37 | };
38 | const unsigned char g_pSerialNumberString[] =
39 | {
40 | (8 + 1) * 2,
41 | USB_DTYPE_STRING,
42 | '1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0
43 | };
44 | const unsigned char g_pDataInterfaceString[] =
45 | {
46 | (19 + 1) * 2,
47 | USB_DTYPE_STRING,
48 | 'B', 0, 'u', 0, 'l', 0, 'k', 0, ' ', 0, 'D', 0, 'a', 0, 't', 0,
49 | 'a', 0, ' ', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0,
50 | 'a', 0, 'c', 0, 'e', 0
51 | };
52 | const unsigned char g_pConfigString[] =
53 | {
54 | (23 + 1) * 2,
55 | USB_DTYPE_STRING,
56 | 'B', 0, 'u', 0, 'l', 0, 'k', 0, ' ', 0, 'D', 0, 'a', 0, 't', 0,
57 | 'a', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0, 'f', 0, 'i', 0, 'g', 0,
58 | 'u', 0, 'r', 0, 'a', 0, 't', 0, 'i', 0, 'o', 0, 'n', 0
59 | };
60 | const unsigned char * const g_pStringDescriptors[] =
61 | {
62 | g_pLangDescriptor,
63 | g_pManufacturerString,
64 | g_pProductString,
65 | g_pSerialNumberString,
66 | g_pDataInterfaceString,
67 | g_pConfigString
68 | };
69 |
70 | #define NUM_STRING_DESCRIPTORS (sizeof(g_pStringDescriptors) / \
71 | sizeof(unsigned char *))
72 |
73 | //*****************************************************************************
74 | //
75 | // The bulk device initialization and customization structures. In this case,
76 | // we are using USBBuffers between the bulk device class driver and the
77 | // application code. The function pointers and callback data values are set
78 | // to insert a buffer in each of the data channels, transmit and receive.
79 | //
80 | // With the buffer in place, the bulk channel callback is set to the relevant
81 | // channel function and the callback data is set to point to the channel
82 | // instance data. The buffer, in turn, has its callback set to the application
83 | // function and the callback data set to our bulk instance structure.
84 | //
85 | //*****************************************************************************
86 |
87 | //Tivaware mods see http://www.ti.com/lit/an/spma050a/spma050a.pdf section 3.7.2
88 | //Don't need tBulkInstance
89 | //? tBulkInstance g_sBulkInstance;
90 |
91 | tUSBDBulkDevice g_sBulkDevice =
92 | {
93 | 0x0a12, //VID
94 | 0x0042, //PID
95 | 500,
96 | USB_CONF_ATTR_SELF_PWR,
97 | RxHandler,
98 | (void *)0,
99 | TxHandler,
100 | (void *)0,
101 | g_pStringDescriptors,
102 | NUM_STRING_DESCRIPTORS,
103 | // &g_sBulkInstance //removed for tivaware
104 | };
105 |
106 |
107 |
--------------------------------------------------------------------------------
/usb_structs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * usb_structs.h
3 | *
4 | * Created on: 31 dec. 2012
5 | * Author: Frans-Willem
6 | * Minor tweak for Tivaware compatibility by Richard Aplin, Dec2013
7 | */
8 |
9 | #ifndef USB_STRUCTS_H_
10 | #define USB_STRUCTS_H_
11 |
12 | #define BULK_BUFFER_SIZE 256
13 |
14 | extern uint32_t RxHandler(void *pvCBData, uint32_t ui32Event,
15 | uint32_t ui32MsgValue, void *pvMsgData);
16 | extern uint32_t TxHandler(void *pvi32CBData, uint32_t ui32Event,
17 | uint32_t ui32MsgValue, void *pvMsgData);
18 |
19 | extern tUSBDBulkDevice g_sBulkDevice;
20 |
21 |
22 | #endif /* USB_STRUCTS_H_ */
23 |
--------------------------------------------------------------------------------