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

📄 tmdlao.c

📁 Nexperia系统声音实现的源码
💻 C
📖 第 1 页 / 共 4 页
字号:

aoOpenExit:
    tmosalSystemMutexExit();

    return err;
}

/**************************************************************************************/
extern tmErrorCode_t tmdlAoInstanceSetup(Int instance, ptmdlAoInstanceSetup_t pSetup)
{
    paoInstVars_t          instVars       = (paoInstVars_t) instance;
    tmbslAoParam_t         param;
    tmbslAoConfig_t       *boardAOConfig  = instVars->boardAOConfig;
    UInt32                 mmioBase       = boardAOConfig->mmioBase;
    tmErrorCode_t          err            = TM_OK;
    Float                  fOsclk;
    ptmbslCoreSystemInfo_t SysInfo;
    UInt32                 frameLength;
    UInt32                 sckDiv;
    UInt32                 rightPos;
    tmosalIntDescriptor_t  descriptor;
    UInt8                  cpuIndex;

    DBG_ISR_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoInstanceSetup(%x,%x)\n", instance, pSetup));
    tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);
    tmAssert (pSetup, TMDL_ERR_AO_NULL_PARAMETER);
    tmAssert ((pSetup->size % AO_SIZE_GRANULARITY) == 0, TMDL_ERR_AO_INVALID_SIZE);
    tmAssert (((UInt) pSetup->base1 % AO_BASE_GRANULARITY) == 0, TMDL_ERR_AO_INVALID_SIZE);
    tmAssert (((UInt) pSetup->base2 % AO_BASE_GRANULARITY) == 0, TMDL_ERR_AO_INVALID_SIZE);

    if (instVars->magic != AO_MAGIC)
        return TMDL_ERR_AO_NOT_OWNER;

    //tmosalSystemMutexEnter();

    param.aoUnit             = instVars->unitName;
    /*devlib is not bothered about the DAC this is used by the channel
      component to tell the ABSL component about the DAC nr for the unit */
    param.dacNr              = 0;
    param.audioTypeFormat    = pSetup->audioTypeFormat;
    param.audioSubtypeFormat = pSetup->audioSubtypeFormat;
    param.sRate              = pSetup->sRate;
    param.size               = pSetup->size;
    param.output             = pSetup->output;
    param.callBack           = pSetup->callBack;
    param.pContextArgument   = pSetup->pContextArgumentToCallBack;
    param.eventsTobeEnabled  = pSetup->eventsTobeEnabled;


    if (!(param.audioTypeFormat & boardAOConfig->audioTypeFormats))
    {
        err = TMDL_ERR_AO_UNSUPPORTED_DATATYPE;
        goto aoInstanceSetupExit;
    }

    if (!(param.audioSubtypeFormat & boardAOConfig->audioSubtypeFormats))
    {
        err = TMDL_ERR_AO_UNSUPPORTED_DATASUBTYPE;
        goto aoInstanceSetupExit;
    }

    if (!(param.output & boardAOConfig->audioAdapters))
    {
        err = TMDL_ERR_AO_UNSUPPORTED_OUTPUT;
        goto aoInstanceSetupExit;
    }

    if (param.sRate > boardAOConfig->maxSRate)
    {
        err = TMDL_ERR_AO_SRATE_TOO_HIGH;
        goto aoInstanceSetupExit;
    }

    if (param.sRate < boardAOConfig->minSRate)
    {
        err = TMDL_ERR_AO_SRATE_TOO_LOW;
        goto aoInstanceSetupExit;
    }

    /* get the processor type of the TriMedia CPU */
    err = tmbslCoreGetSystemInfo(&SysInfo);
    if (err) return err;
    for(cpuIndex=0; cpuIndex < SysInfo->numCpu; cpuIndex++)
    	  if(SysInfo->pCpuInfo[cpuIndex].cpuType == tmbslCoreCpuTypeTM) break;

    /*calculate the required oversampling clock */
    fOsclk = boardAOConfig->osclkFactor * param.sRate; /* n X Fs */

    if(boardAOConfig->enableOsclk)
    {
       if(err =(aoSetClock(instVars->unitName, mmioBase, fOsclk,
       	          SysInfo->pCpuInfo[cpuIndex].cpuClockFreq)))
       	  return err;
    }

    /* setup audio out unit as per the requirement by audio board config structure */

    //Enable Audio out serial Clock ie,SCK
    if(boardAOConfig->enableSerialMaster)
        aoEnableSER_MASTERM(mmioBase);         /* audio out is the serial master */
    else
        aoDisableSER_MASTERM(mmioBase);        /* audio out is the serial slave */

    /* setup for I2S transfer ie MSB first and left channel data on falling edge*/
    aoMsbFirstM(mmioBase);                 /* MSB bit is transmitted first (I2S standard) */
    aoStartFallingEdgeWSM(mmioBase);       /* send left channel sample on Falling edge(I2S standard) */
    aoSampleRisingCLOCK_EDGEM(mmioBase);   /* sample on rising edge */
    aoSetSSPOSM(mmioBase, 0);              /* Left and right channel start at bit 0 */
    aoDisableSIGN_CONVERTM(mmioBase);      /* Disable Sign Convert for MSB */
    aoDisableWS_PULSEM(mmioBase);          /* word strobe in pulse mode */

#if (TMFL_PNX_ID == 1300)   // PNX1300/TM1300

#ifdef __LITTLE_ENDIAN__
       aoEnableLITTLE_ENDIANM(mmioBase);
#else
       aoDisableLITTLE_ENDIANM(mmioBase);
#endif

#endif

    /*Initial state of the device */
//    aoDisableTRANS_ENABLEM(mmioBase);      /* intially disabeled */
    aoSetSIZEM(mmioBase, pSetup->size);

    /* setup for I2S transfer physical parameters */
    switch (param.audioSubtypeFormat) {
        case apfMono16:               /* one channel Audio */
        {
            frameLength = boardAOConfig->frameLength[MONO16];
            aoSetTRANS_MODEM(mmioBase, 2);                                    /* transfer mode is mono 16*/
            aoSetNR_CHANM(mmioBase, 0);
            break;
        }
        case apfMono32:                 /* one channel Audio, 32-bit */
        {
            frameLength = boardAOConfig->frameLength[MONO32];
            aoSetTRANS_MODEM(mmioBase, 0);                                    /* transfer mode is mono 32*/
            aoSetNR_CHANM(mmioBase, 0);
            break;
        }

        case apfStereo16:               /* Two channel Audio */
        {
            frameLength = boardAOConfig->frameLength[STEREO16];
            aoSetTRANS_MODEM(mmioBase, 3);                                     /* transfer mode is Stereo 16*/
            aoSetNR_CHANM(mmioBase, 0);
            break;
        }
        case apfStereo32:               /* Two channel Audio, 32-bit */
        {
            frameLength = boardAOConfig->frameLength[STEREO32];
            aoSetTRANS_MODEM(mmioBase, 1);                                     /* transfer mode is Stereo 32*/
            aoSetNR_CHANM(mmioBase, 0);
            break;
        }
        case apfFourCh_3_1_0_16:       /* Four channel Audio */
        case apfFourCh_2_2_0_16:       /* Four channel Audio */
        case apfFourCh_2_1_1_16:       /* Four channel Audio */
        case apfFourCh_3_0_1_16:       /* Four channel Audio */
        {
            frameLength = boardAOConfig->frameLength[STEREO16];
            aoSetTRANS_MODEM(mmioBase, 3);                                      /* transfer mode is stereo 16*/
            aoSetNR_CHANM(mmioBase, 1);                                         /* no of channels 4 ie, 2 stereo */
            break;
        }
        case apfFourCh_3_1_0_32:       /* Four channel Audio, 32-bit */
        case apfFourCh_2_2_0_32:       /* Four channel Audio, 32-bit */
        case apfFourCh_2_1_1_32:       /* Four channel Audio, 32-bit */
        case apfFourCh_3_0_1_32:       /* Four channel Audio, 32-bit */
        {
            frameLength = boardAOConfig->frameLength[STEREO32];
            aoSetTRANS_MODEM(mmioBase, 1);                                       /* transfer mode is Stereo 32*/
            aoSetNR_CHANM(mmioBase, 1);                                          /* no of channels 4 ie, 2 stereo */
            break;
        }
        case apfFiveDotOne16:  /* Six Channel Audio */
        {
            frameLength = boardAOConfig->frameLength[STEREO16];
            aoSetTRANS_MODEM(mmioBase, 3);                                       /* transfer mode is stereo 16*/
            aoSetNR_CHANM(mmioBase, 2);                                          /* no of channels 6 ie, 3 stereo */
            break;
        }
        case apfFiveDotOne32:  /* Six Channel Audio, 32-bit */
        {
            frameLength = boardAOConfig->frameLength[STEREO32];
            aoSetTRANS_MODEM(mmioBase, 1);                                       /* transfer mode is Stereo 32*/
            aoSetNR_CHANM(mmioBase, 2);                                          /* no of channels 6 ie, 3 stereo */
            break;
        }
        case apfSevenDotOne16:  /* Eight Channel Audio */
        {
            frameLength = boardAOConfig->frameLength[STEREO16];
            aoSetTRANS_MODEM(mmioBase, 3);                                       /* transfer mode is stereo 16*/
            aoSetNR_CHANM(mmioBase, 3);                                          /* no of channels 5 ie, 4 stereo */
            break;
        }
        case apfSevenDotOne32:  /* Eight Channel Audio, 32-bit */
        {
            frameLength = boardAOConfig->frameLength[STEREO32];
            aoSetTRANS_MODEM(mmioBase, 1);                                       /* transfer mode is Stereo 32*/
            aoSetNR_CHANM(mmioBase, 3);                                          /* no of channels 8 ie, 4 stereo */
            break;
        }
        default:
            /* unsupported subtype */
            return(TMDL_ERR_AO_UNSUPPORTED_FORMAT);
    }
    sckDiv      = (boardAOConfig->osclkFactor/frameLength)-1;
    rightPos    = frameLength/2;
    aoSetWSDIVM(mmioBase, (frameLength-1));
    aoSetSCKDIVM(mmioBase, sckDiv);
    aoSetLEFTPOSM(mmioBase, 0+15);                                               /* position of left channel in the word is bit 0*/
    aoSetRIGHTPOSM(mmioBase, rightPos+15);                                       /* position of Right channel in the word is bit 0*/

    if (instVars->boardAOConfig->initFunc)
    {
        if (!instVars->initialized)
        {
            err = instVars->boardAOConfig->initFunc(&(instVars->bslInstance), &param);
            if (err != TM_OK)
                goto aoInstanceSetupExit;
        }
    }

    /* clear all interrupt sources to be sure */
    MMIO(mmioBase + AO_CTL_OFFSET) |= AO_ACK_UDR | AO_ACK_HBE | AO_ACK_HBE | AO_ACK2 | AO_ACK1;


    aoSetBASE1M(mmioBase, pSetup->base1);
    aoSetBASE2M(mmioBase, pSetup->base2);

    MMIO(mmioBase + AO_CTL_OFFSET) = (MMIO(mmioBase + AO_CTL_OFFSET) &
         ~(AO_BUF1_INTEN | AO_BUF2_INTEN | AO_UDR_INTEN | AO_HBE_INTEN))
        | (pSetup->buf1emptyEnable ? AO_BUF1_INTEN : 0)
        | (pSetup->buf2emptyEnable ? AO_BUF2_INTEN : 0)
        | (pSetup->underrunEnable ? AO_UDR_INTEN : 0)
        | (pSetup->hbeEnable ? AO_HBE_INTEN : 0);

    /*Extract the current Interrupt state */
    instVars->intState = MMIO(mmioBase + AO_CTL_OFFSET) & (0xF << 4);

    if (!instVars->initialized) /* To avoid the following calls being made in ISR */
    {
        /* get osal interrupt instance */
        err = tmosalIntInstanceGetSetup (instVars->handle, &descriptor);
        if (err != TM_OK)
            goto aoInstanceSetupExit;

        if (pSetup->isr)    /* Null means poll - no ISR */
        {
            descriptor.pHandler         = (void (*)(void *))pSetup->isr;
            descriptor.pContextArgument = pSetup->pContextArgumentToIsr;
            descriptor.enabled          = True;
            descriptor.interruptible    = False;

            err = tmosalIntInstanceSetup(instVars->handle, &descriptor);
            if (err != TM_OK)
                goto aoInstanceSetupExit;
        }

        instVars->setup = *pSetup; /* Last possible error past, so copy to
                                    * static storage */
        instVars->initialized = True;

        /*Now setup the output */
        tmdlAoInstanceConfig(instance,TMBSL_CMD_AO_SET_OUTPUT,(Pointer)pSetup->output);
    }

aoInstanceSetupExit:
    //tmosalSystemMutexExit();
    return err;
}

/**************************************************************************************/
extern tmErrorCode_t tmdlAoClose(Int instance)
{
    paoInstVars_t      instVars    = (paoInstVars_t) instance;
    tmErrorCode_t      err         = TM_OK;
    UInt32             mmioBase    = instVars->boardAOConfig->mmioBase;

    DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoClose(%x)\n", instance));
    tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);

    if (instVars->magic != AO_MAGIC)
        return TMDL_ERR_AO_NOT_OWNER;

    tmosalSystemMutexEnter();

    /* set to system clock ( 27 MHz ) for soft aoRESETM() */
    aoResetClock(instVars->unitName, mmioBase ); /* to workaround hardware PR */

    /* reset aoDevice  */
    aoRESETM(mmioBase);

// Viper1/Viper2/PNX1500
#if   (TMFL_PNX_ID != 1300)
    if (instVars->gpioInstance != 0)
        err = tmdlGpioClose(instVars->gpioInstance);
#endif

    err = tmosalIntDestroy(instVars->handle);

    /* shutdown external peripheral driver */
    if (instVars->boardAOConfig->deinitFunc)
        err = instVars->boardAOConfig->deinitFunc(instVars->unitName);

    aoCaps.unitCapabilities[instVars->unitIndex].numCurrentInstances--;
    instVars->magic       = 0;
    free(instVars);

    if( --noofOpens == 0)
    {
        noofOpens   = 0;
        aoInitDone  = False;
        memset(&aoCaps, 0, sizeof(aoCapabilitiesList_t));
    }

    tmosalSystemMutexExit();
    return err;
}


/**************************************************************************************/
extern tmErrorCode_t tmdlAoStop(Int instance)
{
    paoInstVars_t   instVars = (paoInstVars_t) instance;
    tmErrorCode_t   err      = TM_OK;
    UInt32          mmioBase = instVars->boardAOConfig->mmioBase;

    DBG_ISR_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoStop(%x)\n", instance));
    tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);

    if (instVars->magic != AO_MAGIC)
        return TMDL_ERR_AO_NOT_OWNER;

    if (!instVars->initialized)
    {
        return TMDL_ERR_AO_INIT_REQUIRED;
    }

    aoDisableTRANS_ENABLEM(mmioBase);

    /* Disable clock Here */

    if (instVars->boardAOConfig->stopFunc)
    {
        err = instVars->boardAOConfig->stopFunc(instVars->unitName);
    }

    return err;
}


/**************************************************************************************/
extern tmErrorCode_t tmdlAoStart(Int instance)
{
    paoInstVars_t   instVars = (paoInstVars_t) instance;
    tmErrorCode_t   err      = TM_OK;
    UInt32          mmioBase = instVars->boardAOConfig->mmioBase;

    DBG_ISR_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoStart(%x)\n", instance));
    tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);

    if (instVars->magic != AO_MAGIC)
        return TMDL_ERR_AO_NOT_OWNER;

    if (!instVars->initialized)
    {
        return TMDL_ERR_AO_INIT_REQUIRED;
    }

    /* Enable the clock Here */

⌨️ 快捷键说明

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