tasks.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);
}

Previous topic

drv_mp3.c

Next topic

Operating Systems

This Page