blob: 3ac21c8da79445d81fb23cba526920c91c53a21a [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 // Set CAN to run at CCLK/6, which should have it running about 1 Mbit (1.042)
153 SC->PCLKSEL0 = 0xff555555;
brians0ab60bb2013-01-31 02:21:51 +0000154
Brian Silvermancb332812013-10-08 13:33:11 -0700155 /* Configure the LEDs. */
156 vParTestInitialise();
brians0ab60bb2013-01-31 02:21:51 +0000157}
Brian Silverman49876942013-10-11 17:50:26 -0700158
159int main(void) {
160 setup_hardware();
161
Brian Silverman49876942013-10-11 17:50:26 -0700162 digital_init();
163
164 analog_init();
165
166 encoder_init();
167
168 gyro_init();
169
Brian Silverman49876942013-10-11 17:50:26 -0700170 initCAN();
171
Brian Silvermand36b7d32013-10-24 15:56:47 -0700172 usb_init();
173
Brian Silverman49876942013-10-11 17:50:26 -0700174 // Start the scheduler.
175 vTaskStartScheduler();
176
177 /* Will only get here if there was insufficient memory to create the idle
178 task. The idle task is created within vTaskStartScheduler(). */
179 for (;;) {}
180}
brians0ab60bb2013-01-31 02:21:51 +0000181
182void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed char *pcTaskName)
183{
Brian Silvermancb332812013-10-08 13:33:11 -0700184 /* This function will get called if a task overflows its stack. */
brians0ab60bb2013-01-31 02:21:51 +0000185
Brian Silvermancb332812013-10-08 13:33:11 -0700186 (void) pxTask;
187 (void) pcTaskName;
brians0ab60bb2013-01-31 02:21:51 +0000188
Brian Silvermancb332812013-10-08 13:33:11 -0700189 for (;;);
brians0ab60bb2013-01-31 02:21:51 +0000190}
brians0ab60bb2013-01-31 02:21:51 +0000191
Brian Silvermancb332812013-10-08 13:33:11 -0700192// This is what portCONFIGURE_TIMER_FOR_RUN_TIME_STATS in FreeRTOSConfig.h
193// actually calls.
Brian Silverman49876942013-10-11 17:50:26 -0700194// It sets up timer 0 to use for timing.
195void vConfigureTimerForRunTimeStats(void) {
Brian Silvermancb332812013-10-08 13:33:11 -0700196 const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;
brians0ab60bb2013-01-31 02:21:51 +0000197
Brian Silvermancb332812013-10-08 13:33:11 -0700198 /* This function configures a timer that is used as the time base when
199 collecting run time statistical information - basically the percentage
200 of CPU time that each task is utilising. It is called automatically when
201 the scheduler is started (assuming configGENERATE_RUN_TIME_STATS is set
202 to 1). */
brians0ab60bb2013-01-31 02:21:51 +0000203
Brian Silvermancb332812013-10-08 13:33:11 -0700204 /* Power up and feed the timer. */
205 SC->PCONP |= 0x02UL;
206 SC->PCLKSEL0 = (SC->PCLKSEL0 & (~(0x3 << 2))) | (0x01 << 2);
brians0ab60bb2013-01-31 02:21:51 +0000207
Brian Silvermancb332812013-10-08 13:33:11 -0700208 /* Reset Timer 0 */
209 TIM0->TCR = TCR_COUNT_RESET;
brians0ab60bb2013-01-31 02:21:51 +0000210
Brian Silvermancb332812013-10-08 13:33:11 -0700211 /* Just count up. */
212 TIM0->CTCR = CTCR_CTM_TIMER;
brians0ab60bb2013-01-31 02:21:51 +0000213
Brian Silvermancb332812013-10-08 13:33:11 -0700214 /* Prescale to a frequency that is good enough to get a decent resolution,
215 but not too fast so as to overflow all the time. */
216 TIM0->PR = (configCPU_CLOCK_HZ / 10000UL) - 1UL;
brians0ab60bb2013-01-31 02:21:51 +0000217
Brian Silvermancb332812013-10-08 13:33:11 -0700218 /* Start the counter. */
219 TIM0->TCR = TCR_COUNT_ENABLE;
brians0ab60bb2013-01-31 02:21:51 +0000220}