======= tasks.c ======= .. code-block:: c /************************************************************************************ Copyright (c) 2001-2007 University of Washington Extension. Module Name: tasks.c Module Description: The tasks that are executed by the test application. ************************************************************************************/ #include "includes.h" // OS includes #include "print.h" #include "init.h" #include "driver.h" #include "drv_spi.h" #include "drv_mp3.h" #include "mp3/train_crossing.h" #define PLAY_SINE_TEST 1 #define CONTINUOUS 1 // allocate the stacks for each task static OS_STK TaskPlayStk[APP_TASK_DEFAULT_STK_SIZE]; //static OS_STK TaskMonStk[APP_TASK_DEFAULT_STK_SIZE]; // Buffer for making calls to the MP3 driver #define MP3BUFFERSIZE 256 INT8U buffer[MP3BUFFERSIZE]; // task prototypes void PlayTask(void* pdata); void MonTask(void* pdata); static INT32U GetMP3(INT8U* pBuffer, INT32U Length, BOOLEAN Start); void print_f(char *format, ...); static void SetLED(BOOLEAN On); //state variable to track CPU usage static INT32U State = 0; OS_EVENT * SemPrint; //get external reference to the print buffer PRINT_BUFFER(); // Create the driver table. Only need to set the drivers Init functions OSDRV_DRIVER_ENTRY DriverTable[] = { // Init Config, Context Initialized, RefCount { { Spi_Init, NULL, NULL, NULL, NULL, NULL }, { 0 }, NULL, FALSE, 0 }, { { Mp3_Init, NULL, NULL, NULL, NULL, NULL }, { 0 }, NULL, FALSE, 0 } // add additional drivers here }; #define DRIVER_COUNT (sizeof(DriverTable)/sizeof(OSDRV_DRIVER_ENTRY)) /************************************************************************************ This task is the initial task running, started by main(). It starts the system tick timer and creates all the other tasks. Then it deletes itself. ************************************************************************************/ void StartupTask(void* pdata) { INT8U err; print_f("StartupTask: begin\n\r"); print_f("StartupTask: tick timer\n\r"); // Initialize BSP functions //BSP_Init(); // Start the system tick InitializeTimerTick(); // re-init the UART so we can use the serial port //initUART0(38400, UART_8N1, UART_FIFO_OFF, getFcclk()); print_f("StartupTask: After initUART\n\r"); // initialize the driver sub-system err = OSDRV_SubsysInit(DriverTable, DRIVER_COUNT); if (err != OS_DRV_NO_ERR) { print_f("StartupTask: Failed to initialize driver subsystem: %d\n\r", err); //park here while (TRUE) ; } SemPrint = OSSemCreate(1); // create the the test tasks // we have OS_STK_GROWTH set to 1, so the stack grows from high to low print_f("StartupTask: Creating the tasks...\n\r"); OSTaskCreate(PlayTask, (void*) 0, (void*) &TaskPlayStk[APP_TASK_DEFAULT_STK_SIZE - 1], PRIO_5); #ifdef OS_TASK_STAT_EN //create a CPU monitor task //OSStatInit(); // OSTaskCreate(MonTask, (void*)0, (void*)&TaskMonStk[APP_TASK_DEFAULT_STK_SIZE-1], APP_TASK_MON_PRIO); #endif //OS_TASK_STAT_EN // delete ourselves, letting the work be done in the new tasks. print_f("StartupTask: deleting self\n\r"); OSTaskDel(OS_PRIO_SELF); } /************************************************************************************ PlayTask - output some sounds ************************************************************************************/ void PlayTask(void* pdata) { INT8U err; HANDLE hSpi; //handle to SPI driver HANDLE hMp3; //handle to MP3 driver INT32U length; // VS1002 commands const INT8U SineWave[] = { 0x53, 0xEF, 0x6E, 0x44, 0x00, 0x00, 0x00, 0x00 }; const INT8U Deact[] = { 0x45, 0x78, 0x69, 0x74, 0x00, 0x00, 0x00, 0x00 }; const INT8U ModeTest[] = { 0x02, 0x00, 0x08, 0x20 }; const INT8U ModePlay[] = { 0x02, 0x00, 0x08, 0x00 }; const INT8U SoftReset[] = { 0x02, 0x00, 0x08, 0x04 }; INT32U DataMode = 1; INT32U ii; BOOLEAN start; OSSemPend(SemPrint, 0, &err); print_f("PlayTask: begin\n\r"); OSSemPost(SemPrint); //set states as we go along so we track CPU uasge better State = 1; //get a handles to the SPI and MP3 drivers hSpi = Open(SPI_DRV0, OSDRV_WRITE | OSDRV_EXCLUSIVE); if (hSpi == OS_DRV_INVALID_HANDLE) { print_f("PlayTask: failed to open SPI driver\n\r"); OSTaskDel(OS_PRIO_SELF); } hMp3 = Open(MP3_DRV0, OSDRV_WRITE | OSDRV_EXCLUSIVE); if (hMp3 == OS_DRV_INVALID_HANDLE) { print_f("PlayTask: failed to open MP3 driver\n\r"); OSTaskDel(OS_PRIO_SELF); } //tell the MP3 driver which SPI port driver to use length = sizeof(HANDLE); err = Ioctl(hMp3, IOCTL_MP3_SET_SPI, &hSpi, &length); if (err != OS_DRV_NO_ERR) { print_f("PlayTask: failed to set SPI port to open MP3 driver, err: %d\n\r", err); OSTaskDel(OS_PRIO_SELF); } // Reset the MP3 chip length = sizeof(SoftReset); memcpy(buffer, SoftReset, length); err = Write(hMp3, buffer, &length); if (err != OS_DRV_NO_ERR) { print_f("PlayTask: failed write, err: %d\n\r", err); OSTaskDel(OS_PRIO_SELF); } #if PLAY_SINE_TEST // Allow tests length = sizeof(ModeTest); memcpy(buffer, ModeTest, length); err = Write(hMp3, buffer, &length); if (err != OS_DRV_NO_ERR) { print_f("PlayTask: failed write, err: %d\n\r", err); OSTaskDel(OS_PRIO_SELF); } // Set to data mode DataMode = 1; length = sizeof(DataMode); err = Ioctl(hMp3, IOCTL_MP3_SET_DATA_MODE, &DataMode, &length); if (err != OS_DRV_NO_ERR) { print_f("PlayTask: failed to set data mode, err: %d\n\r", err); OSTaskDel(OS_PRIO_SELF); } State = 2; for (ii = 0; ii < 3; ii++) { State = 3; OSSemPend(SemPrint, 0, &err); print_f("PlayTask: playing\n\r"); OSSemPost(SemPrint); // Play test sound (note, first time through the chip may not play) length = sizeof(SineWave); memcpy(buffer, SineWave, length); err = Write(hMp3, buffer, &length); if (err != OS_DRV_NO_ERR) { print_f("PlayTask: failed write, err: %d\n\r", err); OSTaskDel(OS_PRIO_SELF); } SetLED(0); OSTimeDlyHMSM(0, 0, 5, 000); OSSemPend(SemPrint, 0, &err); print_f("PlayTask: stopping\n\r"); OSSemPost(SemPrint); // Stop length = sizeof(Deact); memcpy(buffer, Deact, length); err = Write(hMp3, buffer, &length); if (err != OS_DRV_NO_ERR) { print_f("PlayTask: failed write, err: %d\n\r", err); OSTaskDel(OS_PRIO_SELF); } SetLED(1); OSTimeDlyHMSM(0, 0, 2, 000); } #endif //PLAY_SINE_TEST State = 4; // Set to cmd mode DataMode = 0; length = sizeof(DataMode); err = Ioctl(hMp3, IOCTL_MP3_SET_DATA_MODE, &DataMode, &length); if (err != OS_DRV_NO_ERR) { print_f("PlayTask: failed to set data mode, err: %d\n\r", err); OSTaskDel(OS_PRIO_SELF); } // Set to play mode length = sizeof(ModePlay); memcpy(buffer, ModePlay, length); err = Write(hMp3, buffer, &length); if (err != OS_DRV_NO_ERR) { print_f("PlayTask: failed write, err: %d\n\r", err); OSTaskDel(OS_PRIO_SELF); } // Set to data mode DataMode = 1; length = sizeof(DataMode); err = Ioctl(hMp3, IOCTL_MP3_SET_DATA_MODE, &DataMode, &length); if (err != OS_DRV_NO_ERR) { print_f("PlayTask: failed to set data mode, err: %d\n\r", err); OSTaskDel(OS_PRIO_SELF); } // Loop though the data until done start = TRUE; while (TRUE) { INT32U len; State = 5; len = GetMP3(buffer, MP3BUFFERSIZE, start); start = FALSE; SetLED(1); if (len > 0) { length = len; err = Write(hMp3, buffer, &length); if (err != OS_DRV_NO_ERR) { print_f("PlayTask: failed write, err: %d\n\r", err); while (TRUE) ; //park here on error } } SetLED(0); if (len < MP3BUFFERSIZE) { //we are done with file #ifdef CONTINUOUS start = TRUE; OSSemPend(SemPrint, 0, &err); print_f("PlayTask: restarting\n\r"); OSSemPost(SemPrint); #else //CONTINUOUS break; #endif //CONTINUOUS } } State = 6; OSSemPend(SemPrint, 0, &err); print_f("PlayTask: exiting\n\r"); OSSemPost(SemPrint); OSTaskDel(OS_PRIO_SELF); } /************************************************************************************ GetMP3 - get MP3 buffers pBuffer = buffer to fill Length - size to fill Start - TRUE start at beginning of file return - number of bytes returned. If less than Length, then end of file. ************************************************************************************/ INT32U GetMP3(INT8U* pBuffer, INT32U Length, BOOLEAN Start) { static INT32U current = 0; static INT32U count = 0; INT32U len; if (Start) { current = 0; } count++; len = (Length + current) < sizeof(Wave) ? Length : sizeof(Wave) - current; if (((current) >= (sizeof(Wave) - 100)) || (len > 256)) { INT32U tmp; tmp = len; } memcpy(pBuffer, &Wave[current], len); if (((current) >= (sizeof(Wave) - 100)) || (len > 256)) { INT32U tmp; tmp = len; } current += len; return len; } /************************************************************************************ MonTask - monitor the CPU usage ************************************************************************************/ void MonTask(void* pdata) { INT8U err; //give system time to get initial values OSTimeDlyHMSM(0, 0, 1, 000); while (TRUE) { OSSemPend(SemPrint, 0, &err); print_f("MonTask: cpu %%: %d, state: %d\n\r", OSCPUUsage, State); OSSemPost(SemPrint); OSTimeDlyHMSM(0, 0, 1, 000); } } /************************************************************************************ Toggle the LED next to the display (labeled SD) ************************************************************************************/ static void SetLED(BOOLEAN On) { if (On) { FIO1SET_bit.P1_5 = 1; } else { FIO1CLR_bit.P1_5 = 1; } } /************************************************************************************ Print a formated string. Uses temporary stack buffer. ************************************************************************************/ void print_f(char *format, ...) { char buf[80]; va_list args; va_start(args, format); vsnprintf(buf, 80, format, args); printString(buf); va_end(args); }