📄 tmssi.c
字号:
if (err != TMLIBDEV_OK)
{
gpioClose(instVars->gpioInstance);
free(instVars);
intClose(ssiBoardConfig->intNumber);
goto ssiOpenExit;
}
}
else
{
instVars->gpioInstance = 0;
}
instVars->magic = __SSI_MAGIC;
instVars->unitName = unitName;
instVars->boardSSIConfig = ssiBoardConfig;
*instance = (Int) instVars;
ssiOpenExit:
intRESTORE_IEN(ien);
return (TMLIBDEV_OK);
}
/*
* Function : ssiInstanceSetup
* Parameters : P1: Instance variable assigned at open()
* P2: Pointer to setup structure.
* Function Result : TMLIBDEV_OK on success,
* Various other errors (BAD PARAM, etc) if setup fails.
* Side Effects : ssiInstanceSetup is used to initialize the SSI
* and the devices connected to it.
* The first time it is called, it will perform an
* initialization sequence. After that, it will only
* change things without doing a reset.
* To use for reconfiguration.
* On exit, the peripheral is "stopped."
* This means that the default frame is being transmitted,
* and the fifos are being maintained at the ILS level.
*
*/
extern tmLibdevErr_t
ssiInstanceSetup(Int instance, pssiInstanceSetup_t pSetup)
{
tmLibdevErr_t err = TMLIBDEV_OK;
intInstanceSetup_t setup;
pssiInstVars_t instVars = (pssiInstVars_t)instance;
boardSSIConfig_t *boardSSIConfig = instVars->boardSSIConfig;
boardSSIParam_t param;
check(instance);
tmAssert(pSetup, TMLIBDEV_ERR_NULL_PARAMETER);
param.configBuffer = pSetup->configBuffer;
param.configBufferLength = pSetup->configBufferLength;
param.interruptLevelSelect = pSetup->interruptLevelSelect;
ssiReset();
if (boardSSIConfig->init_func) {
/* the init function must leave int15 interrupt closed! */
/*
* The init function can be used to change any other SSI
* settings
*/
err = boardSSIConfig->init_func(¶m);
if (err)
return err;
}
ssiSetFifoSignalLevelILS(pSetup->interruptLevelSelect);
instVars->ssiSetup = *pSetup; /* copy to static storage */
if (instVars->ssiSetup.isr) {
intOpen(boardSSIConfig->intNumber);
setup.enabled = True;
setup.handler = instVars->ssiSetup.isr;
setup.priority = instVars->ssiSetup.interruptPriority;
setup.level_triggered = True;
intInstanceSetup(boardSSIConfig->intNumber, &setup);
/*
* Actually enable the interrupts in ssiStart so that the
* user can fill the pipeline. Otherwise, the TX interrupt
* will always be raised after reset.
*/
}
/* leave stopped */
return (TMLIBDEV_OK);
}
/*
* Function : ssiSetFraming
* Parameters : instance: Instance variable assigned at ssiOpen()
* frame: Pointer to frame descriptor structure.
* Function Result : TMLIBDEV_OK on success,
* Under debug compiles, this function will
* assert on illegal values.
* Side Effects : ssiSetFraming is used to control the
* structure of a frame on the SSI bus.
* The FSS and VSS fields are changed.
*/
extern tmLibdevErr_t
ssiSetFraming(Int instance, pssiFrameSetup_t frame)
{
tmAssert(frame, TMLIBDEV_ERR_NULL_PARAMETER);
check(instance);
/* could assert bad values here */
ssiSetFrameSizeFSS(frame->slotsPerFrame);
ssiSetValidSlotSizeVSS(frame->validSlotsPerFrame);
return (TMLIBDEV_OK);
}
extern tmLibdevErr_t
ssiGetFraming(Int instance, pssiFrameSetup_t frame)
{
tmAssert(frame, TMLIBDEV_ERR_NULL_PARAMETER);
check(instance);
frame->slotsPerFrame = ssiGetFrameSizeFSS();
frame->validSlotsPerFrame = ssiGetValidSlotSizeVSS();
return (TMLIBDEV_OK);
}
/*
* Function : ssiClose
* Parameters : instance (I): Instance value assigned at aiOpen().
* Function Result : TMLIBDEV_OK on success,
* TMLIBDEV_ERR_NOT_OWNER if instance is not owner.
* Side Effects : The device is free and ready for re-allocation.
*/
extern tmLibdevErr_t
ssiClose(Int instance)
{
pssiInstVars_t instVars = (pssiInstVars_t)instance;
boardSSIConfig_t *boardSSIConfig = instVars->boardSSIConfig;
tmLibdevErr_t err = TMLIBDEV_OK;
check(instance);
AppModel_suspend_scheduling();
if (instVars->gpioInstance != 0)
{
gpioClose(instVars->gpioInstance);
}
/* shutdown driver */
if (boardSSIConfig->term_func) {
if (err = boardSSIConfig->term_func())
goto ssiCloseExit;
}
else
{
ssiReset();
if (boardSSIConfig->afe_Hook)
boardSSIConfig->afe_Hook(False);
else {
/* IO2 is high to go on hook */
ssiSetWIO2(1);
ssiSetModeIO2(SSI_IO2_MODE_GPO);
}
}
/* de-install interrupt handler */
if (instVars->ssiSetup.isr)
err = intClose( boardSSIConfig->intNumber );
ssiCaps.unitCapabilities[instVars->unitName].numCurrentInstances--;
instVars->magic = 0;
ssiCloseExit:
AppModel_resume_scheduling();
free(instVars);
return err;
}
/*
* Function : ssiStop
* Parameters : instance (I): instance value from ssiOpen()
* Function Result : TMLIBDEV_OK if success,
* TMLIBDEV_ERR_NOT_OWNER if instance doesn't match owner.
* Side Effects : stops the audio transmit
*/
extern tmLibdevErr_t ssiStop(Int instance)
{
check(instance);
ssiDisable(); /* stop transmitting */
return TMLIBDEV_OK;
}
/*
* Function : ssiStart
* Parameters : instance (I): instance value from ssiOpen()
* Function Result : TMLIBDEV_OK if success,
* TMLIBDEV_ERR_NOT_OWNER if instance doesn't match owner.
* Side Effects : starts the audio transmit
*/
extern tmLibdevErr_t ssiStart(Int instance)
{
pssiInstVars_t instVars = (pssiInstVars_t)instance;
check(instance);
if (!instVars->ssiSetup.isr)
return (TMLIBDEV_OK);
/* enable these here so that the user can fill the pipeline.
* Otherwise, the TX interrupt will always be raised after reset.
*/
if (instVars->ssiSetup.rxInterruptEnable)
ssiEnableRIE(); /* enable receive IRQ */
if (instVars->ssiSetup.changeDetectorInterruptEnable)
ssiEnableChangeDetectCDE(); /* enable change detect IRQ */
if (instVars->ssiSetup.txInterruptEnable)
ssiEnableTIE(); /* enable transmit IRQ */
ssiEnable(); /* start transmitting */
return TMLIBDEV_OK;
}
/**************************************************************
* ssiOffHook
* ssiOnHook
* Passes parameters to AFE library through board support package.
* Takes the phone on or off hook, if supported by AFE.
*
*/
extern tmLibdevErr_t ssiOffHook(Int instance)
{
boardSSIConfig_t *boardSSIConfig = ((pssiInstVars_t)instance)->boardSSIConfig;
check(instance);
if (boardSSIConfig->afe_Hook)
return (boardSSIConfig->afe_Hook(True));
/* IO2 is low to go off hook */
ssiSetWIO2(0);
ssiSetModeIO2(SSI_IO2_MODE_GPO);
return TMLIBDEV_OK;
}
extern tmLibdevErr_t ssiOnHook(Int instance)
{
boardSSIConfig_t *boardSSIConfig = ((pssiInstVars_t)instance)->boardSSIConfig;
check(instance);
if (boardSSIConfig->afe_Hook)
return (boardSSIConfig->afe_Hook(False));
/* IO2 is high to go on hook */
ssiSetWIO2(1);
ssiSetModeIO2(SSI_IO2_MODE_GPO);
return TMLIBDEV_OK;
}
/**************************************************************
* ssiConfigure
* Passes parameters to AFE library through board support package.
* Used for board specific configuration.
*/
extern tmLibdevErr_t ssiConfigure( Int instance, pssiInstanceSetup_t s )
{
boardSSIParam_t b;
boardSSIConfig_t *boardSSIConfig = ((pssiInstVars_t)instance)->boardSSIConfig;
check(instance);
tmAssert(s, TMLIBDEV_ERR_NULL_PARAMETER);
if (!boardSSIConfig->configure)
return BOARD_ERR_NULL_FUNCTION;
b.interruptLevelSelect = s->interruptLevelSelect;
b.configBuffer = s->configBuffer;
b.configBufferLength = s->configBufferLength;
return (boardSSIConfig->configure(&b));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -