⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vs1001k.c

📁 含有完整TCP/IP PPP协议的嵌入式操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
 * \return 0 on success, -1 otherwise. */int VsPlayerStop(void){    cbi(EIMSK, VS_DREQ_BIT);    /* Check whether we need to stop at all to not overwrite other than running status */    if (vs_status == VS_STATUS_RUNNING)        vs_status = VS_STATUS_STOPPED;    sbi(EIMSK, VS_DREQ_BIT);    return 0;}/*! * \brief Sets up decoder internal buffer flushing. * * This routine will set up internal VS buffer flushing, * unless the buffer is already empty and starts the playback * if necessary. The internal VS buffer is flushed in VsPlayerFeed() * at the end of the stream. * * \return 0 on success, -1 otherwise. */int VsPlayerFlush(void){    cbi(EIMSK, VS_DREQ_BIT);    /* Set up fluhing unless both buffers are empty. */    if (vs_status != VS_STATUS_EMPTY || vs_readptr != vs_writeptr) {        if (vs_flush == 0)            vs_flush = VS_FLUSH_BYTES;        /* start the playback if necessary */        if (vs_status != VS_STATUS_RUNNING)            VsPlayerKick();    }    sbi(EIMSK, VS_DREQ_BIT);    return 0;}/*! * \brief Initialize the VS1001 hardware interface. * * \return 0 on success, -1 otherwise. */int VsPlayerInit(void){    /* Disable decoder interrupts. */    cbi(EIMSK, VS_DREQ_BIT);    /* Keep decoder in reset state. */    cbi(VS_RESET_PORT, VS_RESET_BIT);    sbi(VS_RESET_DDR, VS_RESET_BIT);    /* Set BSYNC output low. */    cbi(VS_BSYNC_PORT, VS_BSYNC_BIT);    sbi(VS_BSYNC_DDR, VS_BSYNC_BIT);    /* Set MP3 chip select output low. */    sbi(VS_XCS_PORT, VS_XCS_BIT);    sbi(VS_XCS_DDR, VS_XCS_BIT);    /* Set DREQ input with pullup. */    sbi(VS_DREQ_PORT, VS_DREQ_BIT);    cbi(VS_DREQ_DDR, VS_DREQ_BIT);    /* Init SPI Port. */    sbi(VS_SI_DDR, VS_SI_BIT);    sbi(VS_SS_DDR, VS_SS_BIT);    cbi(VS_SO_DDR, VS_SO_BIT);    /* Set SCK output low. */    cbi(VS_SCK_PORT, VS_SCK_BIT);    sbi(VS_SCK_DDR, VS_SCK_BIT);#ifndef VS_NOSPI    {        u_char dummy;           /* Required by some compilers. */        /*          * Init SPI mode to no interrupts, enabled, MSB first, master mode,          * rising clock and fosc/4 clock speed. Send an initial zero byte to          * make sure SPIF is set. Note, that the decoder reset line is still         * active.         */        outp(BV(MSTR) | BV(SPE), SPCR);        dummy = inp(SPSR);        outp(0, SPDR);    }#endif    /* Rising edge will generate interrupts. */    sbi(EICR, 5);    sbi(EICR, 4);    /* Register the interrupt routine */    NutRegisterIrqHandler(&sig_INTERRUPT6, VsPlayerFeed, NULL);    /* Release decoder reset line. */    sbi(VS_RESET_PORT, VS_RESET_BIT);    NutDelay(4);    /* Force frequency change (see datasheet). */    VsRegWrite(VS_CLOCKF_REG, 0x9800);    VsRegWrite(VS_INT_FCTLH_REG, 0x8008);    NutDelay(200);    /* Clear any spurious interrupt and enable decoder interrupts. */    outp(BV(VS_DREQ_BIT), EIFR);    sbi(EIMSK, VS_DREQ_BIT);    return 0;}/*! * \brief Software reset the decoder. * * This function is typically called after VsPlayerInit() and at the end * of each track. * * \param mode Any of the following flags may be or'ed * - VS_SM_DIFF Left channel inverted. * - VS_SM_FFWD Fast forward. * - VS_SM_RESET Force hardware reset. * - VS_SM_PDOWN Switch to power down mode. * - VS_SM_BASS Bass/treble enhancer. * * \return 0 on success, -1 otherwise. */int VsPlayerReset(u_short mode){    /* Disable decoder interrupts and feeding. */    cbi(EIMSK, VS_DREQ_BIT);    vs_status = VS_STATUS_STOPPED;    /* Software reset, set modes of decoder. */    VsRegWrite(VS_MODE_REG, VS_SM_RESET | mode);    NutDelay(2);    /*     * Check for correct reset.     */    if ((mode & VS_SM_RESET) != 0 || bit_is_clear(VS_DREQ_PIN, VS_DREQ_BIT)) {        /* If not succeeded, give it one more chance and try hw reset,           HW reset may also be forced by VS_SM_RESET mode bit. */        cbi(VS_RESET_PORT, VS_RESET_BIT);        _NOP();        sbi(VS_RESET_PORT, VS_RESET_BIT);        NutDelay(4);        /* Set the requested modes. */        VsRegWrite(VS_MODE_REG, VS_SM_RESET | mode);        NutDelay(2);        if (bit_is_clear(VS_DREQ_PIN, VS_DREQ_BIT))            return -1;    }    /* Force frequency change (see datasheet). */    VsRegWrite(VS_CLOCKF_REG, 0x9800);    VsRegWrite(VS_INT_FCTLH_REG, 0x8008);    NutDelay(2);    /* Clear any spurious interrupt and enable decoder interrupts. */    outp(BV(VS_DREQ_BIT), EIFR);    sbi(EIMSK, VS_DREQ_BIT);    return 0;}/*! * \brief Set mode register of the decoder. * * \param mode Any of the following flags may be or'ed * - VS_SM_DIFF Left channel inverted. * - VS_SM_FFWD Fast forward. * - VS_SM_RESET Software reset. * - VS_SM_PDOWN Switch to power down mode. * - VS_SM_BASS Bass/treble enhancer. * * \return 0 on success, -1 otherwise. */int VsPlayerSetMode(u_short mode){    cbi(EIMSK, VS_DREQ_BIT);    VsRegWrite(VS_MODE_REG, mode);    sbi(EIMSK, VS_DREQ_BIT);    return 0;}/*! * \brief Initialize the MP3 data buffer. * * \param size Number of bytes to allocate for the data buffer. *             Should be at least 4k. If this parameter is 0, *             all available memory minus 8k are allocated. * * \return Pointer to the data buffer or null on failures. */u_char *VsBufferInit(u_short size){    if (size == 0)        size = NutHeapAvailable() - 8192;    if ((vs_databuff = NutHeapAlloc(size)) != 0)        vs_dataend = vs_databuff + size;    vs_readptr = vs_writeptr = vs_databuff;    return vs_writeptr;}/*! * \brief Reset all MP3 data buffer pointers. * * \return Pointer to the data buffer. */u_char *VsBufferReset(void){    cbi(EIMSK, VS_DREQ_BIT);    vs_readptr = vs_writeptr = vs_databuff;    sbi(EIMSK, VS_DREQ_BIT);    return vs_databuff;}/*! * \brief Request MP3 data buffer space. * * \param sizep Pointer to an unsigned short, which receives the *              number of bytes available in the buffer. * * \return Pointer to the next write position. */u_char *VsBufferRequest(u_short * sizep){    cbi(EIMSK, VS_DREQ_BIT);    if (vs_writeptr >= vs_readptr)        *sizep = vs_dataend - vs_writeptr - (vs_readptr == vs_databuff);    else        *sizep = vs_readptr - vs_writeptr - 1;    sbi(EIMSK, VS_DREQ_BIT);    return vs_writeptr;}/*! * \brief Acknowledge filled buffer space. * * \return Pointer to the next write position. */u_char *VsBufferAcknowledge(u_short nbytes){    cbi(EIMSK, VS_DREQ_BIT);    vs_writeptr += nbytes;    if (vs_writeptr == vs_dataend)        vs_writeptr = vs_databuff;    /* Cancel flushing in progress. */    vs_flush = 0;    sbi(EIMSK, VS_DREQ_BIT);    return vs_writeptr;}/*! * \brief Returns total free buffer space. * * \return Total number of free bytes in the buffer. */u_short VsBufferAvailable(void){    u_short avail;    cbi(EIMSK, VS_DREQ_BIT);    if (vs_writeptr >= vs_readptr)        avail = (vs_dataend - vs_databuff) - (vs_writeptr - vs_readptr);    else        avail = (vs_readptr - vs_writeptr) - 1;    sbi(EIMSK, VS_DREQ_BIT);    return avail;}/*! * \brief Returns play time since last reset. * * \return Play time since reset in seconds */u_short VsPlayTime(void){    u_short rc;    cbi(EIMSK, VS_DREQ_BIT);    rc = VsRegRead(VS_DECODE_TIME_REG);    sbi(EIMSK, VS_DREQ_BIT);    return rc;}/*! * \brief Returns status of the player. * * \return Any of the following value: * - VS_STATUS_STOPPED Player is ready to be started by VsPlayerKick(). * - VS_STATUS_RUNNING Player is running. * - VS_STATUS_EOF Player has reached the end of a stream after VsPlayerFlush() has been called. * - VS_STATUS_EMPTY Player runs out of data. VsPlayerKick() will restart it. */u_char VsGetStatus(void){    return vs_status;}#ifdef __GNUC__/*! * \brief Query MP3 stream header information. * * \param vshi Pointer to VS_HEADERINFO structure. * * \return 0 on success, -1 otherwise. */int VsGetHeaderInfo(VS_HEADERINFO * vshi){    u_short *usp = (u_short *) vshi;    cbi(EIMSK, VS_DREQ_BIT);    *usp = VsRegRead(VS_HDAT1_REG);    *++usp = VsRegRead(VS_HDAT0_REG);    sbi(EIMSK, VS_DREQ_BIT);    return 0;}#endif/*! * \brief Initialize decoder memory test and return result. * * \return Memory test result. * - Bit 0: Good X ROM * - Bit 1: Good Y ROM (high) * - Bit 2: Good Y ROM (low) * - Bit 3: Good Y RAM * - Bit 4: Good X RAM * - Bit 5: Good Instruction RAM (high) * - Bit 6: Good Instruction RAM (low) */u_short VsMemoryTest(void){    u_short rc;    static prog_char mtcmd[] = { 0x4D, 0xEA, 0x6D, 0x54, 0x00, 0x00, 0x00, 0x00 };    cbi(EIMSK, VS_DREQ_BIT);    VsSdiWrite_P(mtcmd, sizeof(mtcmd));    NutDelay(40);    rc = VsRegRead(VS_HDAT0_REG);    sbi(EIMSK, VS_DREQ_BIT);    return rc;}/*! * \brief Set volume. * * \param left  Left channel volume. * \param right Right channel volume. * * \return 0 on success, -1 otherwise. */int VsSetVolume(u_char left, u_char right){    cbi(EIMSK, VS_DREQ_BIT);    VsRegWrite(VS_VOL_REG, (((u_short) left) << 8) | (u_short) right);    sbi(EIMSK, VS_DREQ_BIT);    return 0;}/*! * \brief Sine wave beep. * * \param fsin Frequency. * \param ms   Duration. * * \return 0 on success, -1 otherwise. */int VsBeep(u_char fsin, u_char ms){    static prog_char on[] = { 0x53, 0xEF, 0x6E };    static prog_char off[] = { 0x45, 0x78, 0x69, 0x74 };    static prog_char end[] = { 0x00, 0x00, 0x00, 0x00 };    /* Disable decoder interrupts. */    cbi(EIMSK, VS_DREQ_BIT);    fsin = 56 + (fsin & 7) * 9;    VsSdiWrite_P(on, sizeof(on));    VsSdiWrite(&fsin, 1);    VsSdiWrite_P(end, sizeof(end));    NutDelay(ms);    VsSdiWrite_P(off, sizeof(off));    VsSdiWrite_P(end, sizeof(end));    /* Enable decoder interrupts. */    sbi(EIMSK, VS_DREQ_BIT);    return 0;}/*@}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -