📄 lh7a404_adc_driver.c
字号:
status = (INT_32) (adcregsptr->adcmis &
(ADC_FIFO_OV_IRQ | ADC_WATERM_IRQ |
ADC_EOS_IRQ |ADC_PEN_IRQ |
ADC_BROWNOUT_IRQ));
break;
case ADC_CONV_COUNT:
/* Return the number of conversions in the
conversion count sequence */
status = adccfgptr->conv_count;
break;
default:
/* Unsupported parameter */
status = SMA_BAD_PARAMS;
break;
}
break;
default:
/* Unsupported parameter */
status = SMA_BAD_PARAMS;
}
}
return status;
}
/***********************************************************************
*
* Function: adc_read_polled
*
* Purpose: Reads data directly from the ADC FIFO
*
* Processing:
* If the device is not initialized, return 0 to the caller.
* Otherwise, hile the number of bytes read is less than max_bytes
* and the ADC FIFO is not empty, read a FIFO entry from the ADC
* FIFO and place it into the passed user buffer. Increment bytes
* by 2. When the loop is exited, return the number of bytes read
* to the caller.
*
* Parameters:
* devid: Pointer to an ADC configuration structure
* buffer: Pointer to data buffer to copy to
* max_bytes: Number of bytes to read
*
* Outputs: None
*
* Returns: The number of bytes read from the FIFO
*
* Notes: None
*
**********************************************************************/
INT_32 adc_read_polled(INT_32 devid,
void *buffer,
INT_32 max_bytes)
{
ADC_CFG_T *adccfgptr = (ADC_CFG_T *) devid;
ADC_REGS_T *adcregptr = adccfgptr->regptr;
UNS_16 *adcbuf = (UNS_16 *) buffer;
INT_32 bytes = 0;
if (adccfgptr->init == TRUE)
{
/* Grab all entries or until size equals max_bytes */
while ((bytes < max_bytes) &&
((adcregptr->adcfifosts & ADC_FIFO_EMPTY) == 0))
{
*adcbuf = (UNS_16) adcregptr->adcresults;
adcbuf++;
bytes = bytes + 2;
}
}
return bytes;
}
/***********************************************************************
*
* Function: adc_read_ring
*
* Purpose: Reads data from the ADC ring buffer
*
* Processing:
* If the init flag for the ADC structure is FALSE, return 0 to
* the caller. Otherwise, save the state of the ADC interrupts and
* disable the ADC interrupts. Loop until max_bytes equals 0 or
* until the receive ring buffer is empty, whichever comes
* first. Read the data from the ring buffer indexed by the tail
* pointer and place it into the user buffer. Increment the tail
* pointer and user buffer pointer. If the tail pointer exceeds the
* buffer size, set the tail pointer to 0. Increment bytes, and
* decrement max_bytes. Exit the loop based on the loop conditions,
* re-enable the receive interrupts, and return the number of bytes
* read to the caller.
*
* Parameters:
* devid: Pointer to an ADC configuration structure
* buffer: Pointer to data buffer to copy to
* max_bytes: Number of bytes to read
*
* Outputs: None
*
* Returns: The number of bytes actually read from the ring buffer
*
* Notes: None
*
**********************************************************************/
INT_32 adc_read_ring(INT_32 devid,
void *buffer,
INT_32 max_bytes)
{
ADC_CFG_T *adccfgptr = (ADC_CFG_T *) devid;
ADC_REGS_T *adcregs;
UNS_32 tmp1;
UNS_16 *data = (UNS_16 *) buffer;
INT_32 bytes = 0;
if (adccfgptr->init == TRUE)
{
adcregs = adccfgptr->regptr;
/* Temporarily lock out ADC receive interrupt during this
read so the ADC receive interrupt won't cause problems
with the ring buffer index values */
tmp1 = adcregs->adcie & (ADC_FIFO_OV_INT | ADC_WATERM_INT |
ADC_EOS_INT | ADC_PEN_INT | ADC_GLOBAL_INT);
adcregs->adcie &= ~(ADC_FIFO_OV_INT | ADC_WATERM_INT |
ADC_EOS_INT | ADC_PEN_INT | ADC_GLOBAL_INT);
/* Loop until receive ring buffer is empty or until max_bytes
expires */
while ((max_bytes > 0) &&
(adccfgptr->rx_tail != adccfgptr->rx_head))
{
/* Read data from ring buffer into user buffer */
*data = adccfgptr->rx[adccfgptr->rx_tail];
data++;
/* Update tail pointer */
adccfgptr->rx_tail++;
/* Make sure tail didn't overflow */
if (adccfgptr->rx_tail >= ADC_RING_BUFSIZE)
{
adccfgptr->rx_tail = 0;
}
/* Increment data count and decrement buffer size count */
bytes = bytes + 2;
max_bytes = max_bytes - 2;
}
/* Re-enable ADC receive interrupt(s) */
adcregs->adcie |= tmp1;
}
return bytes;
}
/***********************************************************************
*
* Function: adc_write
*
* Purpose: ADC write function (stub only)
*
* Processing:
* Returns 0 to the caller.
*
* Parameters:
* devid: Pointer to ADC config structure
* buffer: Pointer to data buffer to copy from
* n_bytes: Number of bytes to write
*
* Outputs: None
*
* Returns: Number of bytes actually written (always 0)
*
* Notes: None
*
**********************************************************************/
INT_32 adc_write(INT_32 devid,
void *buffer,
INT_32 n_bytes)
{
return 0;
}
/***********************************************************************
*
* Function: adc_isr
*
* Purpose: ADC interrupt handler
*
* Processing:
* On an interrupt, read the (masked) interrupt status. Based on
* the status, handle the watermark or end of sequence interrupts
* by calling the adc_ring_fill() to move the data from the ADC
* FIFO to the ADC driver ring buffer. If the interrupt was due to
* an end of sequence and the end of sequence callback function
* exists, then call the user function. If the interrupt was due
* to a pendown event and the pendown callback function exists,
* then call the user function. If the interrupt was due to a
* brownout interrupt and the brownout callback function exists,
* then call the user function.
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void adc_isr(void)
{
UNS_32 int_status;
/* Read interrupt status register */
int_status = ADC->adcmis;
/* Perform function based on interrupt status */
if ((int_status & ADC_WATERM_INT) != 0)
{
/* FIFO needs servicing, called ring fill handler */
adc_ring_fill(&adccfg);
}
if ((int_status & ADC_EOS_INT) != 0)
{
/* ADC end of sequence interrupt, move data from FIFO
to ring buffer */
adc_ring_fill(&adccfg);
/* Call user function if it exists */
if (adccfg.eos_cbfunc != (PFV) 0)
{
adccfg.eos_cbfunc();
}
/* Clear end of sequence interrupt */
ADC->adcic = ADC_EOS_CLR;
}
if ((int_status & ADC_PEN_INT) != 0)
{
/* Clear end of pendown interrupt and call user function */
ADC->adcic = ADC_PEN_CLR;
/* Call user function if it exists */
if (adccfg.pd_cbfunc != (PFV) 0)
{
adccfg.pd_cbfunc();
}
}
if ((int_status & ADC_BROWNOUT_IRQ) != 0)
{
/* If the brownout interrupt callback function exists, call it */
if (adccfg.bro_cbfunc != (PFV) 0)
{
adccfg.bro_cbfunc();
}
/* Brownout interrupt, clear it */
ADC->adcic = ADC_BROWNOUT_CLR;
}
}
/***********************************************************************
*
* Function: adc_strip_data
*
* Purpose: Strip out and justify analog data from a sample
*
* Processing:
* The data that is returned from the adc_read() function returns a
* value that has data and the analog input number mixed into it.
* This function strips off the analog input number and returns only
* the converted 10-bit data value right justified into a 16-bit
* field.
*
* Parameters:
* data : The raw ADC sample to extract the data from
*
* Outputs: None
*
* Returns: The right justified analog data value
*
* Notes: None
*
**********************************************************************/
UNS_16 adc_strip_data(UNS_16 data)
{
return ADC_READ_OUTPUT(data);
}
/***********************************************************************
*
* Function: adc_strip_input
*
* Purpose: Strip out the analog input channel from a sample
*
* Processing:
* The data that is returned from the adc_read() function returns a
* value that has data and the analog input number mixed into it.
* This function strips off the converted data and returns only the
* analog input channel number.
*
* Parameters:
* data : The raw ADC sample to extract the data from
*
* Outputs: None
*
* Returns: The right justified analog data value
*
* Notes: None
*
**********************************************************************/
UNS_16 adc_strip_input(UNS_16 data)
{
return (data & ADC_CBANKTAG);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -