AnsweredAssumed Answered

imx28 SPI Slave DMA

Question asked by Thomas Fruechtl on Feb 21, 2014
Latest reply on Apr 13, 2014 by Yixing Kong

Hi,

after a long time working with SPI Slave experiments and many help from Freescale and DENX people i got a spi slave running with DMA but if i got an commuication error between SPI host and Slave the DMA transfer times out and i can not reset the spi or dma channel can anyone help me about this.

I have tried reset dma , reset spi block.. but nothing helps

code snipped from mxs_spi.c:

ss->pdesc->cmd.cmd.bits.bytes = len;

  ss->pdesc->cmd.cmd.bits.pio_words = 1;

  ss->pdesc->cmd.cmd.bits.wait4end = 1;

  ss->pdesc->cmd.cmd.bits.dec_sem = 1;

  ss->pdesc->cmd.cmd.bits.irq = 1;

  //ss->pdesc->cmd.cmd.bits.chain = 1; // hello TF

  ss->pdesc->cmd.cmd.bits.command = write ? DMA_READ : DMA_WRITE;

  ss->pdesc->cmd.address = spi_buf_dma;

  ss->pdesc->cmd.pio_words[0] = c0;

  mxs_dma_desc_append(ss->dma, ss->pdesc);

 

 

  mxs_dma_reset(ss->dma);

  mxs_dma_ack_irq(ss->dma);

  mxs_dma_enable_irq(ss->dma, 1);

  init_completion(&ss->done);

  mxs_dma_enable(ss->dma);

  //wait_for_completion(&ss->done);

  retw = wait_for_completion_timeout(&ss->done,500); // hello TF 5s  

 

  printk(" retw = %x\n",retw);

// fixme after a timeout we have to reset kernel dont know why

  if(retw != 0){ // hello TF we have got a value

  count = 10000;

  while ((__raw_readl(ss->regs + HW_SSP_CTRL0) & BM_SSP_CTRL0_RUN)

  && count--)

  continue;

  if (count <= 0) {

  printk(KERN_ERR "%c: timeout on line %s:%d\n",

  write ? 'W' : 'C', __func__, __LINE__);

  status = -ETIMEDOUT;

  }

  if (!dma_buf)

  dma_unmap_single(ss->master_dev, spi_buf_dma, len, dir);

  printk("Status on ok = %x\n",__raw_readl(ss->regs + HW_SSP_STATUS));

  }else{

  printk(KERN_ERR "%c: tom timeout on line %s:%d\n",

  write ? 'W' : 'C', __func__, __LINE__);

  status = -ETIMEDOUT;

 

tryed out some of this but without any success

  printk("Status = %x\n",__raw_readl(ss->regs + HW_SSP_STATUS));

  mxs_dma_disable(ss->dma);

  mxs_dma_reset(ss->dma);

  //mxs_dma_ack_irq(ss->dma);

  //mxs_dma_enable_irq(ss->dma, 1);

  //mxs_reset_block((void __iomem *)ss->regs + HW_SSP_CTRL0, 0);

  printk("Status = %x\n",__raw_readl(ss->regs + HW_SSP_STATUS));

  __raw_writel(BM_SSP_CTRL1_DMA_ENABLE, ss->regs + HW_SSP_CTRL1_CLR);

  printk("Status = %x\n",__raw_readl(ss->regs + HW_SSP_STATUS));

 

the SSP_Status Register returns 0xE0200020 maybe anyone can interpret it dont know how bit 21 can be resetet (DMASENSE) i think this is the problem

during a normal operation without a timeout SSP Status returns 0xE0040020

 

thanks for help

Thomas

Outcomes