📄 lh7a404_ssp_driver.c
字号:
sspcfg.init = TRUE;
/* Save and return address of peripheral block */
sspcfg.regptr = (SSP_REGS_T *) ipbase;
/* Disable SSP and set default clock to divide by 8,
Motorola SPI mode, and 16 data bits */
sspcfg.regptr->cr0 = (SSP_CR0_FRF_MOT | SSP_CR0_SCR(7) | SSP_CR0_DSS(16));
/* Set default FIFO to enabled, loopback mode disabled, all
interrupts disabled, and SPH and SPI to 0 */
sspcfg.regptr->cr1 = SSP_CR1_FEN;
/* Set SSP clock prescaler */
ssp_set_clock(sspcfg.regptr, DEFAULT_SSP_CLOCK);
/* Return pointer to RTC configuration structure */
status = (INT_32) &sspcfg;
}
return status;
}
/***********************************************************************
*
* Function: ssp_close
*
* Purpose: Close the SSP
*
* Processing:
* If init is not TRUE, then return _ERROR to the caller as the
* device was not previously opened. Otherwise, set init to FALSE,
* disable the SSP device, and return _NO_ERROR to the caller.
*
* Parameters:
* devid: Pointer to SSP config structure
*
* Outputs: None
*
* Returns: The status of the close operation
*
* Notes: None
*
**********************************************************************/
STATUS ssp_close(INT_32 devid)
{
SSP_CFG_T *sspcfgptr = (SSP_CFG_T *) devid;
STATUS status = _ERROR;
if (sspcfgptr->init == TRUE)
{
/* 'Uninitialize' device */
sspcfgptr->init = FALSE;
status = _NO_ERROR;
/* Disable device */
sspcfg.regptr->cr0 = 0x00000000;
}
return status;
}
/***********************************************************************
*
* Function: ssp_ioctl
*
* Purpose: SSP configuration block
*
* Processing:
* This function is a large case block. Based on the passed function
* and option values, set or get the appropriate SSP parameter.
*
* Parameters:
* devid: Pointer to SSP config structure
* cmd: ioctl command
* arg: ioctl argument
*
* Outputs: None
*
* Returns: The status of the ioctl operation
*
* Notes: None
*
**********************************************************************/
STATUS ssp_ioctl(INT_32 devid,
INT_32 cmd,
INT_32 arg)
{
SSP_REGS_T *sspregs;
UNS_32 tmp, tmp2;
SSP_CFG_T *sspcfgptr = (SSP_CFG_T *) devid;
STATUS status = _ERROR;
if (sspcfgptr->init == TRUE)
{
status = _NO_ERROR;
sspregs = sspcfgptr->regptr;
switch (cmd)
{
case SSP_ENABLE:
if (arg == 1)
{
/* Enable SSP */
sspregs->cr0 |= SSP_CR0_SSE;
}
else
{
/* Disable SSP */
sspregs->cr0 &= ~SSP_CR0_SSE;
}
break;
case SSP_SET_PROTOCOL:
/* Change SSP protocol state */
tmp = sspregs->cr0 & ~SSP_CR0_PRT_MSK;
switch (arg)
{
case SSP_MOTOROLA_SPI:
/* SPI mode */
sspregs->cr0 = (tmp | SSP_CR0_FRF_MOT);
break;
case SSP_TI_SSI:
/* SSI mode */
sspregs->cr0 = (tmp | SSP_CR0_FRF_TI);
break;
case SSP_MICROWIRE:
/* Microwire mode */
sspregs->cr0 = (tmp | SSP_CR0_FRF_NS);
break;
default:
/* Unsupported parameter */
status = SMA_BAD_PARAMS;
break;
}
break;
case SSP_SET_CLOCK:
/* Change SSP clock */
ssp_set_clock(sspregs, (UNS_32) arg);
break;
case SSP_SET_DATA_BITS:
/* Change number of data bits */
if ((arg >= 4) && (arg <= 16))
{
/* Good data bit size */
tmp = sspregs->cr0 & ~SSP_CR0_DSS(16);
sspregs->cr0 = (tmp | SSP_CR0_DSS(arg));
}
else
{
/* Invalid data bit size */
status = SMA_BAD_PARAMS;
}
break;
case SSP_ENABLE_FIFO:
/* Enable or disable SSP FIFO */
if (arg == 1)
{
/* Enable SSP FIFO */
sspregs->cr1 |= SSP_CR1_FEN;
}
else
{
/* Disable SSP FIFO */
sspregs->cr1 &= ~SSP_CR1_FEN;
}
break;
case SSP_ENABLE_LOOPB:
/* Enable or disable loopback mode */
if (arg == 1)
{
/* Enable SSP loopback mode */
sspregs->cr1 |= SSP_CR1_LBM;
}
else
{
/* Disable SSP loopback mode */
sspregs->cr1 &= ~SSP_CR1_LBM;
}
break;
case SSP_ENABLE_INTS:
/* Enable SSP interrupts */
/* Mask off all bits except interrupt bits */
tmp = (UNS_32) arg & (SSP_CR1_RIE | SSP_CR1_TIE |
SSP_CR1_RORIE | SSP_CR1_TXIDLE);
/* Get old control word and mask off old interrupt
bits */
tmp2 = sspregs->cr1 & ~(SSP_CR1_RIE | SSP_CR1_TIE |
SSP_CR1_RORIE | SSP_CR1_TXIDLE);
/* OR in new interrupt bits */
sspregs->cr1 = (tmp | tmp2);
break;
case SSP_DISABLE_INTS:
/* Disable SSP interrupts */
/* Mask off all bits except interrupt bits */
tmp = (UNS_32) arg & (SSP_CR1_RIE | SSP_CR1_TIE |
SSP_CR1_RORIE | SSP_CR1_TXIDLE);
/* OR in new interrupt bits */
sspregs->cr1 &= ~tmp;
break;
case SSP_CLEAR_OVR_INT:
/* Clear receive overrun bit */
sspregs->iir_icr = 0x00000000;
break;
case SSP_SET_SPI_PHASE:
/* Set the state of the SPH bit */
if (arg == 1)
{
/* Set SPH to 1 */
sspregs->cr1 |= SSP_CR1_SPH;
}
else
{
/* Set SPH to 0 */
sspregs->cr1 &= ~SSP_CR1_SPH;
}
break;
case SSP_SET_SPI_POL:
/* Set the state of the SPO bit */
if (arg == 1)
{
/* Set SPO to 1 */
sspregs->cr1 |= SSP_CR1_SPO;
}
else
{
/* Set SPO to 0 */
sspregs->cr1 &= ~SSP_CR1_SPO;
}
break;
case SSP_GET_STATUS:
/* Return an SSP status */
switch (arg)
{
case SSP_ENABLED_ST:
if ((sspregs->cr0 & SSP_CR0_SSE) != 0)
{
/* SSP is enabled */
status = 1;
}
else
{
/* SSP is disabled */
status = 0;
}
break;
case SSP_PROTOCOL_ST:
/* Return SSP protocol state */
switch (sspregs->cr0 & SSP_CR0_PRT_MSK)
{
case SSP_CR0_FRF_MOT:
/* SPI mode */
status = SSP_MOTOROLA_SPI;
break;
case SSP_CR0_FRF_TI:
/* SSI mode */
status = SSP_TI_SSI;
break;
case SSP_CR0_FRF_NS:
/* Microwire mode */
status = SSP_MICROWIRE;
break;
default:
/* Unknown mode, this should never
happen */
status = _ERROR;
break;
}
break;
case SSP_CLOCK_ST:
/* Return clock speed of SSP interface */
tmp = (sspregs->cr0 & SSP_CR0_SCR(0xFF)) >> 8;
tmp2 = sspregs->cpsr;
if (tmp2 < 1)
{
/* Not a valid value, so use a divider of 1 */
tmp2 = 1;
}
/* Compute SSP bit clock rate */
status = SSP_CLOCK / (tmp2 + tmp + 1);
break;
case SSP_DATA_BITS:
/* Returns number of data bits */
status = ((INT_32) sspregs->cr0 & 0xF) + 1;
break;
case SSP_FIFO_ENABLE_ST:
/* Return FIFO enabled status */
if ((sspregs->cr1 & SSP_CR1_FEN) != 0)
{
/* FIFO enabled */
status = 1;
}
else
{
/* FIFO disabled */
status = 0;
}
break;
case SSP_LOOPB_ST:
/* Return loopback mode enabled status */
if ((sspregs->cr1 & SSP_CR1_LBM) != 0)
{
/* Lopback mode enabled */
status = 1;
}
else
{
/* Lopback mode disabled */
status = 0;
}
break;
case SSP_INTS_ST:
/* Return enabled interrupts */
status = (INT_32) (sspregs->cr1 & (SSP_CR1_RIE |
SSP_CR1_TIE | SSP_CR1_RORIE |
SSP_CR1_TXIDLE));
break;
case SSP_SPI_PHASE_ST:
/* Returns state of SPH bit */
if ((sspregs->cr1 & SSP_CR1_SPH) != 0)
{
/* SPH is high */
status = 1;
}
else
{
/* SPH is low */
status = 0;
}
break;
case SSP_SPI_POL_ST:
/* Returns state of SPO bit */
if ((sspregs->cr1 & SSP_CR1_SPO) != 0)
{
/* SPO is high */
status = 1;
}
else
{
/* SPO is low */
status = 0;
}
break;
default:
/* Unsupported parameter */
status = SMA_BAD_PARAMS;
break;
}
break;
default:
/* Unsupported parameter */
status = SMA_BAD_PARAMS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -