blob: e186bbacc193d11065a59b749d45bdf65d4c1875 [file] [log] [blame]
brians0ab60bb2013-01-31 02:21:51 +00001/*
2 FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd.
3
4 This file is part of the FreeRTOS distribution.
5
6 FreeRTOS is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License (version 2) as published by the
8 Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
9 ***NOTE*** The exception to the GPL is included to allow you to distribute
10 a combined work that includes FreeRTOS without being obliged to provide the
11 source code for proprietary components outside of the FreeRTOS kernel.
12 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 more details. You should have received a copy of the GNU General Public
16 License and the FreeRTOS license exception along with FreeRTOS; if not it
17 can be viewed here: http://www.freertos.org/a00114.html and also obtained
18 by writing to Richard Barry, contact details for whom are available on the
19 FreeRTOS WEB site.
20
21*/
22
23/* Standard includes. */
24#include "stdio.h"
25
26/* Scheduler includes. */
27#include "FreeRTOS.h"
28#include "queue.h"
29#include "task.h"
30
31/* Demo app includes. */
32#include "flash.h"
33#include "partest.h"
brians0ab60bb2013-01-31 02:21:51 +000034#include "LPCUSB/usbapi.h"
35
Brian Silvermanf92396c2013-09-12 20:13:13 -070036#include "analog.h"
37#include "digital.h"
38#include "encoder.h"
Brian Silvermancb332812013-10-08 13:33:11 -070039#include "CAN.h"
Brian Silverman49876942013-10-11 17:50:26 -070040#include "gyro.h"
brians0ab60bb2013-01-31 02:21:51 +000041
Brian Silvermand36b7d32013-10-24 15:56:47 -070042extern void usb_init(void);
brians0ab60bb2013-01-31 02:21:51 +000043
Brian Silvermancb332812013-10-08 13:33:11 -070044// Sets up (and connects) PLL0.
45// The CPU will be running at 100 MHz with a 12 MHz clock input when this is
46// done.
47static void setup_PLL0(void) {
48 // If PLL0 is currently connected.
49 if (SC->PLL0STAT & (1 << 25)) {
50 /* Enable PLL0, disconnected. */
51 SC->PLL0CON = 1;
52 SC->PLL0FEED = PLLFEED_FEED1;
53 SC->PLL0FEED = PLLFEED_FEED2;
54 }
55
56 // Disable PLL0, disconnected.
57 SC->PLL0CON = 0;
58 SC->PLL0FEED = PLLFEED_FEED1;
59 SC->PLL0FEED = PLLFEED_FEED2;
60
61 // Enable main OSC.
62 SC->SCS |= 1 << 5;
63 // Wait until it's ready.
64 while (!(SC->SCS & (1 << 6)));
65
66 // Select main OSC as the PLL0 clock source.
67 SC->CLKSRCSEL = 0x1;
68
69 // Set up PLL0 to output 400MHz.
70 // 12MHz * 50 / 3 * 2 = 400MHz.
71 // The input is 12MHz (from the crystal), M = 50, and N = 3.
72 SC->PLL0CFG = 0x20031;
73 SC->PLL0FEED = PLLFEED_FEED1;
74 SC->PLL0FEED = PLLFEED_FEED2;
75
76 // Enable PLL0, disconnected.
77 SC->PLL0CON = 1;
78 SC->PLL0FEED = PLLFEED_FEED1;
79 SC->PLL0FEED = PLLFEED_FEED2;
80
81 // Set clock divider to dividing by 4 to give a final frequency of 100MHz.
82 SC->CCLKCFG = 0x03;
83
84 // Configure flash accelerator to use 5 CPU clocks like the datasheet says for
85 // a 100MHz clock.
86 SC->FLASHCFG = 0x403a;
87
88 // Wait until PLL0 is locked.
89 while (((SC->PLL0STAT & (1 << 26)) == 0));
90
91 // Enable PLL0 and connect.
92 SC->PLL0CON = 3;
93 SC->PLL0FEED = PLLFEED_FEED1;
94 SC->PLL0FEED = PLLFEED_FEED2;
95
96 // Wait until PLL0 is connected.
97 while (((SC->PLL0STAT & (1 << 25)) == 0));
98}
99
100// Configures PLL1 as the clock for USB.
101static void setup_PLL1(void) {
102 // If PLL1 is currently connected.
103 if (SC->PLL1STAT & (1 << 9)) {
104 // Enable PLL1, disconnected.
105 SC->PLL1CON = 1;
106 SC->PLL1FEED = PLLFEED_FEED1;
107 SC->PLL1FEED = PLLFEED_FEED2;
108 }
109
110 // Disable PLL1, disconnected.
111 SC->PLL1CON = 0;
112 SC->PLL1FEED = PLLFEED_FEED1;
113 SC->PLL1FEED = PLLFEED_FEED2;
114
115 // Set up PLL1 to produce the required 48MHz from the crystal.
116 // USBCLK = 12MHz * 4 = 48MHz.
117 // FCCO = USBCLK * 2 * 3 = 288MHz.
118 // The input is 12MHz, M = 4, and P = 3.
119 SC->PLL1CFG = 0x23;
120 SC->PLL1FEED = PLLFEED_FEED1;
121 SC->PLL1FEED = PLLFEED_FEED2;
122
123 /* Enable PLL1, disconnected. */
124 SC->PLL1CON = 1;
125 SC->PLL1FEED = PLLFEED_FEED1;
126 SC->PLL1FEED = PLLFEED_FEED2;
127
128 // Wait until PLL1 is locked.
129 while (((SC->PLL1STAT & (1 << 10)) == 0));
130
131 /* Enable PLL1 and connect it. */
132 SC->PLL1CON = 3;
133 SC->PLL1FEED = PLLFEED_FEED1;
134 SC->PLL1FEED = PLLFEED_FEED2;
135
136 // Wait until PLL1 is connected.
137 while (((SC->PLL1STAT & (1 << 9)) == 0));
138}
139
Brian Silverman49876942013-10-11 17:50:26 -0700140// Setup the peripherals.
141static void setup_hardware(void) {
Brian Silvermancb332812013-10-08 13:33:11 -0700142 // Setup GPIO power.
143 SC->PCONP = PCONP_PCGPIO;
brians0ab60bb2013-01-31 02:21:51 +0000144
Brian Silvermancb332812013-10-08 13:33:11 -0700145 // Disable TPIU.
146 PINCON->PINSEL10 = 0;
brians0ab60bb2013-01-31 02:21:51 +0000147
Brian Silvermancb332812013-10-08 13:33:11 -0700148 setup_PLL0();
brians0ab60bb2013-01-31 02:21:51 +0000149
Brian Silvermancb332812013-10-08 13:33:11 -0700150 setup_PLL1();
brians0ab60bb2013-01-31 02:21:51 +0000151
Brian Silvermancb332812013-10-08 13:33:11 -0700152 /* Configure the LEDs. */
153 vParTestInitialise();
brians0ab60bb2013-01-31 02:21:51 +0000154}
Brian Silverman49876942013-10-11 17:50:26 -0700155
156int main(void) {
Brian Silverman1dbe3542013-10-31 20:29:11 -0700157 // Errata PCLKSELx.1 says that we have to do all of this BEFORE setting up
158 // PLL0 or it might not work.
159
160 // Set everything to run at full CCLK by default.
161 SC->PCLKSEL0 = 0x55555555;
162
163 CAN_PCLKSEL();
164
Brian Silverman49876942013-10-11 17:50:26 -0700165 setup_hardware();
166
Brian Silverman49876942013-10-11 17:50:26 -0700167 digital_init();
168
169 analog_init();
170
171 encoder_init();
172
173 gyro_init();
174
Brian Silverman49876942013-10-11 17:50:26 -0700175 initCAN();
176
Brian Silvermand36b7d32013-10-24 15:56:47 -0700177 usb_init();
178
Brian Silverman49876942013-10-11 17:50:26 -0700179 // Start the scheduler.
180 vTaskStartScheduler();
181
182 /* Will only get here if there was insufficient memory to create the idle
183 task. The idle task is created within vTaskStartScheduler(). */
184 for (;;) {}
185}
brians0ab60bb2013-01-31 02:21:51 +0000186
187void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed char *pcTaskName)
188{
Brian Silvermancb332812013-10-08 13:33:11 -0700189 /* This function will get called if a task overflows its stack. */
brians0ab60bb2013-01-31 02:21:51 +0000190
Brian Silvermancb332812013-10-08 13:33:11 -0700191 (void) pxTask;
192 (void) pcTaskName;
brians0ab60bb2013-01-31 02:21:51 +0000193
Brian Silvermancb332812013-10-08 13:33:11 -0700194 for (;;);
brians0ab60bb2013-01-31 02:21:51 +0000195}
brians0ab60bb2013-01-31 02:21:51 +0000196
Brian Silvermancb332812013-10-08 13:33:11 -0700197// This is what portCONFIGURE_TIMER_FOR_RUN_TIME_STATS in FreeRTOSConfig.h
198// actually calls.
Brian Silverman49876942013-10-11 17:50:26 -0700199// It sets up timer 0 to use for timing.
200void vConfigureTimerForRunTimeStats(void) {
Brian Silvermancb332812013-10-08 13:33:11 -0700201 const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;
brians0ab60bb2013-01-31 02:21:51 +0000202
Brian Silvermancb332812013-10-08 13:33:11 -0700203 /* This function configures a timer that is used as the time base when
204 collecting run time statistical information - basically the percentage
205 of CPU time that each task is utilising. It is called automatically when
206 the scheduler is started (assuming configGENERATE_RUN_TIME_STATS is set
207 to 1). */
brians0ab60bb2013-01-31 02:21:51 +0000208
Brian Silvermancb332812013-10-08 13:33:11 -0700209 /* Power up and feed the timer. */
210 SC->PCONP |= 0x02UL;
brians0ab60bb2013-01-31 02:21:51 +0000211
Brian Silvermancb332812013-10-08 13:33:11 -0700212 /* Reset Timer 0 */
213 TIM0->TCR = TCR_COUNT_RESET;
brians0ab60bb2013-01-31 02:21:51 +0000214
Brian Silvermancb332812013-10-08 13:33:11 -0700215 /* Just count up. */
216 TIM0->CTCR = CTCR_CTM_TIMER;
brians0ab60bb2013-01-31 02:21:51 +0000217
Brian Silvermancb332812013-10-08 13:33:11 -0700218 /* Prescale to a frequency that is good enough to get a decent resolution,
219 but not too fast so as to overflow all the time. */
220 TIM0->PR = (configCPU_CLOCK_HZ / 10000UL) - 1UL;
brians0ab60bb2013-01-31 02:21:51 +0000221
Brian Silvermancb332812013-10-08 13:33:11 -0700222 /* Start the counter. */
223 TIM0->TCR = TCR_COUNT_ENABLE;
brians0ab60bb2013-01-31 02:21:51 +0000224}