?? gspx-pxa.c
字號:
while ((pHC->pSSPRegs->base.ssr & 4) == 0);
#endif
LeaveCriticalSection(&pHC->SSPCrit);
funcLeave:
EXITFUNC(result);
return result;
}
/* JKU */
#if (USE_DMA == 1)
static GSPI_STATUS ssp_write_non_dma(PVOID hDC, PWORD data, WORD reg, WORD nword)
{
int result = GSPI_SUCCESS;
PSSP_HARDWARE_CONTEXT pHC;
BOOLEAN needToWriteReg = TRUE;
BOOLEAN isFrag = FALSE;
int i;
ENTERFUNC();
if (hDC == 0) {
result = GSPI_INVALIDARGS;
goto funcLeave;
}
pHC = (PSSP_HARDWARE_CONTEXT)hDC;
EnterCriticalSection(&pHC->SSPCrit);
reg |= 0x8000;
while ((pHC->pSSPRegs->base.ssr & 4) == 0); //check TNF
while (pHC->pSSPRegs->base.ssr & 0xF00); //check TFL
set_GPIO_signal(pHC->pGPIORegs, SSP_SFRM,SIG_UP);
set_GPIO_signal(pHC->pGPIORegs, SSP_SFRM,SIG_DOWN);
pHC->pSSPRegs->base.ssdr = reg;
for (i=0; i<nword; i++)
{
while ((pHC->pSSPRegs->base.ssr & 4) == 0); //check TNF
pHC->pSSPRegs->base.ssdr = *data++;
}
while ((pHC->pSSPRegs->base.ssr & 4) == 0); //check TNF
LeaveCriticalSection(&pHC->SSPCrit);
funcLeave:
EXITFUNC(result);
return result;
}
#endif
static GSPI_STATUS setup_read_dma(PSSP_HARDWARE_CONTEXT pHC, int n)
{
volatile DMADescriptorChannelType *rddesc = pHC->read_desc;
volatile DMADescriptorChannelType *wtdesc = pHC->rw_desc;
MYDMAPARAM *pwtDmaParam = &pHC->DMAParam[WTDMA_PARAM];
MYDMAPARAM *prdDmaParam = &pHC->DMAParam[RDDMA_PARAM];
GSPI_STATUS result = GSPI_SUCCESS;
#if (USE_DMAIRQ == 1)
DWORD dmaresult;
#endif ///USE_DMAIRQ
rddesc->ddadr |= DDADR_STOP;
rddesc->dcmd &= ~(DCMD_LENGTH);
#if (USE_DMAIRQ == 1)
rddesc->dcmd |= DCMD_ENDIRQEN | n;
ResetEvent(prdDmaParam->dmaWaitObj);
#else ///USE_DMAIRQ
rddesc->dcmd |= n;
#endif ///USE_DMAIRQ
if (n > PXA_SSP_IODATA_SIZE) {
GSPIMSG(ERRMSG, (TEXT("Requested length is too large (limit, req) = (%d, %xh)\n"), ERRMSG, n));
result = GSPI_INVALIDARGS;
goto funcFinal;
}
wtdesc->ddadr |= DDADR_STOP;
wtdesc->dcmd &= ~(DCMD_LENGTH);
///CRLo: Not enabling the IRQ for the dummy-write. We only care about the read in here
/// wtdesc->dcmd |= DCMD_ENDIRQEN | n;
///ResetEvent(pwtDmaParam->dmaWaitObj);
wtdesc->dcmd |= n;
pHC->pDMARegs->ddg[pwtDmaParam->channel].ddadr = (UINT32) pHC->rw_desc_phys_addr;
pHC->pDMARegs->ddg[prdDmaParam->channel].ddadr = (UINT32) pHC->read_desc_phys_addr;
pHC->pDMARegs->dcsr[pwtDmaParam->channel] |= DCSR_RUN; // set the RUN bit
pHC->pDMARegs->dcsr[prdDmaParam->channel] |= DCSR_RUN; // set the RUN bit
///Wait here until it's done
#if (USE_DMAIRQ == 1)
dmaresult = WaitForSingleObject(prdDmaParam->dmaWaitObj, (MAX_WAITus/1000));
if (dmaresult == WAIT_TIMEOUT) {
GSPIMSG(ERRMSG, (TEXT("Rd-DMA timeout (%d)\n"), n));
result = GSPI_TIMEOUT;
goto funcFinal;
}
#else ///USE_DMAIRQ
///Wait here until it's done
{
int lp;
volatile DWORD dcsr;
for (lp=0 ; lp<MAX_WAITus ; lp++) {
///dcsr = pHC->pDMARegs->dcsr[DMA_CH_READ];
dcsr = pHC->pDMARegs->dcsr[prdDmaParam->channel];
///if (dcsr & (DCSR_EORINT|DCSR_STOPSTATE)) {
if (dcsr & (DCSR_STOPSTATE)) {
///if ((n % 4) == 0) {
/// GSPIMSG(1, (TEXT("rd(%d), (lp, dcsr)= (%d, %xh)\n"), n, lp, dcsr));
///}
break;
}
udelay(pHC->pOSTRegs, 1);
///NdisMSleep(1);
///for (a=0 ; a<10 ; a++) ;
}
if (lp == MAX_WAITus) {
GSPIMSG(ERRMSG, (TEXT("Rd-DMA(%d), (lp, dcsr) = (%d, %xh)\n"), n, lp, dcsr));
result = GSPI_TIMEOUT;
///} else {
/// GSPIMSG(1, (TEXT("Rd-DMA ok, dcsr= %xh\n"), dcsr));
}
///Add one more delay at the end. Otherwise, the firmware download will failed.
/// (Don't know why)
udelay(pHC->pOSTRegs, 50); ///trial value (50us);
///NdisMSleep(1);
}
#endif ///USE_DMAIRQ
funcFinal:
return result;
}
static GSPI_STATUS ssp_read_data_direct(PVOID hDC, WORD* data, WORD reg, WORD nword, WORD dummy_clk)
{
GSPI_STATUS result = GSPI_SUCCESS;
PSSP_HARDWARE_CONTEXT pHC;
WORD nbyte = nword * 2;
#if (USE_DMA == 1)
int accnbyte; ///Accumulated length (0 - nbyte)
int fragnbyte; ///length of each fragment
BOOLEAN isfrag = FALSE;
#endif /// (USE_DMA == 1)
ENTERFUNC();
if (hDC == 0) {
result = GSPI_INVALIDARGS;
goto funcLeave;
}
pHC = (PSSP_HARDWARE_CONTEXT)hDC;
EnterCriticalSection(&pHC->SSPCrit);
///Reset the RX FIFO
pHC->pSSPRegs->base.sscr0 &= ~SSCR0_SSE;
pHC->pSSPRegs->base.sscr0 |= SSCR0_SSE;
#if !(USE_DMA == 1) //JKU
while ((pHC->pSSPRegs->base.ssr & 4) == 0); //JKU: TX is not full
while (pHC->pSSPRegs->base.ssr & 0xF00); //check TFL??? Do we need this???
#endif
set_GPIO_signal(pHC->pGPIORegs, SSP_SFRM,SIG_UP);
set_GPIO_signal(pHC->pGPIORegs, SSP_SFRM,SIG_DOWN);
///================================
#if (USE_DMA == 1)
///DMA mode
{
///Write the register address
///WORD *iodatPt = (WORD*)pHC->iodata;
WORD *iodatPt = (WORD*)pHC->iorw;
*iodatPt = reg;
result = setup_read_dma(pHC, (1+dummy_clk)*2);
if (result != GSPI_SUCCESS) {
GSPIMSG(ERRMSG, (TEXT("Fail to push reg+dummy_clk[%d]...\n"), dummy_clk));
}
}
///==============================================
accnbyte = 0;
while (1) {
fragnbyte = nbyte - accnbyte;
if (fragnbyte> PXA_SSP_IODATA_SIZE) {
fragnbyte = PXA_SSP_IODATA_SIZE;
isfrag = TRUE;
}
result = setup_read_dma(pHC, fragnbyte);
if (result != GSPI_SUCCESS) {
GSPIMSG(ERRMSG, (TEXT("%s, Read data failed...\n"), TEXT(__FUNCTION__)));
break;
}
///} while ((!(pHC->pDMARegs->dcsr[pHC->DMAParam[RDDMA_PARAM].channel] & DCSR_REQPEND) || retry) && --timeout);
memcpy(data, pHC->iodata, fragnbyte);
accnbyte += fragnbyte;
data += (fragnbyte/2); ///type of data is WORD
if (accnbyte == nbyte) {
if (isfrag == TRUE) {
GSPIMSG(RX_FRAG, (TEXT("Cont. reading data. (now, exp)=(%d, %d), complete!\n"), accnbyte, nbyte));
}
break;
} else if (accnbyte > nbyte){
GSPIMSG(ERRMSG, (TEXT("Invalid Rd Length, (exp, acc)=(%d, %d)\n"), nbyte, accnbyte));
} else {
if (isfrag == TRUE) {
GSPIMSG(RX_FRAG, (TEXT("Cont. reading data. (now, exp)=(%d, %d)\n"), accnbyte, nbyte));
}
}
}
#else //JKU: SyChip version
///CPU mode
{
volatile ULONG tmpval;
int i, j, k;
BOOL bData = FALSE;
PWORD dat = (PWORD)data;
pHC->pSSPRegs->base.ssdr = reg;
while ((pHC->pSSPRegs->base.ssr & 0x0008) == 0); //check RNE
tmpval = pHC->pSSPRegs->base.ssdr;
// the dummy clocks
for (k=0; k<dummy_clk; k++)
{
pHC->pSSPRegs->base.ssdr = 0xffff;
while ((pHC->pSSPRegs->base.ssr & 0x0008) == 0); //check RNE
tmpval = pHC->pSSPRegs->base.ssdr;
}
// the buffer
j = nword;
while (j)
{
i = min(j, 16); //RX FIFO size is 16 samples each 32-bit wide
for (k=0; k<i; k++)
{
pHC->pSSPRegs->base.ssdr = 0xFFFF;
}
for (k=0; k<i; k++)
{
while ((pHC->pSSPRegs->base.ssr & 0x0008) == 0); //check RNE
//do { tmpval = pHC->pSSPRegs->base.ssr; } while ((tmpval & 0x0008) == 0);
*dat++ = pHC->pSSPRegs->base.ssdr;
}
j -= i;
}
}
#endif ///USE_DMA
LeaveCriticalSection(&pHC->SSPCrit);
funcLeave:
//DEBUGMSG(ZONE_INIT, (TEXT("[r-]\n")));
EXITFUNC(result);
return result;
}
#if (USE_DMA == 1)
static GSPI_STATUS ssp_read_non_dma(PVOID hDC, WORD* data, WORD reg, WORD nword, WORD dummy_clk)
{
GSPI_STATUS result = GSPI_SUCCESS;
PSSP_HARDWARE_CONTEXT pHC;
WORD nbyte = nword * 2;
ENTERFUNC();
if (hDC == 0) {
result = GSPI_INVALIDARGS;
goto funcLeave;
}
pHC = (PSSP_HARDWARE_CONTEXT)hDC;
EnterCriticalSection(&pHC->SSPCrit);
while ((pHC->pSSPRegs->base.ssr & 4) == 0); //JKU: TX is not full
while (pHC->pSSPRegs->base.ssr & 0xF00); //check TFL??? Do we need this???
pHC->pSSPRegs->base.sscr0 &= ~SSCR0_SSE;
pHC->pSSPRegs->base.sscr0 |= SSCR0_SSE;
//while ((pHC->pSSPRegs->base.ssr & 4) == 0); //JKU: TX is not full
//while (pHC->pSSPRegs->base.ssr & 0xF00); //check TFL??? Do we need this???
set_GPIO_signal(pHC->pGPIORegs, SSP_SFRM,SIG_UP);
set_GPIO_signal(pHC->pGPIORegs, SSP_SFRM,SIG_DOWN);
///================================
///CPU mode
{
volatile ULONG tmpval;
int i, j, k;
BOOL bData = FALSE;
PWORD dat = (PWORD)data;
pHC->pSSPRegs->base.ssdr = reg;
while ((pHC->pSSPRegs->base.ssr & 0x0008) == 0); //check RNE
tmpval = pHC->pSSPRegs->base.ssdr;
// the dummy clocks
for (k=0; k<dummy_clk; k++)
{
pHC->pSSPRegs->base.ssdr = 0xffff;
while ((pHC->pSSPRegs->base.ssr & 0x0008) == 0); //check RNE
tmpval = pHC->pSSPRegs->base.ssdr;
}
j = nword;
while (j)
{
i = min(j, 16); //RX FIFO size is 16 samples each 32-bit wide
for (k=0; k<i; k++)
{
pHC->pSSPRegs->base.ssdr = 0xFFFF;
}
for (k=0; k<i; k++)
{
while ((pHC->pSSPRegs->base.ssr & 0x0008) == 0); //check RNE
//do { tmpval = pHC->pSSPRegs->base.ssr; } while ((tmpval & 0x0008) == 0);
*dat++ = pHC->pSSPRegs->base.ssdr;
}
j -= i;
}
}
LeaveCriticalSection(&pHC->SSPCrit);
funcLeave:
EXITFUNC(result);
return result;
}
#endif
///
/// ssp_read_register: Read the register from SSP interface
/// Input:
/// hDC - the context returned from SSP_Init
/// regaddr - register addreess
/// Output:
/// regdatPt - returned register value
/// Return:
/// 0 - success
/// -1 - failure
GSPI_STATUS ssp_read_register(PVOID hDC, WORD* regdatPt, WORD regaddr)
{
GSPI_STATUS result;
int i;
for (i=0 ; i<GSPI_MAX_REG_RETRY ; i++) {
#if !(USE_DMA == 1) //JKU
result = ssp_read_data_direct(hDC, regdatPt, regaddr, 1, g_spi_dummy_clk_reg);
#else
result = ssp_read_non_dma(hDC, regdatPt, regaddr, 1, g_spi_dummy_clk_reg);
#endif
if (result == GSPI_SUCCESS) {
break;
}
}
if (i == GSPI_MAX_REG_RETRY) {
GSPIMSG(ERRMSG, (L"%s, Read register(%xh) timeout \n", TEXT(__FUNCTION__), regaddr));
result = GSPI_TIMEOUT;
}
return result;
}
///
/// ssp_write_register: Write the register from SSP interface
/// Input:
/// hDC - the context returned from SSP_Init
/// regaddr - register addreess
/// regdat - register value to write
/// Output:
/// None
/// Return:
/// 0 - success
/// -1 - failure
GSPI_STATUS ssp_write_register(PVOID hDC, WORD regaddr, WORD* regdatPt)
{
GSPI_STATUS result;
int i;
for (i=0 ; i<GSPI_MAX_REG_RETRY ; i++) {
#if !(USE_DMA == 1) //JKU
result = ssp_write_data_direct(hDC, regdatPt, regaddr, 1);
#else
result = ssp_write_non_dma(hDC, regdatPt, regaddr, 1);
#endif
if (result == GSPI_SUCCESS) {
break;
}
}
if (i == GSPI_MAX_REG_RETRY) {
GSPIMSG(ERRMSG, (L"%s, Write register(%xh) timeout \n", TEXT(__FUNCTION__), regaddr));
result = GSPI_TIMEOUT;
}
return result;
}
///
/// ssp_read_data: Read the data from SSP interface
/// Input:
/// hDC - the context returned from SSP_Init
/// datPt - data buffer
/// size - size of the data buffer
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -