这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » 44b0,IIS,ing 关于44b0的IIS功能,郁闷ing....

共2条 1/1 1 跳转至

44b0,IIS,ing 关于44b0的IIS功能,郁闷ing....

院士
2006-09-17 18:14:16     打赏
44b0,IIS,ing 关于44b0的IIS功能,郁闷ing....



关键词: 关于     功能     郁闷     ing....    

院士
2006-12-22 22:43:00     打赏
2楼

各位,有没有哪位在有OS支持时,使用44b0IIS成功播放过声音?要求44b0工作在Master模式下,播放声音的任务必须是可抢占的,OS类型不限。

我在测试RockOS时发现,当使用不可抢占任务播放声音文件时,一切正常。

当使用可抢占任务播放声音文件时,播放出象机枪开火那样断断续续的噪声。

OS的Tick中断频率默认设置为100Hz,但是播放声音时因为必须根据声音的采样频率修改CPU的主频(并且PLLCON的设置不符合44b0手册的条件,否则无法通过分频得到播放声音所需的频率),因此播放声音时的Tick中断频率是不确定的。 1: IIS的测试代码,给有意测试的朋友友情提供/******************************************************************************
    Copyright (c) 2006 by RockOS.
    All rights reserved.

    This software is supported by the Rock Software Workroom only.

    Any bugs please contact the author with e-mail or QQ:
     E-mail : baobaoba520@yahoo.com.cn
         QQ : 59681888
*******************************************************************************
File name   : iis.c
Description : IIS management for ITSN44b0x.
            :
            :
Author      : sunxinqiu
History     :
  2006-12-31   first release.
******************************************************************************/
#include "os.h"

/******************************************************************************
Function    : STATUS init_iis()
Params      : N/A
            :
            :
            :
Return      : OS_SUCCESS.
Description : init IIS sound.
            :
******************************************************************************/
STATUS init_iis()
{
    /* The IISCON register:
     * Bit 8: L/R channel index (RO).
     * Bit 7: Transmit FIFO ready flag (RO).
     * Bit 6: Receive FIFO ready flag (RO).
     * Bit 5: Transmit DMA service request enable (1 - enable)
     * Bit 4: Receive DMA service request enable (0 - disable)
     * Bit 3: Transmit channel idle command (0 - IISLRCK is generated).
     * Bit 2: Receive channel idle command(0 - IISLRCK is generated)
     * Bit 1: IIS prescaler enable (0 - prescaler disable).
     * Bit 0: IIS interface stop/start(0 - stop, 1 - start).
     */
    rIISCON=0x00; /* stop IIS if it is playing.*/

    return OS_SUCCESS;
}

/******************************************************************************
Function    : STATUS iis_play ()
Params      : numChannels - number of channels.
            : sampleRate  - the sampling rate for this wave.
            : byteRate    - the bytes rate for this wave.
            : bitsPerSample - number of bits per sample for this wave.
            : psamples    - the samples for this wave.
            : sampleSize  - size of the samples (in bytes).
            :
Return      : OS_SUCCESS for IIS playing successfully, else OS_FAIL.
Description : play the wave data as specified wave type.
            :
******************************************************************************/
STATUS iis_play (uint32_t numChannels,
               uint32_t sampleRate,
               uint32_t byteRate,
               uint32_t bitsPerSample,
               void *   psamples,
               uint32_t sampleSize)
{
    int i;
    int errflag;

    uint32_t offset;
    uint32_t pllcon;

    uint16_t val;

    if ((numChannels != 1) && (numChannels != 2))
    {
        OS_error("iis_play(): %d channel wave is not supported, only 1 or 2 channel is valid.\n");
        return OS_FAIL;
    }

    if ((bitsPerSample != 8) && (bitsPerSample != 16))
    {
        OS_error("iis_play(): sample width %d is not supported, only 8 or 16 is valid.\n", bitsPerSample);
        return OS_FAIL;
    }

    pllcon = rPLLCON;   /* we must change the MCLK of the CPU, save it first. */

    OS_printf("Wave channels : %d\n", numChannels);
    OS_printf("Sample Rate   : %d\n", sampleRate);
    OS_printf("byteRate      : %d\n", byteRate);
    OS_printf("bitsPerSample : %d\n", bitsPerSample);
    OS_printf("sampleSize    : %d\n", sampleSize);

    /* config all registers according the sampling frequancy. */
    errflag = 0;
    switch(sampleRate)
    {
    case 22050:
        /* change MCLK to 45158400Hz (45151515Hz accurately). */
        setMCLK(0x69, 0x17, 0);
        set_uart_mode(UART_CH0, BAUD_DEFAULT, PARITY_NONE);
        set_uart_mode(UART_CH1, BAUD_DEFAULT, PARITY_NONE);
        Delay(1000);

        rIISMOD = 0x81;     /* Master, Tx-mode, Low for Left, IIS compatible, 8bit(*), MCLK=256fs, SCLK=32fs*/
        rIISPSR = 0x33;     /* prescaler_A = prescaler_B = 8. */
        rIISFCON = 0x200;   /* Tx FIFO enable, Rx FIFO disable. */
        rIISCON = 0x02;     /* Tx-DMA disable, Rx-DMA disable, Prescaler enable, start IIS play. */
        break;

    case 44100:
        /* change MCLK to 45158400Hz (45151515Hz accurately). */
        setMCLK(0x8d, 0x1f, 0);
        set_uart_mode(UART_CH0, BAUD_DEFAULT, PARITY_NONE);
        set_uart_mode(UART_CH1, BAUD_DEFAULT, PARITY_NONE);
        Delay(1000);

        rIISMOD = 0x85;     /* Master, Tx-mode, Low for Left, IIS compatible, 8bit(*), MCLK=384fs, SCLK=32fs*/
        rIISPSR = 0x11;     /* prescaler_A = prescaler_B = 4. */
        rIISFCON = 0x200;   /* Tx FIFO enable, Rx FIFO disable. */
        rIISCON = 0x02;     /* Tx-DMA disable, Rx-DMA disable, Prescaler enable, start IIS play. */
        break;

    default:
        errflag = 1;
        break;
    }

    if (errflag != 0)
    {
        rPLLCON = pllcon;
        set_uart_mode(UART_CH0, BAUD_DEFAULT, PARITY_NONE);
        set_uart_mode(UART_CH1, BAUD_DEFAULT, PARITY_NONE);
        OS_error("iis_play(): sample frequancy %dHz is not support!!!\n", sampleRate);
        Delay(1000);
        return OS_FAIL;
    }

    /* config the IISMOD according the sample width. */
    errflag = 0;
    switch(bitsPerSample)
    {
    case 8:
        rIISMOD &= ~(1<<3); /* bit3 = 0, 8-bits sample data.*/

        /* play sound wave now. */
        rIISCON |= 1;   /* start play. */

        offset = 0;
        while (offset < sampleSize)
        {
            while((rIISCON&(1<<7))!=0);
            for (i = 0; i < 8; i++)    /* IIS has 16-bytes FIFO buffer. */
            {
                *rIISFIF = (uint16_t)((uint8_t *)psamples)[offset];
                offset++;
            }
        }
        break;

    case 16:
        rIISMOD |= (1<<3);  /* bit3 = 1, 16-bits sample data.*/

        /* play sound wave now. */
        rIISCON |= 1;   /* start play. */

        offset = 0;
        while (offset < sampleSize)
        {
            while((rIISCON&(1<<7))!=0);
            for (i = 0; i < 8; i++)    /* IIS has 16-bytes FIFO buffer. */
            {
                val = uint16_l2h(((uint16_t *)psamples)[offset]);
                *rIISFIF = uint16_l2h(((uint16_t *)psamples)[offset]);
                offset++;
            }
        }
        break;

    default:
        errflag = 1;
        break;
    }

    rIISCON &= ~1;      /* stop IIS. */
    rPLLCON = pllcon;   /* restore the CPU's MCLK. */
    set_uart_mode(UART_CH0, BAUD_DEFAULT, PARITY_NONE);
    set_uart_mode(UART_CH1, BAUD_DEFAULT, PARITY_NONE);

    return OS_SUCCESS;
}

2: 播放*.wav文件的入口代码/******************************************************************************
    Copyright (c) 2006 by RockOS.
    All rights reserved.

    This software is supported by the Rock Software Workroom only.

    Any bugs please contact the author with e-mail or QQ:
     E-mail : baobaoba520@yahoo.com.cn
         QQ : 59681888
*******************************************************************************
File name   : wave.c
Description : play *.wav sound file, writing for ITSN44b0x.
            :
            :
Author      : sunxinqiu
History     :
  2006-12-31   first release.
******************************************************************************/
#include "os.h"
#include "wave.h"

/******************************************************************************
Global var  : HSEM g_waveSem;
Description : a mutex for play wave sound one by one.
            :
******************************************************************************/
HSEM g_waveSem;

/******************************************************************************
Global var  : extern uint32_t welcome;
Description : this is a wave sound file descriped by a .s file.
            :
******************************************************************************/
extern uint32_t welcome;

/******************************************************************************
Function    : STATUS wave_init(void)
Params      : N/A
            :
            :
            :
Return      : OS_SUCCESS, or OS_FAIL if error.
Description : init wave sound task.
            :
******************************************************************************/
STATUS wave_init()
{
    TASK_INFO taskInfo;

    /* create wave semaphore. */
    g_waveSem = semCreate(OS_SEM_COMMON, 0, "waveSem");

    /* create wave task. */
    taskInfo.priority = 10;
    strcpy (&taskInfo.name[0], "tWave");
    taskInfo.taskEntry = tWaveEntry;
    taskInfo.pData = NULL;
    taskInfo.msgQSize = 0;
    taskInfo.mutexQSize = DEFAULT_MUTEX_Q_SIZE;
    taskInfo.stackSize = DEFAULT_STACK_SIZE;
    taskInfo.option = OPT_TASK_LOCK;
    taskCreate(&taskInfo);

    /* register shell command. */
    regShellCmd(wavplay, "wavplay", "play welcome to RockOS wave.");

    return OS_SUCCESS;
}

/******************************************************************************
Function    : void tWaveEntry (void * p)
Params      : p - not used.
            :
            :
            :
Return      : N/A
Description : entry for wave sound demo task.
            :
******************************************************************************/
void tWaveEntry (void * p)
{
    (void)p;

    while (1)
    {
        semTake(g_waveSem, OS_WAIT_FOR_EVER);
        play_wav((void *)&welcome);
    }
}

/******************************************************************************
Function    : int wavplay(int argc, char * argv[])
Params      : argc - the argument count (including command name).
            : argv - the arguments (argv[0] is the command name)
            :
            :
Return      : always 0.
Description : shell command for playing wave sound.
            :
******************************************************************************/
int wavplay(int argc, char * argv[])
{
    (void)argc;
    (void)argv;

    semGive(g_waveSem);
    return 0;
}

/******************************************************************************
Function    : BOOL iswave (void * pbuff)
Params      : pbuff - a buffer, always the first some bytes from a file.
            :
            :
            :
Return      : OS_TRUE, or OS_FAILSE if pbuff is not a wave buffer.
Description : to judge a buffer is, or is not a wave buffer.
            :
******************************************************************************/
BOOL iswave (void * pbuff)
{
    BOOL nret;

    RIFF_HEADER * priff;

    nret = OS_TRUE;
    priff = (RIFF_HEADER *)pbuff;
    if ((priff->riffId[0] != 'R')
         ||(priff->riffId[1] != 'I')
         ||(priff->riffId[2] != 'F')
         ||(priff->riffId[3] != 'F'))
    {
        nret = OS_FALSE;
    }

    if (nret == OS_TRUE)
    {
        if ((priff->format[0] != 'W')
            ||(priff->format[1] != 'A')
            ||(priff->format[2] != 'V')
            ||(priff->format[3] != 'E'))
        {
            nret = OS_FALSE;
        }
    }

    return nret;
}

/******************************************************************************
Function    : STATUS play_wav(void * pwave)
Params      : pWave - the wave buffer.
            :
            :
            :
Return      : OS_SUCCESS when starting play, or OS_FAIL if it's not a .wav file
Description : play a buffer which save the .wav sound file.
            :
******************************************************************************/
STATUS play_wav(void * pwave)
{
    RIFF_HEADER * priff;

    SUBCHUNK    * psubchunk;
    FMT_CHUNK   * pfmt;
    DATA_CHUNK  * pdata;

    priff = (RIFF_HEADER *)pwave;
    if (iswave(priff) != OS_TRUE)
    {
        OS_error("play_wav(): not a valid wave sound.\n");
        return OS_FAIL;
    }

    /* find the "fmt" subchunk, it is mandatory for wave file. */
    pfmt = NULL;
    psubchunk = (SUBCHUNK *)((uint8_t *)pwave + sizeof(RIFF_HEADER));
    while ((void *)psubchunk < (void *)((uint8_t *)priff + priff->riffSize + 8))
    {
        if ((psubchunk->name[0] = 'f')
            &&(psubchunk->name[1] = 'm')
            &&(psubchunk->name[2] = 't'))
        {
            pfmt = (FMT_CHUNK *)psubchunk;
            break;
        }
        else
        {
            psubchunk = (SUBCHUNK *)((uint8_t *)psubchunk + psubchunk->subchunkSize + 8);
        }
    }

    if (pfmt == NULL)
    {
        OS_error("play_wave(): mandatory subchunk 'fmt' not found, wave file invalid!\n");
        return OS_FAIL;
    }

    /* find the "data" subchunk, it is mandatory for wave file (man sound). */
    pdata = NULL;
    psubchunk = (SUBCHUNK *)((uint8_t *)pfmt + sizeof(FMT_CHUNK));
    while ((void *)psubchunk < (void *)((uint8_t *)priff + priff->riffSize + 8))
    {
        if ((psubchunk->name[0] = 'd')
            &&(psubchunk->name[1] = 'a')
            &&(psubchunk->name[2] = 't')
            &&(psubchunk->name[3] = 'a'))
        {
            pdata = (DATA_CHUNK *)psubchunk;
            break;
        }
        else
        {
            psubchunk = (SUBCHUNK *)((uint8_t *)psubchunk + psubchunk->subchunkSize + 8);
        }
    }
    if (pdata == NULL)
    {
        OS_error("play_wave(): mandatory subchunk 'data' not found, wave file invalid!\n");
        return OS_FAIL;
    }

    if (pfmt->audioFormat != WAVE_MS_FORMAT_PCM)
    {
        OS_error("play_wave(): only support Microsoft Pulse Code Modulation (PCM) wave file!\n"
                 "This wave format (0x%04x) CAN't played!!\n", uint16_l2h(pfmt->audioFormat));
        return OS_FAIL;
    }
    iis_play((uint32_t)uint16_l2h(pfmt->numChannels),
             (uint32_t)uint32_l2h(pfmt->sampleRate),
             (uint32_t)uint32_l2h(pfmt->byteRate),
             (uint32_t)uint16_l2h(pfmt->bitsPerSample),
             &pdata->data[0],
             (uint32_t)uint32_l2h(pdata->dataSize));

    return OS_SUCCESS;
}
3: wave.c的头文件/******************************************************************************
    Copyright (c) 2006 by RockOS.
    All rights reserved.

    This software is supported by the Rock Software Workroom only.

    Any bugs please contact the author with e-mail or QQ:
     E-mail : baobaoba520@yahoo.com.cn
         QQ : 59681888
*******************************************************************************
File name   : wave.h
Description : sound wave file format, for RockOS.
            :
            :
Author      : sunxinqiu
History     :
  2006-12-31   first release.
******************************************************************************/
#ifndef __WAVE_H__
#define __WAVE_H__

#ifdef __cplusplus
extern "C"
{
#endif

/* wave file code. */
enum
{
    WAVE_MS_FORMAT_PCM    = 0x0001, /* microsoft PCM format.  */
    WAVE_IBM_FORMAT_MULAW = 0x0101, /* IBM IBM mu-law format. */
    WAVE_IBM_FORMAT_ALAW  = 0x0102, /* IBM a-law format.      */
    WAVE_IBM_FORMAT_ADPCM = 0x0103  /* IBM AVC Adaptive Differential PCM format. */
};

/* RIFF header fields: */
typedef struct
{
    char     riffId[4];     /* "RIFF" */
    uint32_t riffSize;      /* euqal to file size - 8.*/
    char     format[4];     /* "WAVE "*/
}RIFF_HEADER;

typedef struct
{
    char     name[4];       /* subchunk name. */
    uint32_t subchunkSize;  /* subchunk size (excluding the name and len fields). */
    uint8_t  data[1];
}SUBCHUNK;

/* "fmt" chunk fields: */
typedef struct
{
    char     fmtId[4];      /* "fmt" */
    uint32_t fmtSize;       /* 0x00000010 for WAVE file. */
    uint16_t audioFormat;   /* 0x0001 for PCM file. */
    uint16_t numChannels;   /* 1 for Mono, 2 for Stereo. */
    uint32_t sampleRate;    /* 8000, 44100 etc.*/
    uint32_t byteRate;      /* = sampleRate * NumChannels * BitsPerSample / 8 */
    uint16_t blockAlign;    /* = numChannels * BitsPerSample / 8 */
    uint16_t bitsPerSample; /* 8, 16, etc. */
}FMT_CHUNK;

/* "data" chunk fields: */
typedef struct
{
    char     dataId[4];     /* "data" */
    uint32_t dataSize;      /* = numSamples * numChannels * bitsPerSample / 8 */

    uint8_t  data[1];
}DATA_CHUNK;

STATUS wave_init(void);
void tWaveEntry (void * p);
int wavplay(int argc, char * argv[]);

BOOL iswave (void * pbuff);
STATUS play_wav(void * pwave);

#ifdef __cplusplus
}
#endif

#endif

4: 要设成DMA模式把下面寄存器改成DMA模式:

rIISCON = 0x02;     /* Tx-DMA disable, Rx-DMA disable, Prescaler enable, start IIS play. */

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]