2 FreeRTOS.org V5.4.0 - Copyright (C) 2003-2009 Richard Barry.
\r
4 This file is part of the FreeRTOS.org distribution.
\r
6 FreeRTOS.org is free software; you can redistribute it and/or modify it
\r
7 under the terms of the GNU General Public License (version 2) as published
\r
8 by the Free Software Foundation and modified by the FreeRTOS exception.
\r
9 **NOTE** The exception to the GPL is included to allow you to distribute a
\r
10 combined work that includes FreeRTOS.org without being obliged to provide
\r
11 the source code for any proprietary components. Alternative commercial
\r
12 license and support terms are also available upon request. See the
\r
13 licensing section of http://www.FreeRTOS.org for full details.
\r
15 FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT
\r
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
\r
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
20 You should have received a copy of the GNU General Public License along
\r
21 with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59
\r
22 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\r
25 ***************************************************************************
\r
27 * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation *
\r
29 * This is a concise, step by step, 'hands on' guide that describes both *
\r
30 * general multitasking concepts and FreeRTOS specifics. It presents and *
\r
31 * explains numerous examples that are written using the FreeRTOS API. *
\r
32 * Full source code for all the examples is provided in an accompanying *
\r
35 ***************************************************************************
\r
39 Please ensure to read the configuration and relevant port sections of the
\r
40 online documentation.
\r
42 http://www.FreeRTOS.org - Documentation, latest information, license and
\r
45 http://www.SafeRTOS.com - A version that is certified for use in safety
\r
48 http://www.OpenRTOS.com - Commercial support, development, porting,
\r
49 licensing and training services.
\r
54 * Creates all the demo application tasks, then starts the scheduler. The WEB
\r
55 * documentation provides more details of the standard demo application tasks
\r
56 * (which just exist to test the kernel port and provide an example of how to use
\r
57 * each FreeRTOS API function).
\r
59 * In addition to the standard demo tasks, the following tasks and tests are
\r
60 * defined and/or created within this file:
\r
62 * "LCD" task - the LCD task is a 'gatekeeper' task. It is the only task that
\r
63 * is permitted to access the display directly. Other tasks wishing to write a
\r
64 * message to the LCD send the message on a queue to the LCD task instead of
\r
65 * accessing the LCD themselves. The LCD task just blocks on the queue waiting
\r
66 * for messages - waking and displaying the messages as they arrive. The use
\r
67 * of a gatekeeper in this manner permits both tasks and interrupts to write to
\r
68 * the LCD without worrying about mutual exclusion. This is demonstrated by the
\r
69 * check hook (see below) which sends messages to the display even though it
\r
70 * executes from an interrupt context.
\r
72 * "Check" hook - This only executes fully every five seconds from the tick
\r
73 * hook. Its main function is to check that all the standard demo tasks are
\r
74 * still operational. Should any unexpected behaviour be discovered within a
\r
75 * demo task then the tick hook will write an error to the LCD (via the LCD task).
\r
76 * If all the demo tasks are executing with their expected behaviour then the
\r
77 * check hook writes PASS to the LCD (again via the LCD task), as described above.
\r
78 * The check hook also toggles LED 4 each time it executes.
\r
80 * LED tasks - These just demonstrate how multiple instances of a single task
\r
81 * definition can be created. Each LED task simply toggles an LED. The task
\r
82 * parameter is used to pass the number of the LED to be toggled into the task.
\r
84 * "uIP" task - This is the task that handles the uIP stack. All TCP/IP
\r
85 * processing is performed in this task.
\r
88 /* Standard includes. */
\r
91 /* Scheduler includes. */
\r
92 #include "FreeRTOS.h"
\r
97 /* Hardware library includes. */
\r
98 #include "LPC17xx_defs.h"
\r
100 /* Demo app includes. */
\r
101 #include "BlockQ.h"
\r
102 #include "integer.h"
\r
103 #include "blocktim.h"
\r
105 #include "partest.h"
\r
106 #include "semtest.h"
\r
108 #include "GenQTest.h"
\r
110 #include "recmutex.h"
\r
119 /*-----------------------------------------------------------*/
\r
121 /* The number of LED tasks that will be created. */
\r
122 #define mainNUM_LED_TASKS ( 6 )
\r
124 /* The time between cycles of the 'check' functionality (defined within the
\r
126 #define mainCHECK_DELAY ( ( portTickType ) 5000 / portTICK_RATE_MS )
\r
128 /* Task priorities. */
\r
129 #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
\r
130 #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
\r
131 #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
\r
132 #define mainUIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
\r
133 #define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
\r
134 #define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
\r
135 #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
\r
136 #define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
\r
138 /* The WEB server has a larger stack as it utilises stack hungry string
\r
139 handling library calls. */
\r
140 #define mainBASIC_WEB_STACK_SIZE ( configMINIMAL_STACK_SIZE * 4 )
\r
142 /* The length of the queue used to send messages to the LCD task. */
\r
143 #define mainQUEUE_SIZE ( 3 )
\r
145 /* The task that is toggled by the check task. */
\r
146 #define mainCHECK_TASK_LED ( 4 )
\r
147 /*-----------------------------------------------------------*/
\r
150 * Configure the hardware for the demo.
\r
152 static void prvSetupHardware( void );
\r
155 * Very simple task that toggles an LED.
\r
157 static void vLEDTask( void *pvParameters );
\r
160 * The task that handles the uIP stack. All TCP/IP processing is performed in
\r
163 extern void vuIP_Task( void *pvParameters );
\r
166 * The LCD gatekeeper task as described in the comments at the top of this file.
\r
168 static void vLCDTask( void *pvParameters );
\r
170 /*-----------------------------------------------------------*/
\r
172 /* The queue used to send messages to the LCD task. */
\r
173 xQueueHandle xLCDQueue;
\r
175 /*-----------------------------------------------------------*/
\r
181 /* Configure the hardware for use by this demo. */
\r
182 prvSetupHardware();
\r
184 /* Start the standard demo tasks. These are just here to exercise the
\r
185 kernel port and provide examples of how the FreeRTOS API can be used. */
\r
186 vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
\r
187 vCreateBlockTimeTasks();
\r
188 vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
\r
189 vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
\r
190 vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
\r
191 vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
\r
192 vStartQueuePeekTasks();
\r
193 vStartRecursiveMutexTasks();
\r
194 vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );
\r
196 /* Create the uIP task. The WEB server runs in this task. */
\r
197 xTaskCreate( vuIP_Task, ( signed char * ) "uIP", mainBASIC_WEB_STACK_SIZE, ( void * ) NULL, mainUIP_TASK_PRIORITY, NULL );
\r
199 /* Create the queue used by the LCD task. Messages for display on the LCD
\r
200 are received via this queue. */
\r
201 xLCDQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( xLCDMessage ) );
\r
203 /* Start the LCD gatekeeper task - as described in the comments at the top
\r
205 xTaskCreate( vLCDTask, ( signed portCHAR * ) "LCD", configMINIMAL_STACK_SIZE * 2, NULL, mainLCD_TASK_PRIORITY, NULL );
\r
207 /* Start the scheduler. */
\r
208 vTaskStartScheduler();
\r
210 /* Will only get here if there was insufficient memory to create the idle
\r
211 task. The idle task is created within vTaskStartScheduler(). */
\r
214 /*-----------------------------------------------------------*/
\r
216 void vLCDTask( void *pvParameters )
\r
218 xLCDMessage xMessage;
\r
219 unsigned long ulRow = 0;
\r
220 char cIPAddr[ 17 ]; /* To fit max IP address length of xxx.xxx.xxx.xxx\0 */
\r
222 ( void ) pvParameters;
\r
224 /* The LCD gatekeeper task as described in the comments at the top of this
\r
227 /* Initialise the LCD and display a startup message that includes the
\r
228 configured IP address. */
\r
229 sprintf( cIPAddr, "%d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
\r
233 /* Wait for a message to arrive to be displayed. */
\r
234 while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS );
\r
238 /*-----------------------------------------------------------*/
\r
240 void vApplicationTickHook( void )
\r
242 static xLCDMessage xMessage = { "PASS" };
\r
243 static unsigned portLONG ulTicksSinceLastDisplay = 0;
\r
244 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
\r
246 /* Called from every tick interrupt as described in the comments at the top
\r
249 Have enough ticks passed to make it time to perform our health status
\r
251 ulTicksSinceLastDisplay++;
\r
252 if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
\r
254 /* Reset the counter so these checks run again in mainCHECK_DELAY
\r
256 ulTicksSinceLastDisplay = 0;
\r
258 /* Has an error been found in any task? */
\r
259 if( xAreGenericQueueTasksStillRunning() != pdTRUE )
\r
261 xMessage.pcMessage = "ERROR: GEN Q";
\r
263 else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
\r
265 xMessage.pcMessage = "ERROR: PEEK Q";
\r
267 else if( xAreBlockingQueuesStillRunning() != pdTRUE )
\r
269 xMessage.pcMessage = "ERROR: BLOCK Q";
\r
271 else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
\r
273 xMessage.pcMessage = "ERROR: BLOCK TIME";
\r
275 else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
\r
277 xMessage.pcMessage = "ERROR: SEMAPHR";
\r
279 else if( xArePollingQueuesStillRunning() != pdTRUE )
\r
281 xMessage.pcMessage = "ERROR: POLL Q";
\r
283 else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
\r
285 xMessage.pcMessage = "ERROR: INT MATH";
\r
287 else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
\r
289 xMessage.pcMessage = "ERROR: REC MUTEX";
\r
292 /* Send the message to the OLED gatekeeper for display. The
\r
293 xHigherPriorityTaskWoken parameter is not actually used here
\r
294 as this function is running in the tick interrupt anyway - but
\r
295 it must still be supplied. */
\r
296 xHigherPriorityTaskWoken = pdFALSE;
\r
297 xQueueSendFromISR( xLCDQueue, &xMessage, &xHigherPriorityTaskWoken );
\r
299 /* Also toggle and LED. This can be done from here because in this port
\r
300 the LED toggling functions don't use critical sections. */
\r
301 vParTestToggleLED( mainCHECK_TASK_LED );
\r
304 /*-----------------------------------------------------------*/
\r
306 void prvSetupHardware( void )
\r
308 /* Disable peripherals power. */
\r
311 /* Enable GPIO power. */
\r
312 PCONP = PCONP_PCGPIO;
\r
314 /* Disable TPIU. */
\r
317 /* Disconnect the main PLL. */
\r
318 PLL0CON &= ~PLLCON_PLLC;
\r
319 PLL0FEED = PLLFEED_FEED1;
\r
320 PLL0FEED = PLLFEED_FEED2;
\r
321 while ((PLL0STAT & PLLSTAT_PLLC) != 0);
\r
323 /* Turn off the main PLL. */
\r
324 PLL0CON &= ~PLLCON_PLLE;
\r
325 PLL0FEED = PLLFEED_FEED1;
\r
326 PLL0FEED = PLLFEED_FEED2;
\r
327 while ((PLL0STAT & PLLSTAT_PLLE) != 0);
\r
329 /* No CPU clock divider. */
\r
334 while ((SCS & 0x40) == 0);
\r
336 /* Use main oscillator. */
\r
338 PLL0CFG = (PLLCFG_MUL16 | PLLCFG_DIV1);
\r
340 PLL0FEED = PLLFEED_FEED1;
\r
341 PLL0FEED = PLLFEED_FEED2;
\r
343 /* Activate the PLL by turning it on then feeding the correct
\r
344 sequence of bytes. */
\r
345 PLL0CON = PLLCON_PLLE;
\r
346 PLL0FEED = PLLFEED_FEED1;
\r
347 PLL0FEED = PLLFEED_FEED2;
\r
349 /* 6x CPU clock divider (64 MHz) */
\r
352 /* Wait for the PLL to lock. */
\r
353 while ((PLL0STAT & PLLSTAT_PLOCK) == 0);
\r
355 /* Connect the PLL. */
\r
356 PLL0CON = PLLCON_PLLC | PLLCON_PLLE;
\r
357 PLL0FEED = PLLFEED_FEED1;
\r
358 PLL0FEED = PLLFEED_FEED2;
\r
360 /* Setup the peripheral bus to be the same as the PLL output (64 MHz). */
\r
361 PCLKSEL0 = 0x05555555;
\r
363 /* Configure the LEDs. */
\r
364 vParTestInitialise();
\r
366 /*-----------------------------------------------------------*/
\r
368 void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTaskName )
\r
370 /* This function will get called if a task overflows its stack. */
\r
373 ( void ) pcTaskName;
\r
377 /*-----------------------------------------------------------*/
\r
379 void vConfigureTimerForRunTimeStats( void )
\r
381 const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;
\r
383 /* This function configures a timer that is used as the time base when
\r
384 collecting run time statistical information - basically the percentage
\r
385 of CPU time that each task is utilising. It is called automatically when
\r
386 the scheduler is started (assuming configGENERATE_RUN_TIME_STATS is set
\r
389 /* Power up and feed the timer. */
\r
391 PCLKSEL0 = (PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
\r
393 /* Reset Timer 0 */
\r
394 T0TCR = TCR_COUNT_RESET;
\r
396 /* Just count up. */
\r
397 T0CTCR = CTCR_CTM_TIMER;
\r
399 /* Prescale to a frequency that is good enough to get a decent resolution,
\r
400 but not too fast so as to overflow all the time. */
\r
401 T0PR = ( configCPU_CLOCK_HZ / 10000UL ) - 1UL;
\r
403 /* Start the counter. */
\r
404 T0TCR = TCR_COUNT_ENABLE;
\r
406 /*-----------------------------------------------------------*/
\r
414 /*----------------------------------------------------------------------*/
\r
415 /* FAT file system sample project for FatFs R0.06 (C)ChaN, 2008 */
\r
416 /*----------------------------------------------------------------------*/
\r
419 #include <string.h>
\r
420 #include "LPC17xx.h"
\r
421 #include "integer.h"
\r
422 //#include "interrupt.h"
\r
424 #include "monitor.h"
\r
426 #include "diskio.h"
\r
429 #include "ctl_api.h"
\r
431 #include "usbhost_lpc1768.h"
\r
433 DWORD acc_size; /* Work register for fs command */
\r
434 WORD acc_files, acc_dirs;
\r
437 char linebuf[120]; /* Console input buffer */
\r
439 FATFS fatfs[_DRIVES]; /* File system object for each logical drive */
\r
440 FIL file1, file2; /* File objects */
\r
441 DIR dir; /* Directory object */
\r
442 BYTE Buff[16384] __attribute__ ((aligned (4))) ; /* Working buffer */
\r
444 volatile UINT Timer; /* Performance timer (1kHz increment) */
\r
448 /*---------------------------------------------------------*/
\r
449 /* 1000Hz timer interrupt generated by TIMER0 */
\r
450 /*---------------------------------------------------------*/
\r
452 void Isr_TIMER0 (void)
\r
454 T0IR = 1; /* Clear irq flag */
\r
462 /*---------------------------------------------------------*/
\r
463 /* User Provided Timer Function for FatFs module */
\r
464 /*---------------------------------------------------------*/
\r
465 /* This is a real time clock service to be called from */
\r
466 /* FatFs module. Any valid time must be returned even if */
\r
467 /* the system does not support a real time clock. */
\r
468 /* This is not required in read-only configuration. */
\r
471 DWORD get_fattime ()
\r
477 return ((DWORD)(rtc.year) << 25)
\r
478 | ((DWORD)rtc.month << 21)
\r
479 | ((DWORD)rtc.mday << 16)
\r
480 | ((DWORD)rtc.hour << 11)
\r
481 | ((DWORD)rtc.min << 5)
\r
482 | ((DWORD)rtc.sec >> 1);
\r
486 /*--------------------------------------------------------------------------*/
\r
488 /*--------------------------------------------------------------------------*/
\r
491 FRESULT scan_files (char* path)
\r
498 if ((res = f_opendir(&dirs, path)) == FR_OK) {
\r
500 while (((res = f_readdir(&dirs, &finfo)) == FR_OK) && finfo.fname[0]) {
\r
501 if (finfo.fattrib & AM_DIR) {
\r
503 *(path+i) = '/'; strcpy(path+i+1, &finfo.fname[0]);
\r
504 res = scan_files(path);
\r
506 if (res != FR_OK) break;
\r
509 acc_size += finfo.fsize;
\r
520 void put_rc (FRESULT rc)
\r
523 static const char str[] =
\r
524 "OK\0" "NOT_READY\0" "NO_FILE\0" "FR_NO_PATH\0" "INVALID_NAME\0" "INVALID_DRIVE\0"
\r
525 "DENIED\0" "EXIST\0" "RW_ERROR\0" "WRITE_PROTECTED\0" "NOT_ENABLED\0"
\r
526 "NO_FILESYSTEM\0" "INVALID_OBJECT\0" "MKFS_ABORTED\0";
\r
529 for (p = str, i = 0; i != rc && *p; i++) {
\r
532 xprintf("rc=%u FR_%s\n", (UINT)rc, p);
\r
542 #define CCLK_DIV 4 // 288MHz / 4 = 72MHz
\r
543 #define USBCLK_DIV 6 // 288MHz / 6 = 48MHz
\r
545 //_RB_ if ( PLLSTAT & (1 << 25) ) {
\r
546 //_RB_ PLLCON = 1; /* Disconnect PLL output if PLL is in use */
\r
547 //_RB_ PLLFEED = 0xAA; PLLFEED = 0x55;
\r
549 //_RB_ PLLCON = 0; /* Disable PLL */
\r
550 //_RB_ PLLFEED = 0xAA; PLLFEED = 0x55;
\r
551 CLKSRCSEL = 0; /* Select IRC (4MHz) as the PLL clock source */
\r
553 SCS |= 0x20; /* Enable main OSC */
\r
554 while( !(SCS & 0x40) ); /* Wait until main OSC is usable */
\r
555 CLKSRCSEL = 0x1; /* select main OSC, 12MHz, as the PLL clock source */
\r
557 //_RB_ PLLCFG = ((PLL_N - 1) << 16) | (PLL_M - 1); /* Re-configure PLL */
\r
558 //_RB_ PLLFEED = 0xAA; PLLFEED = 0x55;
\r
559 //_RB_ PLLCON = 1; /* Enable PLL */
\r
560 //_RB_ PLLFEED = 0xAA; PLLFEED = 0x55;
\r
562 //_RB_ while ((PLLSTAT & (1 << 26)) == 0); /* Wait for PLL locked */
\r
564 CCLKCFG = CCLK_DIV-1; /* Select CCLK frequency (divide ratio of hclk) */
\r
565 USBCLKCFG = USBCLK_DIV-1; /* usbclk = 288 MHz/6 = 48 MHz */
\r
566 //_RB_ PLLCON = 3; /* Connect PLL output to the sysclk */
\r
567 //_RB_ PLLFEED = 0xAA; PLLFEED = 0x55;
\r
569 //_RB_ MAMCR = 0; /* Configure MAM for 72MHz operation */
\r
573 PCLKSEL0 = 0x00000000; /* Initialize peripheral clock to default */
\r
574 PCLKSEL1 = 0x00000000;
\r
576 // ClearVector(); /* Initialie VIC */
\r
578 SCS |= 1; /* Enable FIO0 and FIO1 */
\r
580 FIO1DIR = (1<<26); /* Disable Piezo */
\r
583 FIO2DIR = (1<<30); /* Heartbeat LED output */
\r
586 /* Initialize Timer0 as 1kHz interval timer */
\r
587 // RegisterVector(TIMER0_INT, Isr_TIMER0, PRI_LOWEST, CLASS_IRQ);
\r
588 //_RB_ ctl_set_isr(TIMER0_INT, PRI_LOWEST, CTL_ISR_TRIGGER_FIXED, Isr_TIMER0, 0);
\r
589 //_RB_ ctl_unmask_isr(TIMER0_INT);
\r
592 T0MR0 = 18000 - 1; /* 18M / 1k = 18000 */
\r
593 T0MCR = 0x3; /* Clear TC and Interrupt on MR0 match */
\r
596 uart0_init(); /* Initialize UART0 */
\r
598 // IrqEnable(); /* Enable Irq */
\r
599 ctl_global_interrupts_enable();
\r
610 UINT s1, s2, cnt, blen = sizeof(Buff);
\r
611 DWORD ofs = 0, sect = 0;
\r
612 FATFS *fs; /* Pointer to file system object */
\r
615 BYTE ActiveDisk = 0;
\r
622 xputs("\nFatFs module test monitor for LPC2468\n");
\r
627 if (ConnectedDeviceState == DEVICE_CONNECTED) {
\r
628 ConnectedDeviceState = DEVICE_CLEAR;
\r
629 xprintf("USB Mass Storage device detected\n");
\r
630 rc = Host_EnumDev(); // Enumerate the device connected
\r
633 xprintf("USB device enumerated\n");
\r
637 else if (ConnectedDeviceState == DEVICE_DISCONNECTED) {
\r
638 ConnectedDeviceState = DEVICE_CLEAR;
\r
639 Host_Init(); // FreeDevice();
\r
640 xprintf("Device Disconnected\n");
\r
644 if (get_line(ptr, sizeof(linebuf)) == '\r') {
\r
649 case 'd' : /* md <address> [<count>] - Dump memory */
\r
650 if (!xatoi(&ptr, &p1)) break;
\r
651 if (!xatoi(&ptr, &p2)) p2 = 128;
\r
652 for (ptr=(char*)p1; p2 >= 16; ptr += 16, p2 -= 16) {
\r
653 put_dump((BYTE*)ptr, (UINT)ptr, 16);
\r
655 if (p2) put_dump((BYTE*)ptr, (UINT)ptr, p2);
\r
662 case 'a' : /* da [#] - select active disk */
\r
663 if (xatoi(&ptr, &p1)) {
\r
664 ActiveDisk = (BYTE)p1;
\r
666 ActiveDisk = VerifyActiveDisk(ActiveDisk);
\r
669 case 'd' : /* dd [<lba>] - Dump secrtor */
\r
670 if (!xatoi(&ptr, &p2)) p2 = sect;
\r
671 res = disk_read(ActiveDisk, Buff, p2, 1);
\r
672 // res = disk_read(ActiveDisk, gUsbXferBuffer, p2, 1);
\r
673 if (res) { xprintf("rc=%d\n", (WORD)res); break; }
\r
675 xprintf("Sector:%lu\n", p2);
\r
676 for (ptr=(char*)Buff, ofs = 0; ofs < 0x200; ptr+=16, ofs+=16) {
\r
677 // for (ptr=(char*)gUsbXferBuffer, ofs = 0; ofs < 0x200; ptr+=16, ofs+=16) {
\r
678 put_dump((BYTE*)ptr, ofs, 16);
\r
682 case 'i' : /* di - Initialize disk */
\r
683 xprintf("rc=%d\n", (WORD)disk_initialize(ActiveDisk));
\r
686 case 's' : /* ds <phy_drv#> - Show disk status */
\r
687 // if (!xatoi(&ptr, &p1)) break;
\r
688 if (disk_ioctl(ActiveDisk, GET_SECTOR_COUNT, &p2) == RES_OK)
\r
689 { xprintf("Drive size: %lu sectors\n", p2); }
\r
690 if (disk_ioctl(ActiveDisk, GET_SECTOR_SIZE, &w1) == RES_OK)
\r
691 { xprintf("Sector size: %u\n", w1); }
\r
692 if (disk_ioctl(ActiveDisk, GET_BLOCK_SIZE, &p2) == RES_OK)
\r
693 { xprintf("Erase block size: %lu sectors\n", p2); }
\r
694 if (disk_ioctl(ActiveDisk, MMC_GET_TYPE, &b1) == RES_OK)
\r
695 { xprintf("MMC/SDC type: %u\n", b1); }
\r
696 if (disk_ioctl(ActiveDisk, MMC_GET_CSD, Buff) == RES_OK)
\r
697 { xputs("CSD:\n"); put_dump(Buff, 0, 16); }
\r
698 if (disk_ioctl(ActiveDisk, MMC_GET_CID, Buff) == RES_OK)
\r
699 { xputs("CID:\n"); put_dump(Buff, 0, 16); }
\r
700 if (disk_ioctl(ActiveDisk, MMC_GET_OCR, Buff) == RES_OK)
\r
701 { xputs("OCR:\n"); put_dump(Buff, 0, 4); }
\r
702 if (disk_ioctl(ActiveDisk, MMC_GET_SDSTAT, Buff) == RES_OK) {
\r
703 xputs("SD Status:\n");
\r
704 for (s1 = 0; s1 < 64; s1 += 16) put_dump(Buff+s1, s1, 16);
\r
712 case 'd' : /* bd <addr> - Dump R/W buffer */
\r
713 if (!xatoi(&ptr, &p1)) break;
\r
714 for (ptr=(char*)&Buff[p1], ofs = p1, cnt = 32; cnt; cnt--, ptr+=16, ofs+=16) {
\r
715 put_dump((BYTE*)ptr, ofs, 16);
\r
719 case 'e' : /* be <addr> [<data>] ... - Edit R/W buffer */
\r
720 if (!xatoi(&ptr, &p1)) break;
\r
721 if (xatoi(&ptr, &p2)) {
\r
723 Buff[p1++] = (BYTE)p2;
\r
724 } while (xatoi(&ptr, &p2));
\r
728 xprintf("%04X %02X-", (WORD)(p1), (WORD)Buff[p1]);
\r
729 get_line(linebuf, sizeof(linebuf));
\r
731 if (*ptr == '.') break;
\r
732 if (*ptr < ' ') { p1++; continue; }
\r
733 if (xatoi(&ptr, &p2))
\r
734 Buff[p1++] = (BYTE)p2;
\r
740 case 'r' : /* br <lba> [<num>] - Read disk into R/W buffer */
\r
741 if (!xatoi(&ptr, &p2)) break;
\r
742 if (!xatoi(&ptr, &p3)) p3 = 1;
\r
743 xprintf("rc=%u\n", (WORD)disk_read(ActiveDisk, Buff, p2, p3));
\r
746 case 'w' : /* bw <lba> [<num>] - Write R/W buffer into disk */
\r
747 if (!xatoi(&ptr, &p2)) break;
\r
748 if (!xatoi(&ptr, &p3)) p3 = 1;
\r
749 xprintf("rc=%u\n", (WORD)disk_write(ActiveDisk, Buff, p2, p3));
\r
752 case 'f' : /* bf <val> - Fill working buffer */
\r
753 if (!xatoi(&ptr, &p1)) break;
\r
754 memset(Buff, (BYTE)p1, sizeof(Buff));
\r
762 case 'i' : /* fi <log drv#> - Initialize logical drive */
\r
763 if (!xatoi(&ptr, &p1)) break;
\r
764 put_rc(f_mount((BYTE)p1, &fatfs[p1]));
\r
765 // put_rc(f_mount(ActiveDisk, &fatfs[ActiveDisk]));
\r
768 case 's' : /* fs [<path>] - Show logical drive status */
\r
769 res = f_getfree(ptr, (DWORD*)&p2, &fs);
\r
770 if (res) { put_rc(res); break; }
\r
771 xprintf("FAT type = %u\nBytes/Cluster = %lu\nNumber of FATs = %u\n"
\r
772 "Root DIR entries = %u\nSectors/FAT = %lu\nNumber of clusters = %lu\n"
\r
773 "FAT start (lba) = %lu\nDIR start (lba,cluster) = %lu\nData start (lba) = %lu\n\n",
\r
774 (WORD)fs->fs_type, (DWORD)fs->csize * 512, (WORD)fs->n_fats,
\r
775 fs->n_rootdir, fs->sects_fat, (DWORD)fs->max_clust - 2,
\r
776 fs->fatbase, fs->dirbase, fs->database
\r
778 acc_size = acc_files = acc_dirs = 0;
\r
779 res = scan_files(ptr);
\r
780 if (res) { put_rc(res); break; }
\r
781 xprintf("%u files, %lu bytes.\n%u folders.\n"
\r
782 "%lu KB total disk space.\n%lu KB available.\n",
\r
783 acc_files, acc_size, acc_dirs,
\r
784 (fs->max_clust - 2) * (fs->csize / 2), p2 * (fs->csize / 2)
\r
788 case 'l' : /* fl [<path>] - Directory listing */
\r
789 res = f_opendir(&dir, ptr);
\r
790 if (res) { put_rc(res); break; }
\r
793 res = f_readdir(&dir, &finfo);
\r
794 if ((res != FR_OK) || !finfo.fname[0]) break;
\r
795 if (finfo.fattrib & AM_DIR) {
\r
798 s1++; p1 += finfo.fsize;
\r
800 xprintf("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %s\n",
\r
801 (finfo.fattrib & AM_DIR) ? 'D' : '-',
\r
802 (finfo.fattrib & AM_RDO) ? 'R' : '-',
\r
803 (finfo.fattrib & AM_HID) ? 'H' : '-',
\r
804 (finfo.fattrib & AM_SYS) ? 'S' : '-',
\r
805 (finfo.fattrib & AM_ARC) ? 'A' : '-',
\r
806 (finfo.fdate >> 9) + 1980, (finfo.fdate >> 5) & 15, finfo.fdate & 31,
\r
807 (finfo.ftime >> 11), (finfo.ftime >> 5) & 63,
\r
808 finfo.fsize, &(finfo.fname[0]));
\r
810 xprintf("%4u File(s),%10lu bytes total\n%4u Dir(s)", s1, p1, s2);
\r
811 if (f_getfree(ptr, (DWORD*)&p1, &fs) == FR_OK)
\r
812 xprintf(", %10lu bytes free\n", p1 * fs->csize * 512);
\r
815 case 'o' : /* fo <mode> <file> - Open a file */
\r
816 if (!xatoi(&ptr, &p1)) break;
\r
817 put_rc(f_open(&file1, ptr, (BYTE)p1));
\r
820 case 'c' : /* fc - Close a file */
\r
821 put_rc(f_close(&file1));
\r
824 case 'e' : /* fe - Seek file pointer */
\r
825 if (!xatoi(&ptr, &p1)) break;
\r
826 res = f_lseek(&file1, p1);
\r
829 xprintf("fptr=%lu(0x%lX)\n", file1.fptr, file1.fptr);
\r
832 case 'd' : /* fd <len> - read and dump file from current fp */
\r
833 if (!xatoi(&ptr, &p1)) break;
\r
836 if ((UINT)p1 >= 16) { cnt = 16; p1 -= 16; }
\r
837 else { cnt = p1; p1 = 0; }
\r
838 res = f_read(&file1, Buff, cnt, &cnt);
\r
839 if (res != FR_OK) { put_rc(res); break; }
\r
841 put_dump(Buff, ofs, cnt);
\r
846 case 'r' : /* fr <len> - read file */
\r
847 if (!xatoi(&ptr, &p1)) break;
\r
851 if ((UINT)p1 >= blen) {
\r
852 cnt = blen; p1 -= blen;
\r
856 res = f_read(&file1, Buff, cnt, &s2);
\r
857 if (res != FR_OK) { put_rc(res); break; }
\r
859 if (cnt != s2) break;
\r
861 xprintf("%lu bytes read with %lu kB/sec.\n", p2, p2 / Timer);
\r
864 case 'w' : /* fw <len> <val> - write file */
\r
865 if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break;
\r
866 memset(Buff, (BYTE)p2, blen);
\r
870 if ((UINT)p1 >= blen) {
\r
871 cnt = blen; p1 -= blen;
\r
875 res = f_write(&file1, Buff, cnt, &s2);
\r
876 if (res != FR_OK) { put_rc(res); break; }
\r
878 if (cnt != s2) break;
\r
880 xprintf("%lu bytes written with %lu kB/sec.\n", p2, p2 / Timer);
\r
883 case 'n' : /* fn <old_name> <new_name> - Change file/dir name */
\r
884 while (*ptr == ' ') ptr++;
\r
885 ptr2 = strchr(ptr, ' ');
\r
888 while (*ptr2 == ' ') ptr2++;
\r
889 put_rc(f_rename(ptr, ptr2));
\r
892 case 'u' : /* fu <name> - Unlink a file or dir */
\r
893 put_rc(f_unlink(ptr));
\r
896 case 'v' : /* fv - Truncate file */
\r
897 put_rc(f_truncate(&file1));
\r
900 case 'k' : /* fk <name> - Create a directory */
\r
901 put_rc(f_mkdir(ptr));
\r
904 case 'a' : /* fa <atrr> <mask> <name> - Change file/dir attribute */
\r
905 if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break;
\r
906 put_rc(f_chmod(ptr, p1, p2));
\r
909 case 't' : /* ft <year> <month> <day> <hour> <min> <sec> <name> - Change timestamp */
\r
910 if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break;
\r
911 finfo.fdate = ((p1 - 1980) << 9) | ((p2 & 15) << 5) | (p3 & 31);
\r
912 if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break;
\r
913 finfo.ftime = ((p1 & 31) << 11) | ((p1 & 63) << 5) | ((p1 >> 1) & 31);
\r
914 put_rc(f_utime(ptr, &finfo));
\r
917 case 'x' : /* fx <src_name> <dst_name> - Copy file */
\r
918 while (*ptr == ' ') ptr++;
\r
919 ptr2 = strchr(ptr, ' ');
\r
922 while (*ptr2 == ' ') ptr2++;
\r
923 xprintf("Opening \"%s\"", ptr);
\r
924 res = f_open(&file1, ptr, FA_OPEN_EXISTING | FA_READ);
\r
930 xprintf("Creating \"%s\"", ptr2);
\r
931 res = f_open(&file2, ptr2, FA_CREATE_ALWAYS | FA_WRITE);
\r
938 xprintf("Copying file...");
\r
942 res = f_read(&file1, Buff, blen, &s1);
\r
943 if (res || s1 == 0) break; /* error or eof */
\r
944 res = f_write(&file2, Buff, s1, &s2);
\r
946 if (res || s2 < s1) break; /* error or disk full */
\r
948 xprintf("%lu bytes copied with %lu kB/sec.\n", p1, p1 / Timer);
\r
953 case 'm' : /* fm <partition rule> <cluster size> - Create file system */
\r
954 if (!xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break;
\r
955 xprintf("The drive %u will be formatted. Are you sure? (Y/n)=", ActiveDisk);
\r
956 get_line(ptr, sizeof(linebuf));
\r
958 put_rc(f_mkfs(ActiveDisk, (BYTE)p2, (WORD)p3));
\r
961 case 'z' : /* fz [<rw size>] - Change R/W length for fr/fw/fx command */
\r
962 if (xatoi(&ptr, &p1) && p1 >= 1 && p1 <= sizeof(Buff))
\r
964 xprintf("blen=%u\n", blen);
\r
969 case 't' : /* t [<year> <mon> <mday> <hour> <min> <sec>] */
\r
970 if (xatoi(&ptr, &p1)) {
\r
971 rtc.year = (WORD)p1;
\r
972 xatoi(&ptr, &p1); rtc.month = (BYTE)p1;
\r
973 xatoi(&ptr, &p1); rtc.mday = (BYTE)p1;
\r
974 xatoi(&ptr, &p1); rtc.hour = (BYTE)p1;
\r
975 xatoi(&ptr, &p1); rtc.min = (BYTE)p1;
\r
976 if (!xatoi(&ptr, &p1)) break;
\r
977 rtc.sec = (BYTE)p1;
\r
981 xprintf("%u/%u/%u %02u:%02u:%02u\n", rtc.year, rtc.month, rtc.mday, rtc.hour, rtc.min, rtc.sec);
\r
984 case 'u' : /* usb test commands */
\r
987 case 's' : /* print bulk size */
\r
988 xprintf("MS Bulk size %lu\n", MS_BlkSize);
\r
999 void vApplicationTickHook( void )
\r
1002 /*-----------------------------------------------------------*/
\r
1005 void vConfigureTimerForRunTimeStats( void )
\r
1009 void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTaskName )
\r
1012 xQueueHandle xLCDQueue;
\r