summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorJiaojinxing <jiaojinxing1987@gmail.com>2016-10-20 13:22:24 (GMT)
committer Jiaojinxing <jiaojinxing1987@gmail.com>2016-10-20 13:22:24 (GMT)
commit08a25f29dd40c4219ec2d63c51b2917bbc9d9cae (patch)
tree213333b58c41f9b67fe9d68a3ac689735dd5864f
parentded0c1297c84948c40c10bb7422e86d55c91edf4 (diff)
downloadbspam335x-08a25f29dd40c4219ec2d63c51b2917bbc9d9cae.zip
bspam335x-08a25f29dd40c4219ec2d63c51b2917bbc9d9cae.tar.gz
bspam335x-08a25f29dd40c4219ec2d63c51b2917bbc9d9cae.tar.bz2
Fixed audio driver and link script file bug.
-rw-r--r--SylixOS/driver/audio/audioLib.c13
-rw-r--r--SylixOS/driver/audio/audioLib.h10
-rw-r--r--SylixOS/driver/audio/audioLibTest1.c2
-rw-r--r--SylixOS/driver/audio/audioLibTest2.c28
-rw-r--r--SylixOS/driver/audio/dsp/dspDrv.c14
-rw-r--r--SylixOS/driver/mcasp/am335x_mcasp.c243
-rw-r--r--SylixOSBSP.ld9
7 files changed, 217 insertions, 102 deletions
diff --git a/SylixOS/driver/audio/audioLib.c b/SylixOS/driver/audio/audioLib.c
index cd5d9c7..be0d794 100644
--- a/SylixOS/driver/audio/audioLib.c
+++ b/SylixOS/driver/audio/audioLib.c
@@ -38,7 +38,7 @@
struct __AUDIO_CAPTURE_STRUCT {
AUDIO_CAPTURE_PARAM param; /* 音频捕捉参数 */
AUDIO_CATPURE_CALLBACK pfuncOnAudioCapture; /* 音频捕捉回调函数 */
- VOID *pvCbArg; /* 回调参数 */
+ PVOID pvCbArg; /* 回调参数 */
INT iFd; /* 文件描述符 */
BOOL bOpened; /* 是否已经打开 */
BOOL bConfiged; /* 是否已经配置 */
@@ -301,8 +301,10 @@ INT API_AudioCaptureSetParam (AUDIO_CAPTURE_HANDLE hCaptureHandle, AUDIO_CAPTU
*********************************************************************************************************/
INT API_AudioCaptureStart (AUDIO_CAPTURE_HANDLE hCaptureHandle,
AUDIO_CATPURE_CALLBACK pfuncOnAudioCapture,
- VOID *pvCbArg)
+ PVOID pvCbArg)
{
+ INT iRet;
+
if (!hCaptureHandle) {
return (PX_ERROR);
}
@@ -328,7 +330,8 @@ INT API_AudioCaptureStart (AUDIO_CAPTURE_HANDLE hCaptureHandle,
hCaptureHandle->bExitRequest = LW_FALSE;
- if (pthread_create(&hCaptureHandle->hServiceThread, NULL, __AudioCaptureService, hCaptureHandle) != 0) {
+ iRet = pthread_create(&hCaptureHandle->hServiceThread, NULL, __AudioCaptureService, hCaptureHandle);
+ if (iRet != 0) {
printf("failed to create capture service thread\n");
goto __error_handle;
}
@@ -380,7 +383,7 @@ INT API_AudioCaptureStop (AUDIO_CAPTURE_HANDLE hCaptureHandle)
** 全局变量:
** 调用模块:
*********************************************************************************************************/
-static VOID *__AudioCaptureService(VOID *pvArg)
+static PVOID __AudioCaptureService (PVOID pvArg)
{
AUDIO_CAPTURE_HANDLE hCaptureHandle = pvArg;
struct count_info iptr;
@@ -573,7 +576,7 @@ INT API_AudioPlaySetParam (AUDIO_PLAY_HANDLE hPlayHandle, AUDIO_PLAY_PARAM *p
** 全局变量:
** 调用模块:
*********************************************************************************************************/
-INT API_AudioPlay (AUDIO_PLAY_HANDLE hPlayHandle, const VOID *pvData, size_t stDataLen)
+INT API_AudioPlay (AUDIO_PLAY_HANDLE hPlayHandle, const PVOID pvData, size_t stDataLen)
{
ssize_t stRet;
const UINT8 *pucPtr;
diff --git a/SylixOS/driver/audio/audioLib.h b/SylixOS/driver/audio/audioLib.h
index 79e7920..59d3f4d 100644
--- a/SylixOS/driver/audio/audioLib.h
+++ b/SylixOS/driver/audio/audioLib.h
@@ -41,9 +41,9 @@ typedef struct {
/*
* 音频捕捉回调函数
*/
-typedef VOID (*AUDIO_CATPURE_CALLBACK)(VOID *pvArg, /* 注册的回调函数参数 */
- const VOID *pvData, /* 音频数据 */
- size_t stDataLen); /* 音频数据长度(字节) */
+typedef VOID (*AUDIO_CATPURE_CALLBACK)(PVOID pvArg, /* 注册的回调函数参数 */
+ const PVOID pvData, /* 音频数据 */
+ size_t stDataLen); /* 音频数据长度(字节) */
struct __AUDIO_CAPTURE_STRUCT;
typedef struct __AUDIO_CAPTURE_STRUCT *AUDIO_CAPTURE_HANDLE; /* 音频捕捉句柄 */
@@ -114,7 +114,7 @@ INT API_AudioCaptureSetParam(AUDIO_CAPTURE_HANDLE hCaptureHandle, AUDIO_CAPTUR
*********************************************************************************************************/
INT API_AudioCaptureStart(AUDIO_CAPTURE_HANDLE hCaptureHandle,
AUDIO_CATPURE_CALLBACK pfuncOnAudioCapture,
- VOID *pvCbArg);
+ PVOID pvCbArg);
/*********************************************************************************************************
** 函数名称: API_AudioCaptureStop
@@ -167,7 +167,7 @@ INT API_AudioPlaySetParam(AUDIO_PLAY_HANDLE hPlayHandle, AUDIO_PLAY_PARAM *pP
** 全局变量:
** 调用模块:
*********************************************************************************************************/
-INT API_AudioPlay(AUDIO_PLAY_HANDLE hPlayHandle, const VOID *pvData, size_t stDataLen);
+INT API_AudioPlay(AUDIO_PLAY_HANDLE hPlayHandle, const PVOID pvData, size_t stDataLen);
#endif /* AUDIOLIB_H_ */
/*********************************************************************************************************
diff --git a/SylixOS/driver/audio/audioLibTest1.c b/SylixOS/driver/audio/audioLibTest1.c
index 5fae34f..4f7a6dc 100644
--- a/SylixOS/driver/audio/audioLibTest1.c
+++ b/SylixOS/driver/audio/audioLibTest1.c
@@ -61,7 +61,7 @@ static AUDIO_PLAY_HANDLE _G_hPlayHandle; /* 音频
** 全局变量:
** 调用模块:
*********************************************************************************************************/
-static void audio_capture_callback (void *arg, const void *data, size_t len)
+static void audio_capture_callback (PVOID arg, const PVOID data, size_t len)
{
struct timespec tvNow;
diff --git a/SylixOS/driver/audio/audioLibTest2.c b/SylixOS/driver/audio/audioLibTest2.c
index 99332ba..9802103 100644
--- a/SylixOS/driver/audio/audioLibTest2.c
+++ b/SylixOS/driver/audio/audioLibTest2.c
@@ -51,6 +51,7 @@
*********************************************************************************************************/
static AUDIO_CAPTURE_HANDLE _G_hCaptureHandle; /* 音频捕捉器句柄 */
static AUDIO_PLAY_HANDLE _G_hPlayHandle; /* 音频播放器句柄 */
+static LW_OBJECT_HANDLE _G_hPlayQueue;
/*********************************************************************************************************
** 函数名称: audio_capture_callback
** 功能描述: 音频捕捉回调
@@ -61,11 +62,9 @@ static AUDIO_PLAY_HANDLE _G_hPlayHandle; /* 音频
** 全局变量:
** 调用模块:
*********************************************************************************************************/
-static void audio_capture_callback (void *arg, const void *data, size_t len)
+static void audio_capture_callback (PVOID arg, const PVOID data, size_t len)
{
- if (_G_hPlayHandle) {
- API_AudioPlay(_G_hPlayHandle, data, len); /* 播放音频 */
- }
+ API_MsgQueueSend(_G_hPlayQueue, data, len);
}
/*********************************************************************************************************
** 函数名称: audio_lib_test2
@@ -79,9 +78,17 @@ int audio_lib_test2 (int argc, char **argv)
{
AUDIO_CAPTURE_PARAM captureParam;
AUDIO_PLAY_PARAM playParam;
+ CHAR *buf;
+ size_t len;
API_AudioLibInit(); /* 初始化音频库 */
+ _G_hPlayQueue = API_MsgQueueCreate("play_queue",
+ 20,
+ __AUDIOLIB_TEST_BUFFER_LEN,
+ LW_OPTION_OBJECT_LOCAL,
+ LW_NULL);
+
_G_hCaptureHandle = API_AudioCaptureOpen(); /* 打开音频捕捉器 */
captureParam.iChannelNum = __AUDIOLIB_TEST_CHANNELS;
@@ -104,10 +111,21 @@ int audio_lib_test2 (int argc, char **argv)
API_AudioPlaySetParam(_G_hPlayHandle, &playParam); /* 设置音频播放参数 */
+ buf = malloc(__AUDIOLIB_TEST_BUFFER_LEN); /* 分配缓冲区 */
+ if (!buf) {
+ printf("failed to alloc buffer!\n");
+ return (-1);
+ }
+
while (1) {
- sleep(1);
+ API_MsgQueueReceive(_G_hPlayQueue, buf,
+ __AUDIOLIB_TEST_BUFFER_LEN, &len, LW_OPTION_WAIT_INFINITE);
+
+ API_AudioPlay(_G_hPlayHandle, buf, len); /* 播放音频 */
}
+ free(buf); /* 释放缓冲区 */
+
API_AudioCaptureStop(_G_hCaptureHandle); /* 停止音频捕捉 */
API_AudioCaptureClose(_G_hCaptureHandle); /* 关闭音频捕捉器 */
diff --git a/SylixOS/driver/audio/dsp/dspDrv.c b/SylixOS/driver/audio/dsp/dspDrv.c
index 33a0765..6b623a4 100644
--- a/SylixOS/driver/audio/dsp/dspDrv.c
+++ b/SylixOS/driver/audio/dsp/dspDrv.c
@@ -421,13 +421,16 @@ static VOID __dspBatchReadDone (PVOID pvArg)
UINT i;
SSIZETFUNCPTR pfuncDrvTransfer;
INT iError;
+ INTREG intReg;
/*
* 读完成计数++
*/
+ LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
i = pDspDev->DSP_uiBatchReadDoneCount;
pDspDev->DSP_uiBatchReadDoneCount++;
pDspDev->DSP_uiBatchReadDoneCount = pDspDev->DSP_uiBatchReadDoneCount % pDspDev->DSP_ulBlockCounter;
+ LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
SEL_WAKE_UP_ALL(&pDspDev->DSP_selList, SELREAD); /* 唤醒 select 等待读任务 */
@@ -536,17 +539,20 @@ static INT __dspBatchReadStop (__PDSP_DEV pDspDev)
*********************************************************************************************************/
static VOID __dspBatchWriteDone (PVOID pvArg)
{
- __PDSP_DEV pDspDev = pvArg;
- UINT i;
- SSIZETFUNCPTR pfuncDrvTransfer;
- INT iError;
+ __PDSP_DEV pDspDev = pvArg;
+ UINT i;
+ SSIZETFUNCPTR pfuncDrvTransfer;
+ INT iError;
+ INTREG intReg;
/*
* 写完成计数++
*/
+ LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
i = pDspDev->DSP_uiBatchWriteDoneCount;
pDspDev->DSP_uiBatchWriteDoneCount++;
pDspDev->DSP_uiBatchWriteDoneCount = pDspDev->DSP_uiBatchWriteDoneCount % pDspDev->DSP_ulBlockCounter;
+ LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
SEL_WAKE_UP_ALL(&pDspDev->DSP_selList, SELWRITE); /* 唤醒 select 等待写任务 */
diff --git a/SylixOS/driver/mcasp/am335x_mcasp.c b/SylixOS/driver/mcasp/am335x_mcasp.c
index 5824535..873f315 100644
--- a/SylixOS/driver/mcasp/am335x_mcasp.c
+++ b/SylixOS/driver/mcasp/am335x_mcasp.c
@@ -35,10 +35,14 @@
*********************************************************************************************************/
#define __MCASP_CHANNEL_NR (2)
-/* Slot size to send/receive data */
+/*
+ * Slot size to send/receive data
+ */
#define __MCASP_DEFAULT_SLOT_SIZE (32)
-/* Word size to send/receive data. Word size <= Slot size */
+/*
+ * Word size to send/receive data. Word size <= Slot size
+ */
#define __MCASP_DEFAULT_WORD_SIZE (32)
#define __MCASP_I2S_CHANNELS_NUM (2)
@@ -53,8 +57,8 @@
#define __MSASP_AUIDO_BUF_SIZE (512)
/*
-** Definitions which are not configurable
-*/
+ * Definitions which are not configurable
+ */
#define SIZE_PARAMSET (32u)
#define OPT_FIFO_WIDTH (0x02 << 8u)
@@ -70,13 +74,13 @@
#define __DMAJOB_STATUS_FREE (0x00)
#define __DMAJOB_STATUS_TRANS (0xFF)
/*********************************************************************************************************
- 定义
+ DMA 工作类型定义
*********************************************************************************************************/
typedef struct {
- LW_SPI_MESSAGE DMAJOB_transMsg;
- UINT DMAJOB_uiStatus;
- EDMA3CCPaRAMEntry DMAJOB_paramSet;
- UINT DMAJOB_uiParId;
+ LW_SPI_MESSAGE DMAJOB_transMsg; /* 传输消息 */
+ UINT DMAJOB_uiStatus; /* 状态 */
+ EDMA3CCPaRAMEntry DMAJOB_paramSet; /* DMA 参数 */
+ UINT DMAJOB_uiParId; /* 参数 ID */
} AUDIO_DMA_JOB, *PAUDIO_DMA_JOB;
/*********************************************************************************************************
McASP 通道类型定义
@@ -91,31 +95,34 @@ typedef struct {
UINT MCASP_uiTxDmaChannel; /* 发送 DMA 通道号 */
UINT MCASP_uiRxDmaChannel; /* 接收 DMA 通道号 */
- INT MCASP_iBytesPerSample;
+ INT MCASP_iBytesPerSample; /* 采样大小(多通道) */
addr_t MCASP_ulCtrlVirtAddrBase; /* CTRL 寄存器虚拟地址基地址 */
BOOL MCASP_bIsInit; /* 是否已经初始化 */
- AUDIO_DMA_JOB MCASP_ringRxDmaJob[__MCASP_DMA_MAX_NODE_NUM];
- AUDIO_DMA_JOB MCASP_ringTxDmaJob[__MCASP_DMA_MAX_NODE_NUM];
+ AUDIO_DMA_JOB MCASP_ringRxDmaJob[__MCASP_DMA_MAX_NODE_NUM]; /* 接收 DMA 工作环 */
+ AUDIO_DMA_JOB MCASP_ringTxDmaJob[__MCASP_DMA_MAX_NODE_NUM]; /* 发送 DMA 工作环 */
+
+ UINT MCASP_uiCurRxDmaJob; /* 当前接收 DMA 工作 */
+ UINT MCASP_uiCurTxDmaJob; /* 当前发送 DMA 工作 */
- UINT MCASP_uiCurRxDmaJob;
- UINT MCASP_uiCurTxDmaJob;
+ UINT MCASP_uiSerializerRx; /* 接收 Serializer */
+ UINT MCASP_uiSerializerTx; /* 发送 Serializer */
- UINT MCASP_uiSerializerRx;
- UINT MCASP_uiSerializerTx;
+ LW_SPI_MESSAGE MCASP_rxMsgPool[__DSP_MAX_FRAGMENT_NUM]; /* 接收 MSG 池 */
+ LW_SPI_MESSAGE MCASP_txMsgPool[__DSP_MAX_FRAGMENT_NUM]; /* 发送 MSG 池 */
- LW_SPI_MESSAGE MCASP_rxMsgPool[__DSP_MAX_FRAGMENT_NUM];
- LW_SPI_MESSAGE MCASP_txMsgPool[__DSP_MAX_FRAGMENT_NUM];
+ LW_QUEUE MCASP_rxMsgQueue; /* 接收 MSG 队列 */
+ LW_QUEUE MCASP_txMsgQueue; /* 发送 MSG 队列 */
- LW_QUEUE MCASP_rxMsgQueue;
- LW_QUEUE MCASP_txMsgQueue;
+ UINT8 *MCASP_pucRxDmaBufferDummy; /* 假的接收缓冲区 */
+ UINT8 *MCASP_pucTxDmaBufferDummy; /* 假的发送缓冲区 */
- UINT8 *MCASP_pucTxDmaBufferDummy;
- UINT8 *MCASP_pucRxDmaBufferDummy;
+ spinlock_t MCASP_splRx; /* RX 自旋锁 */
+ spinlock_t MCASP_splTx; /* TX 自旋锁 */
- PAM335X_PINMUX MCASP_pPinMux;
+ PAM335X_PINMUX MCASP_pPinMux; /* 管脚配置 */
} __AM335X_MCASP_CHANNEL, *__PAM335X_MCASP_CHANNEL;
/*********************************************************************************************************
全局变量
@@ -150,6 +157,9 @@ static __AM335X_MCASP_CHANNEL _G_am335xMcAspChannels[__MCASP_CHANNEL_NR] = {
static VOID __am335xMcAspDmaRxDone (__PAM335X_MCASP_CHANNEL pMcAspChannel)
{
PAUDIO_DMA_JOB pDmaJob;
+ INTREG iregInterLevel;
+
+ LW_SPIN_LOCK_QUICK(&pMcAspChannel->MCASP_splRx, &iregInterLevel);
/*
* 获得当前传输完成的 DMA 工作
@@ -224,6 +234,8 @@ static VOID __am335xMcAspDmaRxDone (__PAM335X_MCASP_CHANNEL pMcAspChannel)
pDmaJob->DMAJOB_paramSet.destAddr = (UINT)pMcAspChannel->MCASP_pucRxDmaBufferDummy;
EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, pDmaJob->DMAJOB_uiParId, &pDmaJob->DMAJOB_paramSet);
}
+
+ LW_SPIN_UNLOCK_QUICK(&pMcAspChannel->MCASP_splRx, iregInterLevel);
}
/*********************************************************************************************************
** 函数名称: __am335xMcAspDmaTxDone
@@ -237,6 +249,9 @@ static VOID __am335xMcAspDmaRxDone (__PAM335X_MCASP_CHANNEL pMcAspChannel)
static VOID __am335xMcAspDmaTxDone (__PAM335X_MCASP_CHANNEL pMcAspChannel)
{
PAUDIO_DMA_JOB pDmaJob;
+ INTREG iregInterLevel;
+
+ LW_SPIN_LOCK_QUICK(&pMcAspChannel->MCASP_splTx, &iregInterLevel);
pDmaJob = &pMcAspChannel->MCASP_ringTxDmaJob[pMcAspChannel->MCASP_uiCurTxDmaJob];
@@ -308,6 +323,8 @@ static VOID __am335xMcAspDmaTxDone (__PAM335X_MCASP_CHANNEL pMcAspChannel)
pDmaJob->DMAJOB_paramSet.srcAddr = (UINT)pMcAspChannel->MCASP_pucTxDmaBufferDummy;
EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, pDmaJob->DMAJOB_uiParId, &pDmaJob->DMAJOB_paramSet);
}
+
+ LW_SPIN_UNLOCK_QUICK(&pMcAspChannel->MCASP_splTx, iregInterLevel);
}
/*********************************************************************************************************
** 函数名称: __am335xMcAspTransferMsg
@@ -322,39 +339,42 @@ static INT __am335xMcAspTransferMsg (__PAM335X_MCASP_CHANNEL pMcAspChannel,
PLW_SPI_MESSAGE pSpiMsg)
{
UINT uiIn;
+ INTREG iregInterLevel;
if ((pSpiMsg->SPIMSG_pucWrBuffer == LW_NULL &&
pSpiMsg->SPIMSG_pucRdBuffer == LW_NULL) ||
- pSpiMsg->SPIMSG_uiLen == 0) {
+ pSpiMsg->SPIMSG_uiLen == 0) { /* 参数检查 */
return (PX_ERROR);
}
- INTREG iregInterLevel = KN_INT_DISABLE();
-
- if (pSpiMsg->SPIMSG_pucRdBuffer) {
+ if (pSpiMsg->SPIMSG_pucRdBuffer) { /* 需要接收 */
+ LW_SPIN_LOCK_QUICK(&pMcAspChannel->MCASP_splRx, &iregInterLevel);
- if (API_QueueIsFull(&pMcAspChannel->MCASP_rxMsgQueue)) {
- KN_INT_ENABLE(iregInterLevel);
+ if (API_QueueIsFull(&pMcAspChannel->MCASP_rxMsgQueue)) { /* 接收队列已满 */
+ LW_SPIN_UNLOCK_QUICK(&pMcAspChannel->MCASP_splRx, iregInterLevel);
printk(KERN_ERR "__am335xMcAspTransferMsg(): rx queue full\n");
return (PX_ERROR);
}
- API_QueueIn(&pMcAspChannel->MCASP_rxMsgQueue, &uiIn);
- pMcAspChannel->MCASP_rxMsgPool[uiIn] = *pSpiMsg;
+ API_QueueIn(&pMcAspChannel->MCASP_rxMsgQueue, &uiIn); /* 获得入队位置并入队 */
+ pMcAspChannel->MCASP_rxMsgPool[uiIn] = *pSpiMsg; /* 在入队位置记录接收消息 */
- } else if (pSpiMsg->SPIMSG_pucWrBuffer) {
+ LW_SPIN_UNLOCK_QUICK(&pMcAspChannel->MCASP_splRx, iregInterLevel);
- if (API_QueueIsFull(&pMcAspChannel->MCASP_txMsgQueue)) {
- KN_INT_ENABLE(iregInterLevel);
+ } else if (pSpiMsg->SPIMSG_pucWrBuffer) { /* 需要发送 */
+ LW_SPIN_LOCK_QUICK(&pMcAspChannel->MCASP_splTx, &iregInterLevel);
+
+ if (API_QueueIsFull(&pMcAspChannel->MCASP_txMsgQueue)) { /* 发送队列已满 */
+ LW_SPIN_UNLOCK_QUICK(&pMcAspChannel->MCASP_splTx, iregInterLevel);
printk(KERN_ERR "__am335xMcAspTransferMsg(): tx queue full\n");
return (PX_ERROR);
}
- API_QueueIn(&pMcAspChannel->MCASP_txMsgQueue, &uiIn);
- pMcAspChannel->MCASP_txMsgPool[uiIn] = *pSpiMsg;
- }
+ API_QueueIn(&pMcAspChannel->MCASP_txMsgQueue, &uiIn); /* 获得入队位置并入队 */
+ pMcAspChannel->MCASP_txMsgPool[uiIn] = *pSpiMsg; /* 在入队位置记录发送消息 */
- KN_INT_ENABLE(iregInterLevel);
+ LW_SPIN_UNLOCK_QUICK(&pMcAspChannel->MCASP_splTx, iregInterLevel);
+ }
return (ERROR_NONE);
}
@@ -373,30 +393,38 @@ static VOID __am335xMcAspRxDmaInit (__PAM335X_MCASP_CHANNEL pMcAspChannel)
EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
pMcAspChannel->MCASP_uiRxDmaChannel,
- pMcAspChannel->MCASP_uiRxDmaChannel, 0);
+ pMcAspChannel->MCASP_uiRxDmaChannel, 0); /* 申请 DMA 通道 */
- pMcAspChannel->MCASP_uiCurRxDmaJob = 0;
+ pMcAspChannel->MCASP_uiCurRxDmaJob = 0; /* 复位当前接收 DMA 工作点 */
- API_QueueInit(&pMcAspChannel->MCASP_rxMsgQueue, __DSP_MAX_FRAGMENT_NUM);
+ API_QueueInit(&pMcAspChannel->MCASP_rxMsgQueue,
+ __DSP_MAX_FRAGMENT_NUM); /* 初始化接收消息队列 */
+ /*
+ * 分配假的接收缓冲区
+ */
pMcAspChannel->MCASP_pucRxDmaBufferDummy = API_VmmDmaAlloc(__MSASP_AUIDO_BUF_SIZE);
- for (i = 0; i < __MCASP_DMA_MAX_NODE_NUM; i++) {
+ for (i = 0; i < __MCASP_DMA_MAX_NODE_NUM; i++) { /* 初始化每个接收 DMA 工作 */
pDmaJob = &pMcAspChannel->MCASP_ringRxDmaJob[i];
- lib_memset(pDmaJob, 0, sizeof(*pDmaJob));
+ lib_memset(pDmaJob, 0, sizeof(*pDmaJob)); /* 清零 DMA 工作 */
if (i == 0) {
pDmaJob->DMAJOB_uiParId = pMcAspChannel->MCASP_uiRxDmaChannel;
} else {
- pDmaJob->DMAJOB_uiParId = PAR_RX_START + (i - 1);
+ pDmaJob->DMAJOB_uiParId = PAR_RX_START + (i - 1); /* 参数 ID */
}
- pDmaJob->DMAJOB_paramSet.opt = OPT_FIFO_WIDTH | RX_DMA_INT_ENABLE(pMcAspChannel->MCASP_uiRxDmaChannel);
+ pDmaJob->DMAJOB_paramSet.opt = OPT_FIFO_WIDTH | /* FIFO 宽度 */
+ RX_DMA_INT_ENABLE(pMcAspChannel->MCASP_uiRxDmaChannel);
+ /* 源地址为设备物理地址 */
pDmaJob->DMAJOB_paramSet.srcAddr = pMcAspChannel->MCASP_ulDataPhyAddrBase;
+ /* 目的地址为假的接收缓冲区 */
pDmaJob->DMAJOB_paramSet.destAddr = (UINT)pMcAspChannel->MCASP_pucRxDmaBufferDummy;
+ /* 每次接收双通道采样 */
pDmaJob->DMAJOB_paramSet.aCnt = pMcAspChannel->MCASP_iBytesPerSample;
pDmaJob->DMAJOB_paramSet.bCnt = __MSASP_AUIDO_BUF_SIZE /
pMcAspChannel->MCASP_iBytesPerSample;
@@ -420,7 +448,9 @@ static VOID __am335xMcAspRxDmaInit (__PAM335X_MCASP_CHANNEL pMcAspChannel)
EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, pDmaJob->DMAJOB_uiParId, &pDmaJob->DMAJOB_paramSet);
}
- /* Enable EDMA for the transfer */
+ /*
+ * Enable EDMA for the transfer
+ */
EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, pMcAspChannel->MCASP_uiRxDmaChannel,
EDMA3_TRIG_MODE_EVENT);
}
@@ -434,16 +464,18 @@ static VOID __am335xMcAspRxDmaInit (__PAM335X_MCASP_CHANNEL pMcAspChannel)
*********************************************************************************************************/
static VOID __am335xMcAspRxDmaDeInit (__PAM335X_MCASP_CHANNEL pMcAspChannel)
{
- /* Disable EDMA for the transfer */
+ /*
+ * Disable EDMA for the transfer
+ */
EDMA3DisableTransfer(SOC_EDMA30CC_0_REGS, pMcAspChannel->MCASP_uiRxDmaChannel,
EDMA3_TRIG_MODE_EVENT);
EDMA3FreeChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
pMcAspChannel->MCASP_uiRxDmaChannel,
EDMA3_TRIG_MODE_EVENT,
- pMcAspChannel->MCASP_uiRxDmaChannel, 0);
+ pMcAspChannel->MCASP_uiRxDmaChannel, 0); /* 释放 DMA 通道 */
- API_VmmDmaFree(pMcAspChannel->MCASP_pucRxDmaBufferDummy);
+ API_VmmDmaFree(pMcAspChannel->MCASP_pucRxDmaBufferDummy); /* 释放假的接收 DMA 缓冲区 */
pMcAspChannel->MCASP_pucRxDmaBufferDummy = LW_NULL;
}
/*********************************************************************************************************
@@ -461,31 +493,39 @@ static VOID __am335xMcAspTxDmaInit (__PAM335X_MCASP_CHANNEL pMcAspChannel)
EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
pMcAspChannel->MCASP_uiTxDmaChannel,
- pMcAspChannel->MCASP_uiTxDmaChannel, 0);
+ pMcAspChannel->MCASP_uiTxDmaChannel, 0); /* 申请 DMA 通道 */
- pMcAspChannel->MCASP_uiCurTxDmaJob = 0;
+ pMcAspChannel->MCASP_uiCurTxDmaJob = 0; /* 复位当前发送 DMA 工作点 */
- API_QueueInit(&pMcAspChannel->MCASP_txMsgQueue, __DSP_MAX_FRAGMENT_NUM);
+ API_QueueInit(&pMcAspChannel->MCASP_txMsgQueue,
+ __DSP_MAX_FRAGMENT_NUM); /* 初始化接收消息队列 */
+ /*
+ * 分配假的发送缓冲区
+ */
pMcAspChannel->MCASP_pucTxDmaBufferDummy = API_VmmDmaAlloc(__MSASP_AUIDO_BUF_SIZE);
lib_bzero(pMcAspChannel->MCASP_pucTxDmaBufferDummy, __MSASP_AUIDO_BUF_SIZE);
- for (i = 0; i < __MCASP_DMA_MAX_NODE_NUM; i++) {
+ for (i = 0; i < __MCASP_DMA_MAX_NODE_NUM; i++) { /* 初始化每个发送 DMA 工作 */
pDmaJob = &pMcAspChannel->MCASP_ringTxDmaJob[i];
- lib_memset(pDmaJob, 0, sizeof(*pDmaJob));
+ lib_memset(pDmaJob, 0, sizeof(*pDmaJob)); /* 清零 DMA 工作 */
if (i == 0) {
pDmaJob->DMAJOB_uiParId = pMcAspChannel->MCASP_uiTxDmaChannel;
} else {
- pDmaJob->DMAJOB_uiParId = PAR_TX_START + (i - 1);
+ pDmaJob->DMAJOB_uiParId = PAR_TX_START + (i - 1); /* 参数 ID */
}
- pDmaJob->DMAJOB_paramSet.opt = OPT_FIFO_WIDTH | TX_DMA_INT_ENABLE(pMcAspChannel->MCASP_uiTxDmaChannel);
+ pDmaJob->DMAJOB_paramSet.opt = OPT_FIFO_WIDTH | /* FIFO 宽度 */
+ TX_DMA_INT_ENABLE(pMcAspChannel->MCASP_uiTxDmaChannel);
+ /* 源地址为假的发送缓冲区 */
pDmaJob->DMAJOB_paramSet.srcAddr = (UINT)pMcAspChannel->MCASP_pucTxDmaBufferDummy;
+ /* 目的地址为设备物理地址 */
pDmaJob->DMAJOB_paramSet.destAddr = pMcAspChannel->MCASP_ulDataPhyAddrBase;
+ /* 每次发送双通道采样 */
pDmaJob->DMAJOB_paramSet.aCnt = pMcAspChannel->MCASP_iBytesPerSample;
pDmaJob->DMAJOB_paramSet.bCnt = __MSASP_AUIDO_BUF_SIZE /
pMcAspChannel->MCASP_iBytesPerSample;
@@ -523,16 +563,18 @@ static VOID __am335xMcAspTxDmaInit (__PAM335X_MCASP_CHANNEL pMcAspChannel)
*********************************************************************************************************/
static VOID __am335xMcAspTxDmaDeInit (__PAM335X_MCASP_CHANNEL pMcAspChannel)
{
- /* Disable EDMA for the transfer */
+ /*
+ * Disable EDMA for the transfer
+ */
EDMA3DisableTransfer(SOC_EDMA30CC_0_REGS, pMcAspChannel->MCASP_uiTxDmaChannel,
EDMA3_TRIG_MODE_EVENT);
EDMA3FreeChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
pMcAspChannel->MCASP_uiTxDmaChannel,
EDMA3_TRIG_MODE_EVENT,
- pMcAspChannel->MCASP_uiTxDmaChannel, 0);
+ pMcAspChannel->MCASP_uiTxDmaChannel, 0); /* 释放 DMA 通道 */
- API_VmmDmaFree(pMcAspChannel->MCASP_pucTxDmaBufferDummy);
+ API_VmmDmaFree(pMcAspChannel->MCASP_pucTxDmaBufferDummy); /* 释放假的发送 DMA 缓冲区 */
pMcAspChannel->MCASP_pucTxDmaBufferDummy = LW_NULL;
}
/*********************************************************************************************************
@@ -545,7 +587,7 @@ static VOID __am335xMcAspTxDmaDeInit (__PAM335X_MCASP_CHANNEL pMcAspChannel)
*********************************************************************************************************/
VOID am335xMcaspEdma3Done (UINT uiChannel)
{
- switch (uiChannel) {
+ switch (uiChannel) { /* 根据通道号调用相应的完成函数*/
case EDMA3_CHA_MCASP0_RX:
__am335xMcAspDmaRxDone(&_G_am335xMcAspChannels[0]);
break;
@@ -585,7 +627,7 @@ static INT __am335xMcAspTransfer (__PAM335X_MCASP_CHANNEL pMcAspChannel,
REGISTER INT i;
INT iError;
- for (i = 0; i < iNum; i++, pSpiMsg++) {
+ for (i = 0; i < iNum; i++, pSpiMsg++) { /* 传输每一个消息 */
iError = __am335xMcAspTransferMsg(pMcAspChannel, pSpiMsg);
if (iError != ERROR_NONE) {
return (i);
@@ -639,13 +681,17 @@ static VOID __am335xMcAspI2SConfigure (__PAM335X_MCASP_CHANNEL pMcAspChannel)
McASPRxReset(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
McASPTxReset(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
- /* Enable the FIFOs for DMA transfer */
+ /*
+ * Enable the FIFOs for DMA transfer
+ */
McASPReadFifoEnable(pMcAspChannel->MCASP_ulCtrlVirtAddrBase +
pMcAspChannel->MCASP_ulFifoRegOffset, 1, 1);
McASPWriteFifoEnable(pMcAspChannel->MCASP_ulCtrlVirtAddrBase +
pMcAspChannel->MCASP_ulFifoRegOffset, 1, 1);
- /* Set I2S format in the transmitter/receiver format units */
+ /*
+ * Set I2S format in the transmitter/receiver format units
+ */
McASPRxFmtI2SSet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase,
__MCASP_DEFAULT_WORD_SIZE, __MCASP_DEFAULT_SLOT_SIZE, MCASP_RX_MODE_DMA);
McASPTxFmtI2SSet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase,
@@ -653,28 +699,38 @@ static VOID __am335xMcAspI2SConfigure (__PAM335X_MCASP_CHANNEL pMcAspChannel)
pMcAspChannel->MCASP_iBytesPerSample = __MCASP_DEFAULT_WORD_SIZE >> 3;
- /* Configure the frame sync. I2S shall work in TDM format with 2 slots */
+ /*
+ * Configure the frame sync. I2S shall work in TDM format with 2 slots
+ */
McASPRxFrameSyncCfg(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, 2, MCASP_RX_FS_WIDTH_WORD,
MCASP_RX_FS_EXT_BEGIN_ON_FALL_EDGE);
McASPTxFrameSyncCfg(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, 2, MCASP_TX_FS_WIDTH_WORD,
MCASP_TX_FS_EXT_BEGIN_ON_FALL_EDGE);
- /* configure the clock for receiver */
+ /*
+ * configure the clock for receiver
+ */
McASPRxClkCfg(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_RX_CLK_EXTERNAL, 0, 0);
McASPRxClkPolaritySet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_RX_CLK_POL_RIS_EDGE);
McASPRxClkCheckConfig(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_RX_CLKCHCK_DIV32,
0x00, 0xFF);
- /* configure the clock for transmitter */
+ /*
+ * configure the clock for transmitter
+ */
McASPTxClkCfg(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_TX_CLK_EXTERNAL, 0, 0);
McASPTxClkPolaritySet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_TX_CLK_POL_FALL_EDGE);
McASPTxClkCheckConfig(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_TX_CLKCHCK_DIV32,
0x00, 0xFF);
- /* Enable synchronization of RX and TX sections */
+ /*
+ * Enable synchronization of RX and TX sections
+ */
McASPTxRxClkSyncEnable(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
- /* Enable the transmitter/receiver slots. I2S uses 2 slots */
+ /*
+ * Enable the transmitter/receiver slots. I2S uses 2 slots
+ */
McASPRxTimeSlotSet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, __MCASP_I2S_SLOTS);
McASPTxTimeSlotSet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, __MCASP_I2S_SLOTS);
@@ -718,18 +774,26 @@ static VOID __am335xMcAspI2SConfigure (__PAM335X_MCASP_CHANNEL pMcAspChannel)
*********************************************************************************************************/
static VOID __am335xMcAspI2SDataTxRxActivate (__PAM335X_MCASP_CHANNEL pMcAspChannel)
{
- /* Start the clocks */
+ /*
+ * Start the clocks
+ */
McASPTxClkStart(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_TX_CLK_EXTERNAL);
McASPRxClkStart(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_RX_CLK_EXTERNAL);
- /* Activate the serializers */
+ /*
+ * Activate the serializers
+ */
McASPTxSerActivate(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
McASPRxSerActivate(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
- /* make sure that the XDATA bit is cleared to zero */
+ /*
+ * make sure that the XDATA bit is cleared to zero
+ */
while (McASPTxStatusGet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase) & MCASP_TX_STAT_DATAREADY);
- /* Activate the state machines */
+ /*
+ * Activate the state machines
+ */
McASPTxEnable(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
McASPRxEnable(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
}
@@ -757,6 +821,9 @@ static INT __am335xMcAspMasterCtl (__PAM335X_MCASP_CHANNEL pMcAspChannel,
switch (iCmd) {
case __AUDIO_CODEC_OPEN:
+ /*
+ * 映射寄存器
+ */
pMcAspChannel->MCASP_ulCtrlVirtAddrBase = (addr_t)API_VmmIoRemapNocache(
(PVOID)pMcAspChannel->MCASP_ulCtrlPhyAddrBase,
pMcAspChannel->MCASP_stCtrlPhyAddrSize);
@@ -765,6 +832,12 @@ static INT __am335xMcAspMasterCtl (__PAM335X_MCASP_CHANNEL pMcAspChannel,
return (PX_ERROR);
}
+ LW_SPIN_INIT(&pMcAspChannel->MCASP_splTx); /* 初始化读写自旋锁 */
+ LW_SPIN_INIT(&pMcAspChannel->MCASP_splRx);
+
+ /*
+ * 使能模块时钟
+ */
switch (uiChannel) {
case 0:
am335xEnableModuleClock(am335xModuleIdGet("MCASP0"));
@@ -779,24 +852,27 @@ static INT __am335xMcAspMasterCtl (__PAM335X_MCASP_CHANNEL pMcAspChannel,
return (PX_ERROR);
}
- am335xPinMuxSetup(pMcAspChannel->MCASP_pPinMux);
+ am335xPinMuxSetup(pMcAspChannel->MCASP_pPinMux); /* 配置管脚 */
- __am335xMcAspI2SConfigure(pMcAspChannel);
+ __am335xMcAspI2SConfigure(pMcAspChannel); /* 配置 I2S */
- __am335xMcAspTxDmaInit(pMcAspChannel);
+ __am335xMcAspTxDmaInit(pMcAspChannel); /* 初始化 TX DMA */
- __am335xMcAspRxDmaInit(pMcAspChannel);
+ __am335xMcAspRxDmaInit(pMcAspChannel); /* 初始化 RX DMA */
- __am335xMcAspI2SDataTxRxActivate(pMcAspChannel);
+ __am335xMcAspI2SDataTxRxActivate(pMcAspChannel); /* 激活发送和接收 */
break;
case __AUDIO_CODEC_CLOSE:
- McASPRxReset(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
+ McASPRxReset(pMcAspChannel->MCASP_ulCtrlVirtAddrBase); /* 复位发送和接收 */
McASPTxReset(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
- __am335xMcAspTxDmaDeInit(pMcAspChannel);
- __am335xMcAspRxDmaDeInit(pMcAspChannel);
+ __am335xMcAspTxDmaDeInit(pMcAspChannel); /* 反向初始化 TX DMA */
+ __am335xMcAspRxDmaDeInit(pMcAspChannel); /* 反向初始化 RX DMA */
+ /*
+ * 关闭模块时钟
+ */
switch (uiChannel) {
case 0:
am335xDisableModuleClock(am335xModuleIdGet("MCASP0"), 1);
@@ -811,6 +887,9 @@ static INT __am335xMcAspMasterCtl (__PAM335X_MCASP_CHANNEL pMcAspChannel,
return (PX_ERROR);
}
+ /*
+ * 取消映射寄存器
+ */
API_VmmIoUnmap((PVOID)pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
pMcAspChannel->MCASP_ulCtrlVirtAddrBase = 0;
break;
@@ -880,8 +959,8 @@ static INT __am335xMcAspInit(__PAM335X_MCASP_CHANNEL pMcAspChannel,
UINT uiSerializerTx,
UINT uiSerializerRx)
{
- if (!pMcAspChannel->MCASP_bIsInit) {
- pMcAspChannel->MCASP_pPinMux = pPinMux;
+ if (!pMcAspChannel->MCASP_bIsInit) { /* 还没有初始化 */
+ pMcAspChannel->MCASP_pPinMux = pPinMux; /* 记录管脚配置等信息 */
pMcAspChannel->MCASP_uiSerializerTx = uiSerializerTx;
pMcAspChannel->MCASP_uiSerializerRx = uiSerializerRx;
pMcAspChannel->MCASP_bIsInit = LW_TRUE;
diff --git a/SylixOSBSP.ld b/SylixOSBSP.ld
index 818fae2..4350b08 100644
--- a/SylixOSBSP.ld
+++ b/SylixOSBSP.ld
@@ -55,6 +55,15 @@ SECTIONS
} > TEXT
/*********************************************************************************************************
+ GOT
+*********************************************************************************************************/
+
+ .got : {
+ *(.got.plt)
+ *(.got)
+ } > TEXT
+
+/*********************************************************************************************************
.ARM.exidx is sorted, so has to go in its own output section.
*********************************************************************************************************/