parent
06e66cefca
commit
2cd6c30118
@ -1,51 +0,0 @@
|
||||
#ifndef _RINGCONFIG_H_
|
||||
#define _RINGCONFIG_H_
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <h>Audio Configuration
|
||||
// <o>Sampling Frequency <8000=> 8000 kHz <16000=> 16000 kHz
|
||||
// <44100=> 44100 kHz <48000=> 48000 kHz
|
||||
#ifndef AUDIO_SAMPLINGFREQUENCY
|
||||
#define AUDIO_SAMPLINGFREQUENCY 16000
|
||||
#endif
|
||||
|
||||
// <o>Number of samples <256=> 256 <512=> 512 <1024=> 1024 <2048=> 2048
|
||||
// <i> Must be consistent with the settings of the Audio source
|
||||
#ifndef AUDIO_NBSAMPLES
|
||||
#define AUDIO_NBSAMPLES 2048
|
||||
#endif
|
||||
|
||||
// <o>Number of channels <1=> Mono <2=> Stereo
|
||||
#ifndef AUDIO_NBCHANNELS
|
||||
#define AUDIO_NBCHANNELS 1U
|
||||
#endif
|
||||
|
||||
// <o>Channel encoding <2=> 16 Bits
|
||||
#ifndef AUDIO_CHANNEL_ENCODING
|
||||
#define AUDIO_CHANNEL_ENCODING 2U
|
||||
#endif
|
||||
|
||||
// <q> RX_ENABLED: Enable RX
|
||||
#define RX_ENABLED 1
|
||||
|
||||
// <q> TX_ENABLED: Enable TX
|
||||
#define TX_ENABLED 1
|
||||
|
||||
// <q> SDF_VHT_TX_RX_ORDERING: Force TX RX ordering
|
||||
#define SDF_VHT_TX_RX_ORDERING 0
|
||||
|
||||
// </h>
|
||||
|
||||
// <h>Ring Buffer Configuration
|
||||
// <o>Number of buffers <2=> 2 <4=> 4 <8=> 8 <16=> 16 <32=> 32
|
||||
#ifndef RING_NBBUFS
|
||||
#define RING_NBBUFS 4
|
||||
#endif
|
||||
// </h>
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#define RING_BUFSIZE (AUDIO_NBSAMPLES * AUDIO_NBCHANNELS * AUDIO_CHANNEL_ENCODING)
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,69 @@
|
||||
#ifndef _AUDIOCONFIG_H_
|
||||
#define _AUDIOCONFIG_H_
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <e>Audio Configuration for RX
|
||||
#ifndef AUDIO_DRV_RX_ENABLED
|
||||
#define AUDIO_DRV_RX_ENABLED 1
|
||||
#endif
|
||||
// <o>Sampling Frequency <8000=> 8000 kHz <16000=> 16000 kHz
|
||||
// <44100=> 44100 kHz <48000=> 48000 kHz
|
||||
#ifndef AUDIO_DRV_SAMPLINGFREQUENCY_RX
|
||||
#define AUDIO_DRV_SAMPLINGFREQUENCY_RX 16000
|
||||
#endif
|
||||
|
||||
// <o>Number of samples <256=> 256 <512=> 512 <1024=> 1024 <2048=> 2048
|
||||
// <i> Must be consistent with the settings of the Audio source
|
||||
#ifndef AUDIO_DRV_NBSAMPLES_RX
|
||||
#define AUDIO_DRV_NBSAMPLES_RX 2048
|
||||
#endif
|
||||
|
||||
// <o>Number of channels <1=> Mono <2=> Stereo
|
||||
#ifndef AUDIO_DRV_NBCHANNELS_RX
|
||||
#define AUDIO_DRV_NBCHANNELS_RX 1U
|
||||
#endif
|
||||
|
||||
// <o>Channel encoding <2=> 16 Bits
|
||||
#ifndef AUDIO_DRV_CHANNEL_ENCODING_RX
|
||||
#define AUDIO_DRV_CHANNEL_ENCODING_RX 2U
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
|
||||
// <e>Audio Configuration for TX
|
||||
#ifndef AUDIO_DRV_TX_ENABLED
|
||||
#define AUDIO_DRV_TX_ENABLED 1
|
||||
#endif
|
||||
// <o>Sampling Frequency <8000=> 8000 kHz <16000=> 16000 kHz
|
||||
// <44100=> 44100 kHz <48000=> 48000 kHz
|
||||
#ifndef AUDIO_DRV_SAMPLINGFREQUENCY_TX
|
||||
#define AUDIO_DRV_SAMPLINGFREQUENCY_TX 16000
|
||||
#endif
|
||||
|
||||
// <o>Number of samples <256=> 256 <512=> 512 <1024=> 1024 <2048=> 2048
|
||||
// <i> Must be consistent with the settings of the Audio source
|
||||
#ifndef AUDIO_DRV_NBSAMPLES_TX
|
||||
#define AUDIO_DRV_NBSAMPLES_TX 2048
|
||||
#endif
|
||||
|
||||
// <o>Number of channels <1=> Mono <2=> Stereo
|
||||
#ifndef AUDIO_DRV_NBCHANNELS_TX
|
||||
#define AUDIO_DRV_NBCHANNELS_TX 1U
|
||||
#endif
|
||||
|
||||
// <o>Channel encoding <2=> 16 Bits
|
||||
#ifndef AUDIO_DRV_CHANNEL_ENCODING_TX
|
||||
#define AUDIO_DRV_CHANNEL_ENCODING_TX 2U
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
|
||||
// <q> SDF_VHT_TX_RX_ORDERING: Force TX RX ordering
|
||||
#define SDF_VHT_TX_RX_ORDERING 0
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#define SDF_AUDIO_CONFIG
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,26 @@
|
||||
#ifndef _RINGCONFIG_H_
|
||||
#define _RINGCONFIG_H_
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
|
||||
// <h>Ring Buffer Configuration
|
||||
// <o>Number of buffers <2=> 2 <4=> 4 <8=> 8 <16=> 16 <32=> 32
|
||||
#ifndef RING_NBBUFS
|
||||
#define RING_NBBUFS 4
|
||||
#endif
|
||||
// </h>
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#if defined(SDF_AUDIO_CONFIG)
|
||||
#define RING_BUFSIZE_RX (AUDIO_DRV_NBSAMPLES_RX * AUDIO_DRV_NBCHANNELS_RX * AUDIO_DRV_CHANNEL_ENCODING_RX)
|
||||
#define RING_BUFSIZE_TX (AUDIO_DRV_NBSAMPLES_TX * AUDIO_DRV_NBCHANNELS_TX * AUDIO_DRV_CHANNEL_ENCODING_TX)
|
||||
#endif
|
||||
|
||||
#if defined(SDF_VIDEO_CONFIG)
|
||||
#define RING_BUFSIZE_RX (VIDEO_DRV_WIDTH * VIDEO_DRV_HEIGHT * VIDEO_DRV_PIXEL_SIZE)
|
||||
#define RING_BUFSIZE_TX 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,35 @@
|
||||
#ifndef _VIDEOCONFIG_H_
|
||||
#define _VIDEOCONFIG_H_
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <h>Video Configuration
|
||||
// <o>Width in pixels <16-640>
|
||||
#ifndef VIDEO_DRV_WIDTH
|
||||
#define VIDEO_DRV_WIDTH 32
|
||||
#endif
|
||||
|
||||
// <o>Height in pixels <16-640>
|
||||
#ifndef VIDEO_DRV_HEIGHT
|
||||
#define VIDEO_DRV_HEIGHT 32
|
||||
#endif
|
||||
|
||||
// <o>Pixel size in bytes <1=> 1 <2=> 2
|
||||
#ifndef VIDEO_DRV_PIXEL_SIZE
|
||||
#define VIDEO_DRV_PIXEL_SIZE 1
|
||||
#endif
|
||||
|
||||
// <o>Frame rate <10=> 10 <25=> 25 <30=> 30 <60=> 60
|
||||
#ifndef VIDEO_DRV_FRAME_RATE
|
||||
#define VIDEO_DRV_FRAME_RATE 10
|
||||
#endif
|
||||
|
||||
// </h>
|
||||
|
||||
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#define SDF_VIDEO_CONFIG
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Arm Limited. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "audio_drv.h"
|
||||
#include "arm_vsi.h"
|
||||
#ifdef _RTE_
|
||||
#include "RTE_Components.h"
|
||||
#endif
|
||||
#include CMSIS_device_header
|
||||
|
||||
/* Audio Peripheral definitions */
|
||||
#define AudioO ARM_VSI1 /* Audio Output access struct */
|
||||
#define AudioO_IRQn ARM_VSI1_IRQn /* Audio Output Interrupt number */
|
||||
#define AudioO_Handler ARM_VSI1_Handler /* Audio Output Interrupt handler */
|
||||
#define AudioI ARM_VSI0 /* Audio Input access struct */
|
||||
#define AudioI_IRQn ARM_VSI0_IRQn /* Audio Input Interrupt number */
|
||||
#define AudioI_Handler ARM_VSI0_Handler /* Audio Input Interrupt handler */
|
||||
|
||||
/* Audio Peripheral registers */
|
||||
#define CONTROL Regs[0] /* Control receiver */
|
||||
#define CHANNELS Regs[1] /* Number of channels */
|
||||
#define SAMPLE_BITS Regs[2] /* Sample number of bits (8..32) */
|
||||
#define SAMPLE_RATE Regs[3] /* Sample rate (samples per second) */
|
||||
#define STOP_SIMULATION Regs[4] /* Stop audio simulation */
|
||||
|
||||
/* Audio Control register definitions */
|
||||
#define CONTROL_ENABLE_Pos 0U /* CONTROL: ENABLE Position */
|
||||
#define CONTROL_ENABLE_Msk (1UL << CONTROL_ENABLE_Pos) /* CONTROL: ENABLE Mask */
|
||||
|
||||
/* Driver State */
|
||||
static uint8_t Initialized = 0U;
|
||||
|
||||
/* Event Callback */
|
||||
static AudioDrv_Event_t CB_Event = NULL;
|
||||
|
||||
/* Audio Output Interrupt Handler */
|
||||
void AudioO_Handler (void) {
|
||||
|
||||
AudioO->IRQ.Clear = 0x00000001U;
|
||||
__DSB();
|
||||
__ISB();
|
||||
if (CB_Event != NULL) {
|
||||
CB_Event(AUDIO_DRV_EVENT_TX_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
/* Audio Input Interrupt Handler */
|
||||
void AudioI_Handler (void) {
|
||||
|
||||
AudioI->IRQ.Clear = 0x00000001U;
|
||||
__DSB();
|
||||
__ISB();
|
||||
if (CB_Event != NULL) {
|
||||
CB_Event(AUDIO_DRV_EVENT_RX_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize Audio Interface */
|
||||
int32_t AudioDrv_Initialize (AudioDrv_Event_t cb_event) {
|
||||
|
||||
CB_Event = cb_event;
|
||||
|
||||
/* Initialize Audio Output peripheral */
|
||||
AudioO->Timer.Control = 0U;
|
||||
AudioO->DMA.Control = 0U;
|
||||
AudioO->IRQ.Clear = 0x00000001U;
|
||||
AudioO->IRQ.Enable = 0x00000001U;
|
||||
AudioO->CONTROL = 0U;
|
||||
|
||||
/* Initialize Audio Input peripheral */
|
||||
AudioI->Timer.Control = 0U;
|
||||
AudioI->DMA.Control = 0U;
|
||||
AudioI->IRQ.Clear = 0x00000001U;
|
||||
AudioI->IRQ.Enable = 0x00000001U;
|
||||
AudioI->CONTROL = 0U;
|
||||
|
||||
/* Enable peripheral interrupts */
|
||||
//NVIC_EnableIRQ(AudioO_IRQn);
|
||||
NVIC->ISER[(((uint32_t)AudioO_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)AudioO_IRQn) & 0x1FUL));
|
||||
//NVIC_EnableIRQ(AudioI_IRQn);
|
||||
NVIC->ISER[(((uint32_t)AudioI_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)AudioI_IRQn) & 0x1FUL));
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
Initialized = 1U;
|
||||
|
||||
return AUDIO_DRV_OK;
|
||||
}
|
||||
|
||||
/* De-initialize Audio Interface */
|
||||
int32_t AudioDrv_Uninitialize (void) {
|
||||
|
||||
/* Disable peripheral interrupts */
|
||||
//NVIC_DisableIRQ(AudioO_IRQn);
|
||||
NVIC->ICER[(((uint32_t)AudioO_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)AudioO_IRQn) & 0x1FUL));
|
||||
//NVIC_DisableIRQ(AudioI_IRQn);
|
||||
NVIC->ICER[(((uint32_t)AudioI_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)AudioI_IRQn) & 0x1FUL));
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
/* De-initialize Audio Output peripheral */
|
||||
AudioO->Timer.Control = 0U;
|
||||
AudioO->DMA.Control = 0U;
|
||||
AudioO->IRQ.Clear = 0x00000001U;
|
||||
AudioO->IRQ.Enable = 0x00000000U;
|
||||
AudioO->CONTROL = 0U;
|
||||
|
||||
/* De-initialize Audio Input peripheral */
|
||||
AudioI->Timer.Control = 0U;
|
||||
AudioI->DMA.Control = 0U;
|
||||
AudioI->IRQ.Clear = 0x00000001U;
|
||||
AudioI->IRQ.Enable = 0x00000000U;
|
||||
AudioI->CONTROL = 0U;
|
||||
|
||||
Initialized = 0U;
|
||||
|
||||
return AUDIO_DRV_OK;
|
||||
}
|
||||
|
||||
/* Configure Audio Interface */
|
||||
int32_t AudioDrv_Configure (uint32_t interface, uint32_t channels, uint32_t sample_bits, uint32_t sample_rate) {
|
||||
uint32_t format;
|
||||
|
||||
if (Initialized == 0U) {
|
||||
return AUDIO_DRV_ERROR;
|
||||
}
|
||||
|
||||
if ((channels < 1U) ||
|
||||
(channels > 32U) ||
|
||||
(sample_bits < 8U) ||
|
||||
(sample_bits > 32U) ||
|
||||
(sample_rate == 0U)) {
|
||||
return AUDIO_DRV_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
switch (interface) {
|
||||
case AUDIO_DRV_INTERFACE_TX:
|
||||
if ((AudioO->CONTROL & CONTROL_ENABLE_Msk) != 0U) {
|
||||
return AUDIO_DRV_ERROR;
|
||||
}
|
||||
AudioO->CHANNELS = channels;
|
||||
AudioO->SAMPLE_BITS = sample_bits;
|
||||
AudioO->SAMPLE_RATE = sample_rate;
|
||||
break;
|
||||
case AUDIO_DRV_INTERFACE_RX:
|
||||
if ((AudioI->CONTROL & CONTROL_ENABLE_Msk) != 0U) {
|
||||
return AUDIO_DRV_ERROR;
|
||||
}
|
||||
AudioI->CHANNELS = channels;
|
||||
AudioI->SAMPLE_BITS = sample_bits;
|
||||
AudioI->SAMPLE_RATE = sample_rate;
|
||||
break;
|
||||
default:
|
||||
return AUDIO_DRV_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
return AUDIO_DRV_OK;
|
||||
}
|
||||
|
||||
/* Set Audio Interface buffer */
|
||||
int32_t AudioDrv_SetBuf (uint32_t interface, void *buf, uint32_t block_num, uint32_t block_size) {
|
||||
|
||||
if (Initialized == 0U) {
|
||||
return AUDIO_DRV_ERROR;
|
||||
}
|
||||
|
||||
switch (interface) {
|
||||
case AUDIO_DRV_INTERFACE_TX:
|
||||
if ((AudioO->DMA.Control & ARM_VSI_DMA_Enable_Msk) != 0U) {
|
||||
return AUDIO_DRV_ERROR;
|
||||
}
|
||||
AudioO->DMA.Address = (uint32_t)buf;
|
||||
AudioO->DMA.BlockNum = block_num;
|
||||
AudioO->DMA.BlockSize = block_size;
|
||||
break;
|
||||
case AUDIO_DRV_INTERFACE_RX:
|
||||
if ((AudioI->DMA.Control & ARM_VSI_DMA_Enable_Msk) != 0U) {
|
||||
return AUDIO_DRV_ERROR;
|
||||
}
|
||||
AudioI->DMA.Address = (uint32_t)buf;
|
||||
AudioI->DMA.BlockNum = block_num;
|
||||
AudioI->DMA.BlockSize = block_size;
|
||||
break;
|
||||
default:
|
||||
return AUDIO_DRV_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
return AUDIO_DRV_OK;
|
||||
}
|
||||
|
||||
/* Control Audio Interface */
|
||||
int32_t AudioDrv_Control (uint32_t control) {
|
||||
uint32_t sample_size;
|
||||
uint32_t sample_rate;
|
||||
uint32_t block_size;
|
||||
|
||||
if (Initialized == 0U) {
|
||||
return AUDIO_DRV_ERROR;
|
||||
}
|
||||
|
||||
if ((control & AUDIO_DRV_CONTROL_TX_DISABLE) != 0U) {
|
||||
AudioO->Timer.Control = 0U;
|
||||
AudioO->DMA.Control = 0U;
|
||||
AudioO->CONTROL = 0U;
|
||||
} else if ((control & AUDIO_DRV_CONTROL_TX_ENABLE) != 0U) {
|
||||
AudioO->CONTROL = CONTROL_ENABLE_Msk;
|
||||
AudioO->DMA.Control = ARM_VSI_DMA_Direction_M2P |
|
||||
ARM_VSI_DMA_Enable_Msk;
|
||||
sample_size = AudioO->CHANNELS * ((AudioO->SAMPLE_BITS + 7U) / 8U);
|
||||
sample_rate = AudioO->SAMPLE_RATE;
|
||||
if ((sample_size == 0U) || (sample_rate == 0U)) {
|
||||
AudioO->Timer.Interval = 0xFFFFFFFFU;
|
||||
} else {
|
||||
block_size = AudioO->DMA.BlockSize;
|
||||
AudioO->Timer.Interval = (1000000U * (block_size / sample_size)) / sample_rate;
|
||||
}
|
||||
AudioO->Timer.Control = ARM_VSI_Timer_Trig_DMA_Msk |
|
||||
ARM_VSI_Timer_Trig_IRQ_Msk |
|
||||
ARM_VSI_Timer_Periodic_Msk |
|
||||
ARM_VSI_Timer_Run_Msk;
|
||||
}
|
||||
|
||||
if ((control & AUDIO_DRV_CONTROL_RX_DISABLE) != 0U) {
|
||||
AudioI->Timer.Control = 0U;
|
||||
AudioI->DMA.Control = 0U;
|
||||
AudioI->CONTROL = 0U;
|
||||
} else if ((control & AUDIO_DRV_CONTROL_RX_ENABLE) != 0U) {
|
||||
AudioI->CONTROL = CONTROL_ENABLE_Msk;
|
||||
AudioI->DMA.Control = ARM_VSI_DMA_Direction_P2M |
|
||||
ARM_VSI_DMA_Enable_Msk;
|
||||
sample_size = AudioI->CHANNELS * ((AudioI->SAMPLE_BITS + 7U) / 8U);
|
||||
sample_rate = AudioI->SAMPLE_RATE;
|
||||
if ((sample_size == 0U) || (sample_rate == 0U)) {
|
||||
AudioI->Timer.Interval = 0xFFFFFFFFU;
|
||||
} else {
|
||||
block_size = AudioI->DMA.BlockSize;
|
||||
AudioI->Timer.Interval = (1000000U * (block_size / sample_size)) / sample_rate;
|
||||
}
|
||||
AudioI->Timer.Control = ARM_VSI_Timer_Trig_DMA_Msk |
|
||||
ARM_VSI_Timer_Trig_IRQ_Msk |
|
||||
ARM_VSI_Timer_Periodic_Msk |
|
||||
ARM_VSI_Timer_Run_Msk;
|
||||
}
|
||||
|
||||
return AUDIO_DRV_OK;
|
||||
}
|
||||
|
||||
/* Get transmitted block count */
|
||||
uint32_t AudioDrv_GetTxCount (void) {
|
||||
return (AudioO->Timer.Count);
|
||||
}
|
||||
|
||||
/* Get received block count */
|
||||
uint32_t AudioDrv_GetRxCount (void) {
|
||||
return (AudioI->Timer.Count);
|
||||
}
|
||||
|
||||
/* Get Audio Interface status */
|
||||
AudioDrv_Status_t AudioDrv_GetStatus (void) {
|
||||
AudioDrv_Status_t status;
|
||||
uint32_t sr;
|
||||
|
||||
if ((AudioO->CONTROL & CONTROL_ENABLE_Msk) != 0U) {
|
||||
status.tx_active = 1U;
|
||||
} else {
|
||||
status.tx_active = 0U;
|
||||
}
|
||||
|
||||
if ((AudioI->CONTROL & CONTROL_ENABLE_Msk) != 0U) {
|
||||
status.rx_active = 1U;
|
||||
} else {
|
||||
status.rx_active = 0U;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
void AudioDrv_Stop (void)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = AudioDrv_Control(AUDIO_DRV_CONTROL_TX_DISABLE);
|
||||
ret = AudioDrv_Control(AUDIO_DRV_CONTROL_RX_DISABLE);
|
||||
|
||||
AudioO->STOP_SIMULATION=1;
|
||||
AudioI->STOP_SIMULATION=1;
|
||||
|
||||
}
|
||||
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Arm Limited. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __AUDIO_DRV_H
|
||||
#define __AUDIO_DRV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Audio Interface */
|
||||
#define AUDIO_DRV_INTERFACE_TX (1U) ///< Transmitter
|
||||
#define AUDIO_DRV_INTERFACE_RX (2U) ///< Receiver
|
||||
|
||||
/* Audio Control */
|
||||
#define AUDIO_DRV_CONTROL_TX_ENABLE (1UL << 0) ///< Enable Transmitter
|
||||
#define AUDIO_DRV_CONTROL_RX_ENABLE (1UL << 1) ///< Enable Receiver
|
||||
#define AUDIO_DRV_CONTROL_TX_DISABLE (1UL << 2) ///< Disable Transmitter
|
||||
#define AUDIO_DRV_CONTROL_RX_DISABLE (1UL << 3) ///< Disable Receiver
|
||||
|
||||
/* Audio Event */
|
||||
#define AUDIO_DRV_EVENT_TX_DATA (1UL << 0) ///< Data block transmitted
|
||||
#define AUDIO_DRV_EVENT_RX_DATA (1UL << 1) ///< Data block received
|
||||
|
||||
/* Return code */
|
||||
#define AUDIO_DRV_OK (0) ///< Operation succeeded
|
||||
#define AUDIO_DRV_ERROR (-1) ///< Unspecified error
|
||||
#define AUDIO_DRV_ERROR_BUSY (-2) ///< Driver is busy
|
||||
#define AUDIO_DRV_ERROR_TIMEOUT (-3) ///< Timeout occurred
|
||||
#define AUDIO_DRV_ERROR_UNSUPPORTED (-4) ///< Operation not supported
|
||||
#define AUDIO_DRV_ERROR_PARAMETER (-5) ///< Parameter error
|
||||
|
||||
/**
|
||||
\brief Audio Status
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t tx_active : 1; ///< Transmitter active
|
||||
uint32_t rx_active : 1; ///< Receiver active
|
||||
uint32_t reserved : 30;
|
||||
} AudioDrv_Status_t;
|
||||
|
||||
/**
|
||||
\fn AudioDrv_Event_t
|
||||
\brief Audio Events callback function type: void (*AudioDrv_Event_t) (uint32_t event
|
||||
\param[in] event events notification mask
|
||||
\return none
|
||||
*/
|
||||
typedef void (*AudioDrv_Event_t) (uint32_t event);
|
||||
|
||||
uint8_t* AudioRXBuffer();
|
||||
uint8_t* AudioTXBuffer();
|
||||
extern int32_t AudioDrv_Setup(void);
|
||||
|
||||
/**
|
||||
\fn int32_t AudioDrv_Initialize (AudioDrv_Event_t cb_event)
|
||||
\brief Initialize Audio Interface.
|
||||
\param[in] cb_event pointer to \ref AudioDrv_Event_t
|
||||
\return return code
|
||||
*/
|
||||
int32_t AudioDrv_Initialize (AudioDrv_Event_t cb_event);
|
||||
|
||||
/**
|
||||
\fn void AudioDrv_Stop (void);
|
||||
\brief Stop audio simulation.
|
||||
\return return code
|
||||
*/
|
||||
void AudioDrv_Stop (void);
|
||||
|
||||
/**
|
||||
\fn int32_t AudioDrv_Uninitialize (void)
|
||||
\brief De-initialize Audio Interface.
|
||||
\return return code
|
||||
*/
|
||||
int32_t AudioDrv_Uninitialize (void);
|
||||
|
||||
/**
|
||||
\fn int32_t AudioDrv_Configure (uint32_t interface, uint32_t channels, uint32_t sample_bits, uint32_t sample_rate)
|
||||
\brief Configure Audio Interface.
|
||||
\param[in] interface audio interface
|
||||
\param[in] channels number of channels
|
||||
\param[in] sample_bits sample number of bits (8..32)
|
||||
\param[in] sample_rate sample rate (samples per second)
|
||||
\return return code
|
||||
*/
|
||||
int32_t AudioDrv_Configure (uint32_t interface, uint32_t channels, uint32_t sample_bits, uint32_t sample_rate);
|
||||
|
||||
/**
|
||||
\fn int32_t AudioDrv_SetBuf (uint32_t interface, void *buf, uint32_t block_num, uint32_t block_size)
|
||||
\brief Set Audio Interface buffer.
|
||||
\param[in] interface audio interface
|
||||
\param[in] buf pointer to buffer for audio data
|
||||
\param[in] block_num number of blocks in buffer (must be 2^n)
|
||||
\param[in] block_size block size in number of samples
|
||||
\return return code
|
||||
*/
|
||||
int32_t AudioDrv_SetBuf (uint32_t interface, void *buf, uint32_t block_num, uint32_t block_size);
|
||||
|
||||
/**
|
||||
\fn int32_t AudioDrv_Control (uint32_t control)
|
||||
\brief Control Audio Interface.
|
||||
\param[in] control operation
|
||||
\return return code
|
||||
*/
|
||||
int32_t AudioDrv_Control (uint32_t control);
|
||||
|
||||
/**
|
||||
\fn uint32_t AudioDrv_GetTxCount (void)
|
||||
\brief Get transmitted block count.
|
||||
\return number of transmitted blocks
|
||||
*/
|
||||
uint32_t AudioDrv_GetTxCount (void);
|
||||
|
||||
/**
|
||||
\fn uint32_t AudioDrv_GetRxCount (void)
|
||||
\brief Get received block count.
|
||||
\return number of received blocks
|
||||
*/
|
||||
uint32_t AudioDrv_GetRxCount (void);
|
||||
|
||||
/**
|
||||
\fn AudioDrv_Status_t AudioDrv_GetStatus (void)
|
||||
\brief Get Audio Interface status.
|
||||
\return \ref AudioDrv_Status_t
|
||||
*/
|
||||
AudioDrv_Status_t AudioDrv_GetStatus (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __AUDIO_DRV_H */
|
||||
@ -0,0 +1,101 @@
|
||||
#include <stddef.h>
|
||||
#include "video_drv.h"
|
||||
#include "arm_vsi.h"
|
||||
#ifdef _RTE_
|
||||
#include "RTE_Components.h"
|
||||
#endif
|
||||
#include CMSIS_device_header
|
||||
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
|
||||
|
||||
#include "RingBuffer.h"
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
#include "SchedEvents.h"
|
||||
#include "VideoConfig.h"
|
||||
#include "RingConfig.h"
|
||||
|
||||
#include "RingInit.h"
|
||||
|
||||
extern osThreadId_t gStreamingThreadID;
|
||||
|
||||
// Number of bytes read by DMA
|
||||
#define VIDEO_BLOCK_SIZE RING_BUFSIZE_RX
|
||||
|
||||
// Number of DMA blocks
|
||||
#define VIDEO_DMA_NB_BLOCKS RING_NBBUFS
|
||||
|
||||
|
||||
extern int32_t VideoDrv_Setup(void);
|
||||
|
||||
|
||||
extern ring_config_t ringConfigRX;
|
||||
|
||||
#ifdef __FVP_PY
|
||||
__attribute__((section(".ARM.__at_0x90000000")))
|
||||
#endif
|
||||
__ALIGNED(16) static uint8_t video_bufferRX[VIDEO_DMA_NB_BLOCKS*VIDEO_BLOCK_SIZE];
|
||||
static uint8_t *reservedBufRX=NULL;
|
||||
|
||||
|
||||
uint8_t* VideoRXBuffer()
|
||||
{
|
||||
return(video_bufferRX);
|
||||
}
|
||||
|
||||
|
||||
static void VideoEvent (uint32_t event) {
|
||||
|
||||
if (event & VIDEO_DRV_EVENT_RX_DATA)
|
||||
{
|
||||
|
||||
|
||||
ringInterruptReleaseBuffer(&ringConfigRX,(void *)gStreamingThreadID);
|
||||
int reservedRX=ringInterruptReserveBuffer(&ringConfigRX);
|
||||
reservedBufRX=ringGetBufferAddress(&ringConfigRX,reservedRX);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int32_t VideoDrv_Setup(void) {
|
||||
int32_t ret;
|
||||
|
||||
ret = VideoDrv_Initialize(VideoEvent);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ret = VideoDrv_Configure(VIDEO_DRV_INTERFACE_RX,
|
||||
8U * VIDEO_DRV_PIXEL_SIZE, /* 16 sample bits */
|
||||
static_cast<uint32_t>(VIDEO_DRV_FRAME_RATE*VIDEO_DRV_WIDTH*VIDEO_DRV_HEIGHT));
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Work because user process not started yet
|
||||
*/
|
||||
|
||||
int reservedRX=ringInterruptReserveBuffer(&ringConfigRX);
|
||||
reservedBufRX=ringGetBufferAddress(&ringConfigRX,reservedRX);
|
||||
|
||||
|
||||
ret = VideoDrv_SetBuf(VIDEO_DRV_INTERFACE_RX,
|
||||
video_bufferRX, VIDEO_DMA_NB_BLOCKS,VIDEO_BLOCK_SIZE);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = VideoDrv_Control(VIDEO_DRV_CONTROL_RX_ENABLE);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Arm Limited. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "video_drv.h"
|
||||
#include "arm_vsi.h"
|
||||
#ifdef _RTE_
|
||||
#include "RTE_Components.h"
|
||||
#endif
|
||||
#include CMSIS_device_header
|
||||
|
||||
/* Video Peripheral definitions */
|
||||
#define VideoO ARM_VSI1 /* Video Output access struct */
|
||||
#define VideoO_IRQn ARM_VSI1_IRQn /* Video Output Interrupt number */
|
||||
#define VideoO_Handler ARM_VSI1_Handler /* Video Output Interrupt handler */
|
||||
#define VideoI ARM_VSI0 /* Video Input access struct */
|
||||
#define VideoI_IRQn ARM_VSI0_IRQn /* Video Input Interrupt number */
|
||||
#define VideoI_Handler ARM_VSI0_Handler /* Video Input Interrupt handler */
|
||||
|
||||
/* Video Peripheral registers */
|
||||
#define CONTROL Regs[0] /* Control receiver */
|
||||
#define SAMPLE_BITS Regs[1] /* Sample number of bits (8..32) */
|
||||
#define SAMPLE_RATE Regs[2] /* Sample rate (frame per second) */
|
||||
#define STOP_SIMULATION Regs[4] /* Stop audio simulation */
|
||||
|
||||
/* Video Control register definitions */
|
||||
#define CONTROL_ENABLE_Pos 0U /* CONTROL: ENABLE Position */
|
||||
#define CONTROL_ENABLE_Msk (1UL << CONTROL_ENABLE_Pos) /* CONTROL: ENABLE Mask */
|
||||
|
||||
/* Driver State */
|
||||
static uint8_t Initialized = 0U;
|
||||
|
||||
/* Event Callback */
|
||||
static VideoDrv_Event_t CB_Event = NULL;
|
||||
|
||||
|
||||
/* Video Input Interrupt Handler */
|
||||
void VideoI_Handler (void) {
|
||||
|
||||
VideoI->IRQ.Clear = 0x00000001U;
|
||||
__DSB();
|
||||
__ISB();
|
||||
if (CB_Event != NULL) {
|
||||
CB_Event(VIDEO_DRV_EVENT_RX_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VideoO_Handler (void) {
|
||||
|
||||
VideoO->IRQ.Clear = 0x00000001U;
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
|
||||
|
||||
/* Initialize Video Interface */
|
||||
int32_t VideoDrv_Initialize (VideoDrv_Event_t cb_event) {
|
||||
|
||||
CB_Event = cb_event;
|
||||
|
||||
/* Initialize Video Output peripheral */
|
||||
VideoO->Timer.Control = 0U;
|
||||
VideoO->DMA.Control = 0U;
|
||||
VideoO->IRQ.Clear = 0x00000001U;
|
||||
VideoO->IRQ.Enable = 0x00000001U;
|
||||
VideoO->CONTROL = 0U;
|
||||
|
||||
/* Initialize Video Input peripheral */
|
||||
VideoI->Timer.Control = 0U;
|
||||
VideoI->DMA.Control = 0U;
|
||||
VideoI->IRQ.Clear = 0x00000001U;
|
||||
VideoI->IRQ.Enable = 0x00000001U;
|
||||
VideoI->CONTROL = 0U;
|
||||
|
||||
/* Enable peripheral interrupts */
|
||||
NVIC->ISER[(((uint32_t)VideoI_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoI_IRQn) & 0x1FUL));
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
Initialized = 1U;
|
||||
|
||||
return VIDEO_DRV_OK;
|
||||
}
|
||||
|
||||
/* De-initialize Video Interface */
|
||||
int32_t VideoDrv_Uninitialize (void) {
|
||||
|
||||
/* Disable peripheral interrupts */
|
||||
NVIC->ICER[(((uint32_t)VideoI_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoI_IRQn) & 0x1FUL));
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
/* De-initialize Video Output peripheral */
|
||||
VideoO->Timer.Control = 0U;
|
||||
VideoO->DMA.Control = 0U;
|
||||
VideoO->IRQ.Clear = 0x00000001U;
|
||||
VideoO->IRQ.Enable = 0x00000000U;
|
||||
VideoO->CONTROL = 0U;
|
||||
|
||||
/* De-initialize Video Input peripheral */
|
||||
VideoI->Timer.Control = 0U;
|
||||
VideoI->DMA.Control = 0U;
|
||||
VideoI->IRQ.Clear = 0x00000001U;
|
||||
VideoI->IRQ.Enable = 0x00000000U;
|
||||
VideoI->CONTROL = 0U;
|
||||
|
||||
Initialized = 0U;
|
||||
|
||||
return VIDEO_DRV_OK;
|
||||
}
|
||||
|
||||
/* Configure Video Interface */
|
||||
int32_t VideoDrv_Configure (uint32_t interface, uint32_t pixel_size, uint32_t samplerate) {
|
||||
uint32_t format;
|
||||
|
||||
if (Initialized == 0U) {
|
||||
return VIDEO_DRV_ERROR;
|
||||
}
|
||||
|
||||
if ((pixel_size < 8*1U) ||
|
||||
(pixel_size > 8*2U)) {
|
||||
return VIDEO_DRV_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
switch (interface) {
|
||||
case VIDEO_DRV_INTERFACE_RX:
|
||||
if ((VideoI->CONTROL & CONTROL_ENABLE_Msk) != 0U) {
|
||||
return VIDEO_DRV_ERROR;
|
||||
}
|
||||
VideoI->SAMPLE_BITS = pixel_size;
|
||||
VideoI->SAMPLE_RATE = samplerate;
|
||||
break;
|
||||
default:
|
||||
return VIDEO_DRV_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
return VIDEO_DRV_OK;
|
||||
}
|
||||
|
||||
/* Set Video Interface buffer */
|
||||
int32_t VideoDrv_SetBuf (uint32_t interface, void *buf, uint32_t block_num, uint32_t block_size) {
|
||||
|
||||
if (Initialized == 0U) {
|
||||
return VIDEO_DRV_ERROR;
|
||||
}
|
||||
|
||||
switch (interface) {
|
||||
case VIDEO_DRV_INTERFACE_RX:
|
||||
if ((VideoI->DMA.Control & ARM_VSI_DMA_Enable_Msk) != 0U) {
|
||||
return VIDEO_DRV_ERROR;
|
||||
}
|
||||
VideoI->DMA.Address = (uint32_t)buf;
|
||||
VideoI->DMA.BlockNum = block_num;
|
||||
VideoI->DMA.BlockSize = block_size;
|
||||
break;
|
||||
default:
|
||||
return VIDEO_DRV_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
return VIDEO_DRV_OK;
|
||||
}
|
||||
|
||||
/* Control Video Interface */
|
||||
int32_t VideoDrv_Control (uint32_t control) {
|
||||
uint32_t sample_size;
|
||||
uint32_t sample_rate;
|
||||
uint32_t block_size;
|
||||
|
||||
if (Initialized == 0U) {
|
||||
return VIDEO_DRV_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((control & VIDEO_DRV_CONTROL_RX_DISABLE) != 0U) {
|
||||
VideoI->Timer.Control = 0U;
|
||||
VideoI->DMA.Control = 0U;
|
||||
VideoI->CONTROL = 0U;
|
||||
} else if ((control & VIDEO_DRV_CONTROL_RX_ENABLE) != 0U) {
|
||||
VideoI->CONTROL = CONTROL_ENABLE_Msk;
|
||||
VideoI->DMA.Control = ARM_VSI_DMA_Direction_P2M |
|
||||
ARM_VSI_DMA_Enable_Msk;
|
||||
sample_size = ((VideoI->SAMPLE_BITS + 7U) / 8U);
|
||||
sample_rate = VideoI->SAMPLE_RATE;
|
||||
if ((sample_size == 0U) || (sample_rate == 0U)) {
|
||||
VideoI->Timer.Interval = 0xFFFFFFFFU;
|
||||
} else {
|
||||
block_size = VideoI->DMA.BlockSize;
|
||||
VideoI->Timer.Interval = (1000000U * (block_size / sample_size)) / sample_rate;
|
||||
}
|
||||
VideoI->Timer.Control = ARM_VSI_Timer_Trig_DMA_Msk |
|
||||
ARM_VSI_Timer_Trig_IRQ_Msk |
|
||||
ARM_VSI_Timer_Periodic_Msk |
|
||||
ARM_VSI_Timer_Run_Msk;
|
||||
}
|
||||
|
||||
return VIDEO_DRV_OK;
|
||||
}
|
||||
|
||||
/* Get received block count */
|
||||
uint32_t VideoDrv_GetRxCount (void) {
|
||||
return (VideoI->Timer.Count);
|
||||
}
|
||||
|
||||
/* Get Video Interface status */
|
||||
VideoDrv_Status_t VideoDrv_GetStatus (void) {
|
||||
VideoDrv_Status_t status;
|
||||
uint32_t sr;
|
||||
|
||||
|
||||
if ((VideoI->CONTROL & CONTROL_ENABLE_Msk) != 0U) {
|
||||
status.rx_active = 1U;
|
||||
} else {
|
||||
status.rx_active = 0U;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
void VideoDrv_Stop (void)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = VideoDrv_Control(VIDEO_DRV_CONTROL_RX_DISABLE);
|
||||
|
||||
VideoI->STOP_SIMULATION=1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Arm Limited. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __VIDEO_DRV_H
|
||||
#define __VIDEO_DRV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Video Interface */
|
||||
#define VIDEO_DRV_INTERFACE_RX (2U) ///< Receiver
|
||||
|
||||
/* Video Control */
|
||||
#define VIDEO_DRV_CONTROL_RX_ENABLE (1UL << 1) ///< Enable Receiver
|
||||
#define VIDEO_DRV_CONTROL_RX_DISABLE (1UL << 3) ///< Disable Receiver
|
||||
|
||||
/* Video Event */
|
||||
#define VIDEO_DRV_EVENT_RX_DATA (1UL << 1) ///< Data block received
|
||||
|
||||
/* Return code */
|
||||
#define VIDEO_DRV_OK (0) ///< Operation succeeded
|
||||
#define VIDEO_DRV_ERROR (-1) ///< Unspecified error
|
||||
#define VIDEO_DRV_ERROR_BUSY (-2) ///< Driver is busy
|
||||
#define VIDEO_DRV_ERROR_TIMEOUT (-3) ///< Timeout occurred
|
||||
#define VIDEO_DRV_ERROR_UNSUPPORTED (-4) ///< Operation not supported
|
||||
#define VIDEO_DRV_ERROR_PARAMETER (-5) ///< Parameter error
|
||||
|
||||
/**
|
||||
\brief Video Status
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t tx_active : 1; ///< Transmitter active
|
||||
uint32_t rx_active : 1; ///< Receiver active
|
||||
uint32_t reserved : 30;
|
||||
} VideoDrv_Status_t;
|
||||
|
||||
uint8_t* VideoRXBuffer();
|
||||
int32_t VideoDrv_Setup(void);
|
||||
|
||||
/**
|
||||
\fn VideoDrv_Event_t
|
||||
\brief Video Events callback function type: void (*VideoDrv_Event_t) (uint32_t event
|
||||
\param[in] event events notification mask
|
||||
\return none
|
||||
*/
|
||||
typedef void (*VideoDrv_Event_t) (uint32_t event);
|
||||
|
||||
/**
|
||||
\fn int32_t VideoDrv_Initialize (VideoDrv_Event_t cb_event)
|
||||
\brief Initialize Video Interface.
|
||||
\param[in] cb_event pointer to \ref VideoDrv_Event_t
|
||||
\return return code
|
||||
*/
|
||||
int32_t VideoDrv_Initialize (VideoDrv_Event_t cb_event);
|
||||
|
||||
/**
|
||||
\fn void VideoDrv_Stop (void);
|
||||
\brief Stop audio simulation.
|
||||
\return return code
|
||||
*/
|
||||
void VideoDrv_Stop (void);
|
||||
|
||||
|
||||
/**
|
||||
\fn int32_t VideoDrv_Uninitialize (void)
|
||||
\brief De-initialize Video Interface.
|
||||
\return return code
|
||||
*/
|
||||
int32_t VideoDrv_Uninitialize (void);
|
||||
|
||||
/**
|
||||
\fn int32_t VideoDrv_Configure (uint32_t interface, uint32_t channels, uint32_t sample_bits, uint32_t sample_rate)
|
||||
\brief Configure Video Interface.
|
||||
\param[in] interface audio interface
|
||||
\param[in] pixel_size size in bytes
|
||||
\param[in] samplerate samples per second
|
||||
\return return code
|
||||
*/
|
||||
int32_t VideoDrv_Configure (uint32_t interface, uint32_t pixel_size,uint32_t samplerate);
|
||||
|
||||
/**
|
||||
\fn int32_t VideoDrv_SetBuf (uint32_t interface, void *buf, uint32_t block_num, uint32_t block_size)
|
||||
\brief Set Video Interface buffer.
|
||||
\param[in] interface audio interface
|
||||
\param[in] buf pointer to buffer for audio data
|
||||
\param[in] block_num number of blocks in buffer (must be 2^n)
|
||||
\param[in] block_size block size in number of samples
|
||||
\return return code
|
||||
*/
|
||||
int32_t VideoDrv_SetBuf (uint32_t interface, void *buf, uint32_t block_num, uint32_t block_size);
|
||||
|
||||
/**
|
||||
\fn int32_t VideoDrv_Control (uint32_t control)
|
||||
\brief Control Video Interface.
|
||||
\param[in] control operation
|
||||
\return return code
|
||||
*/
|
||||
int32_t VideoDrv_Control (uint32_t control);
|
||||
|
||||
|
||||
/**
|
||||
\fn uint32_t VideoDrv_GetRxCount (void)
|
||||
\brief Get received block count.
|
||||
\return number of received blocks
|
||||
*/
|
||||
uint32_t VideoDrv_GetRxCount (void);
|
||||
|
||||
/**
|
||||
\fn VideoDrv_Status_t VideoDrv_GetStatus (void)
|
||||
\brief Get Video Interface status.
|
||||
\return \ref VideoDrv_Status_t
|
||||
*/
|
||||
VideoDrv_Status_t VideoDrv_GetStatus (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __VIDEO_DRV_H */
|
||||
Loading…
Reference in New Issue