本帖最后由 zhaojianguo 于 2019-11-18 15:01 编辑
大家好:
采用外部AD芯片采样,在采样过程中使用AM335X中控芯片的EDMA功能,但是并未触发采样CS,采到的数据也不对,麻烦大家给看下,问题出在哪里。
static void adc_edma_config(void)
{
int result = 0;
unsigned int BRCnt = 0;
int srcbidx = 0;
int desbidx = 0;
int srccidx = 0;
int descidx = 0;
struct edmacc_param param_set;
/* Set B count reload as B count. */
BRCnt = ADC_EDMA_BCNT;
/* Setting up the SRC/DES Index */
srcbidx = 0;
desbidx = ADC_EDMA_ACNT;
/* A Sync Transfer Mode */
srccidx = 0;
descidx = ADC_EDMA_ACNT;
// gpmc channel
result = edma_alloc_channel (ADC_EDMA_GPMCEVT_CHAN, callback1, NULL, EVENTQ_0);
if (result < 0) {
printk("edma_adc_config:edma_alloc_channel ""failed for dma_ch1, error:%d\n", result);
return result;
}
dma_ch1 = result;
edma_set_src (dma_ch1, (unsigned long)(g_gpmc_cs1_base), INCR, W16BIT);
edma_set_dest (dma_ch1, (unsigned long)(TI_SRAM_BASE), INCR, W16BIT);
edma_set_src_index (dma_ch1, srcbidx, srccidx);
edma_set_dest_index (dma_ch1, desbidx, descidx);
edma_set_transfer_params (dma_ch1, ADC_EDMA_ACNT, ADC_EDMA_BCNT, ADC_EDMA_CCNT, BRCnt, ASYNC);
/* Enable the Interrupts on Channel 1 */
edma_read_slot (dma_ch1, ¶m_set);
param_set.opt |= (1 << ITCINTEN_SHIFT);
param_set.opt |= (1 << TCINTEN_SHIFT);
param_set.opt |= EDMA_TCC(EDMA_CHAN_SLOT(dma_ch1));
edma_write_slot(dma_ch1, ¶m_set);
return 0;
}
static int adc_sram_init(void)
{
padc_dots = ioremap(TI_SRAM_BASE, SZ_16K);
if(!padc_dots)
{
printk("%s: ioremap error\r\n", __func__);
return -1;
}
g_adc_pdata = padc_dots;
return 0;
}
int adc_init(void)
{
int i;
u32 rc;
u16 w;
int ret;
void __iomem *p_REGS;
//配置CS1,时序 U9 GPMC_CSN1
ret = gpio_gpmc_csn_init(GPMC_CS1, 16, &g_gpmc_cs1_base, &g_gpmc_cs1_vbase, &ad7616_timings);
if(ret)
{
printk("%s: CS%d init error\r\n" ,GPMC_CS1);
return -1;
}
g_addr_cs[0] = g_gpmc_cs1_vbase;
p_REGS = ioremap(SOC_CONTROL_REGS, SZ_8K);
if(!p_REGS)
{
printk("%s:ioremap(%x) error\r\n", __func__, SOC_CONTROL_REGS);
return -1;
}
g_SOC_CONTROL_REGS = (unsigned int)p_REGS;
p_REGS = ioremap(SOC_GPIO_0_REGS, SZ_4K);
if(!p_REGS)
{
printk("%s:ioremap(%x) error\r\n", __func__, SOC_GPIO_0_REGS);
iounmap((void __iomem *)g_SOC_CONTROL_REGS);
return -1;
}
g_SOC_GPIO_0_REGS = (unsigned int)p_REGS;
p_REGS = ioremap(SOC_GPIO_1_REGS, SZ_4K);
if(!p_REGS)
{
printk("%s:ioremap(%x) error\r\n", __func__, SOC_GPIO_1_REGS);
iounmap((void __iomem *)g_SOC_CONTROL_REGS);
return -1;
}
g_SOC_GPIO_1_REGS = (unsigned int)p_REGS;
p_REGS = ioremap(SOC_GPIO_2_REGS, SZ_4K);
if(!p_REGS)
{
printk("%s:ioremap(%x) error\r\n", __func__, SOC_GPIO_2_REGS);
iounmap((void __iomem *)g_SOC_CONTROL_REGS);
return -1;
}
g_SOC_GPIO_2_REGS = (unsigned int)p_REGS;
//配置CS1 功能
HWREG((unsigned int)g_SOC_CONTROL_REGS + CONTROL_CONF_GPMC_CSN(1)) =
(CONTROL_CONF_PULLUDDISABLE | CONTROL_CONF_MUXMODE(0));
GPIODirModeSet((unsigned int)g_SOC_GPIO_1_REGS, 30, GPIO_DIR_OUTPUT);
//配置GPMC_A7 gpio1_23 reset 上拉输出
HWREG((unsigned int)g_SOC_CONTROL_REGS + CONTROL_CONF_GPMC_A(7)) =
(CONTROL_CONF_PULLUDDISABLE | CONTROL_CONF_MUXMODE(7));
GPIODirModeSet((unsigned int)g_SOC_GPIO_1_REGS, 23, GPIO_DIR_OUTPUT);
GPIOPinWrite((unsigned int)g_SOC_GPIO_1_REGS, 23, GPIO_PIN_LOW);
ustimer_delay(1*USTIMER_MS); // 全复位至少1.2us
GPIOPinWrite((unsigned int)g_SOC_GPIO_1_REGS, 23, GPIO_PIN_HIGH);
ustimer_delay(20*USTIMER_MS); // RESET到CONVST最少15ms
//配置XDMA_EVENT_INTR0管脚为输入.此管脚对应AD7616的BUSY管脚
HWREG((unsigned int)g_SOC_CONTROL_REGS + CONTROL_CONF_XDMA_EVENT_INTR(0)) =
(CONTROL_CONF_PULLUPSEL | CONTROL_CONF_MUXMODE(7));
GPIODirModeSet((unsigned int)g_SOC_GPIO_0_REGS, 19, GPIO_DIR_INPUT);
// 外部AD软件初始化
for(i=0; i<EQU_SLOT_AC_NUM; i++)
{
// 写0正式启动转换
*(u32*)g_addr_cs[i] = 0;
}
adc_sram_init();
adc_edma_config();
edma_start(dma_ch1);
return 0;
}
|