[i.MX] imx6q ECSPI2从模式通过中断接受数据异常

[复制链接]
1087|0
 楼主| hwx628 发表于 2019-1-17 14:09 | 显示全部楼层 |阅读模式
第一次是还是进中断是Rxdata_reg收到是0x00000001;从第二次之后收到的都是0xFFFFFFFF;来源是另外一块MCU,每100ms发我这边32bytes的数据,一次128bit,分两次发给我,每次进中断都正常。时钟是5Mhz。目前只用了ECSPI2来接受东西,每次中断都能进去,

有大佬帮我看看么,困住很久了,代码如下
  1. #define ECSPI_FIFO_SIZE 64
  2. //#define DEBUG
  3. #define SPI_RETRY_TIMES 2
  4. #define BURST_L         8
  5. //master device ECSPI1 for test
  6. uint8_t  tx_buf_ecspi1[ECSPI_FIFO_SIZE*4];
  7. uint8_t  rx_buf_ecspi1[ECSPI_FIFO_SIZE*4];
  8. //slave device ECSPI2 for test
  9. uint8_t  tx_buf_ecspi2[ECSPI_FIFO_SIZE*4];
  10. uint8_t  rx_buf_ecspi2[ECSPI_FIFO_SIZE*4];
  11. //ECSPI device configuration @HWX
  12. param_ecspi_t param[2] = {{1,1,1,0,0,12,0,0},//sschanel=1,master,ECSPI1,5MHz
  13. {0,0,1,1,1,12,0,0}};//sschanel=1,slave,ECSPI2,non-single burst,5MHz

  14. static void ecspi_start_transfer(unsigned instance, uint16_t brs_bts);
  15. static int ecspi_xfer_slv(unsigned instance, const uint8_t * tx_buf, uint8_t * rx_buf, int bytes);
  16. static int ecspi_xfer_mst(unsigned instance, const uint8_t * tx_buf, uint8_t * rx_buf, int bytes);

  17. /*///////////////////////////////////////////////////////////////////////////////
  18. // Code
  19. ///////////////////////////////////////////////////////////////////////////////*/

  20. static void ecspi_start_transfer(unsigned instance, uint16_t brs_bts)
  21. {
  22.     // Set burst length
  23.     HW_ECSPI_CONREG(instance).B.BURST_LENGTH = brs_bts - 1;

  24.     // Clear status
  25.     HW_ECSPI_STATREG_WR(instance, BM_ECSPI_STATREG_RO | BM_ECSPI_STATREG_TC);
  26. }

  27. static int ecspi_xfer_slv(unsigned instance, const uint8_t * tx_buf, uint8_t * rx_buf, int bytes)
  28. {

  29.     // new added by @HWX
  30.     /* Configure ECSPI.CONREG   */
  31.     /* Configure ECSPI.CONFIGREG   */
  32.     /* Fill TXFIFO*/
  33.     /* Wait for RXFIFO Interrupt(Ready or Data Request or Full) */
  34.     /* Read Data from RXFIFO*/
  35.     uint32_t val;
  36.     uint32_t idx;

  37.       val = 0;
  38. //            return ERROR_GENERIC;
  39. //        }

  40.     // Read from Rx FIFO

  41.     for (idx = 0; bytes > 0; bytes -= 4, idx += 4)
  42.     {
  43.         val = HW_ECSPI_RXDATA_RD(instance);
  44.         if (rx_buf)
  45.         {
  46.             switch (bytes)
  47.             {
  48.                 default:
  49.                     rx_buf[idx + 3] = val >> 24;
  50. //                    rx_buf[idx + 2] = (val >> 16) & 0xFF;
  51. //                    rx_buf[idx + 1] = (val >> 8) & 0xFF;
  52. //                    rx_buf[idx] = val & 0xFF;
  53.                     break;
  54.                 case 3:
  55.                     rx_buf[idx + 2] = (val >> 16) & 0xFF;
  56. //                    rx_buf[idx + 1] = (val >> 8) & 0xFF;
  57. //                    rx_buf[idx] = val & 0xFF;
  58.                     break;
  59.                 case 2:
  60.                     rx_buf[idx + 1] = (val >> 8) & 0xFF;
  61. //                    rx_buf[idx] = val & 0xFF;
  62.                     break;
  63.                 case 1:
  64.                     rx_buf[idx] = val & 0xFF;
  65.                     break;
  66.             }
  67.         }
  68.     }

  69. //#ifdef DEBUG
  70. //            printf("ecspi_xfer_slave: Receive data 0x%x %x %x %x,",rx_buf[0],rx_buf[1],rx_buf[2],rx_buf[3]);
  71. //#endif

  72.     // Clear status,write 1 to clear it
  73. //    HW_ECSPI_STATREG_WR(instance, BM_ECSPI_STATREG_TC);

  74.     return SUCCESS;


  75. }

  76. //! [url=home.php?mod=space&uid=247401]@brief[/url] Perform a SPI master transfer.
  77. //!
  78. //! @param instance ECSPI module instance number starting at 1.
  79. //! @param tx_buf
  80. //! @param rx_buf
  81. //! @param bytes Number of bytes to transfer.
  82. //!
  83. //! [url=home.php?mod=space&uid=2539868]@Todo[/url] Use interrupts to get notification of transfer completion instead of
  84. //!     polling the ECSPI STATREG and pausing 500 碌s.
  85. static int ecspi_xfer_mst(unsigned instance, const uint8_t * tx_buf, uint8_t * rx_buf, int bytes)
  86. {
  87.     uint32_t val;
  88.     uint32_t idx;
  89. //
  90. //    // Start burst
  91. //    HW_ECSPI_CONREG_SET(instance, BM_ECSPI_CONREG_SMC);
  92. //
  93. //    // Write to Tx FIFO
  94. //    val = 0;
  95. //
  96. //    for (idx = 0; idx < bytes; idx += 4)
  97. //    {
  98. //        // Only read from the buffer if it is not NULL. If a tx_buf is not provided,
  99. //        // then transfer 0 bytes.
  100. //        if (tx_buf)
  101. //        {
  102. //            val = tx_buf[idx] + (tx_buf[idx + 1] << 8) + (tx_buf[idx + 2] << 16) + (tx_buf[idx + 3] << 24);
  103. //        }
  104. //
  105. //        HW_ECSPI_TXDATA_WR(instance, val);
  106. //    }
  107. //    // write 1 to start burst immediately
  108. ////     HW_ECSPI_CONREG_SET(instance, BM_ECSPI_CONREG_XCH);
  109. //    //poll the value of XCH BIT,if XCH = 0, transfer process is over already.
  110. ////     while(BG_ECSPI_CONREG_XCH(HW_ECSPI_CONREG_ADDR(instance)) == 0)
  111. ////     {
  112. ////
  113. ////     }
  114. //    // Wait for transfer complete
  115. //    val = SPI_RETRY_TIMES;
  116. //    while (!HW_ECSPI_STATREG(instance).B.TC)
  117. //    {
  118. //        val--;
  119. //        if (val == 0)
  120. //        {
  121. ////#ifdef DEBUG
  122. ////            printf("ecspi_xfer: Transfer timeout.\n");
  123. ////#endif
  124. //            return ERROR_GENERIC;
  125. //        }
  126. //
  127. ////        hal_delay_us(500);  //delay module not added now @HWX
  128. //    }


  129. //    if(HW_ECSPI_STATREG(instance).B.RR)
  130. //    {
  131.         for (idx = 0; bytes > 0; bytes -= 4, idx += 4)
  132.         {
  133.             val = HW_ECSPI_RXDATA_RD(instance);
  134.             if (rx_buf)
  135.             {
  136.                 switch (bytes)
  137.                 {
  138.                     default:
  139.                         rx_buf[idx + 3] = val >> 24;
  140. //                        rx_buf[idx + 2] = (val >> 16) & 0xFF;
  141. //                        rx_buf[idx + 1] = (val >> 8) & 0xFF;
  142. //                        rx_buf[idx] = val & 0xFF;
  143.                         break;
  144.                     case 3:
  145.                         rx_buf[idx + 2] = (val >> 16) & 0xFF;
  146. //                        rx_buf[idx + 1] = (val >> 8) & 0xFF;
  147. //                        rx_buf[idx] = val & 0xFF;
  148.                         break;
  149.                     case 2:
  150.                         rx_buf[idx + 1] = (val >> 8) & 0xFF;
  151. //                        rx_buf[idx] = val & 0xFF;
  152.                         break;
  153.                     case 1:
  154.                         rx_buf[idx] = val & 0xFF;
  155.                         break;
  156.                 }
  157.             }
  158.         }
  159. //    }
  160.     // Clear status
  161.     HW_ECSPI_STATREG_WR(instance, BM_ECSPI_STATREG_TC);

  162.     return SUCCESS;
  163. }

  164. int ecspi_configure(dev_ecspi_e instance, const param_ecspi_t * param)
  165. {
  166.     // Reset eCSPI controller
  167.     HW_ECSPI_CONREG(instance).B.EN = 1;

  168.     // Setup chip select
  169.     HW_ECSPI_CONREG(instance).B.CHANNEL_SELECT = param->channel;

  170.     // Setup mode
  171.     uint32_t channelMask = 1 << param->channel;
  172.     uint32_t value = HW_ECSPI_CONREG(instance).B.CHANNEL_MODE;
  173.     BW_ECSPI_CONREG_CHANNEL_MODE(instance, param->mode ? (value | channelMask) : (value & ~channelMask));

  174.     // Setup pre & post clock divider
  175.     HW_ECSPI_CONREG(instance).B.PRE_DIVIDER = (param->pre_div == 0) ? 0 : (param->pre_div - 1);
  176.     HW_ECSPI_CONREG(instance).B.POST_DIVIDER = param->post_div;

  177.     // Enable eCSPI
  178.     HW_ECSPI_CONREG(instance).B.EN = 1;

  179.     // Setup SCLK_PHA, SCLK_POL, SS_POL
  180.     value = HW_ECSPI_CONFIGREG(instance).B.SCLK_PHA;
  181.     HW_ECSPI_CONFIGREG(instance).B.SCLK_PHA = param->sclk_pha ? (value | channelMask) : (value & ~channelMask);

  182.     value = HW_ECSPI_CONFIGREG(instance).B.SCLK_POL;
  183.     HW_ECSPI_CONFIGREG(instance).B.SCLK_POL = param->sclk_pol ? (value | channelMask) : (value & ~channelMask);

  184.     value = HW_ECSPI_CONFIGREG(instance).B.SS_POL;
  185.     HW_ECSPI_CONFIGREG(instance).B.SS_POL = param->ss_pol ? (value | channelMask) : (value & ~channelMask);

  186.     HW_ECSPI_CONFIGREG(instance).B.SS_CTL |= channelMask;
  187. //    HW_ECSPI_CONFIGREG(instance).B.SS_CTL = 0x0;
  188. //    HW_ECSPI_PERIODREG(instance).B.SAMPLE_PERIOD = 0x10;

  189.     //Configure the Rx_threshold
  190.     HW_ECSPI_DMAREG(instance).B.RX_THRESHOLD = 0x1; //unit = one word(32 bits)
  191.     //Enable  RDR interrupt
  192. //    HW_ECSPI_INTREG(instance).B.TCEN =0x01;
  193.     HW_ECSPI_INTREG(instance).B.RDREN =1;

  194.     return SUCCESS;
  195. }

  196. //! @todo Validate [url=home.php?mod=space&uid=18481]@a[/url] dev value for the chip, since not all chips will have all 5 instances.
  197. int ecspi_open(dev_ecspi_e dev, const param_ecspi_t * param)
  198. {
  199.     // Configure IO signals
  200.     ecspi_iomux_config(dev);

  201.     // Ungate the module clock.
  202.     clock_gating_config(REGS_ECSPI_BASE(dev), CLOCK_ON);

  203.     // Configure eCSPI registers
  204.     ecspi_configure(dev, param);

  205.     return SUCCESS;
  206. }

  207. int ecspi_close(dev_ecspi_e dev)
  208. {
  209.     // Disable controller
  210.     HW_ECSPI_CONREG(dev).B.EN = 0;

  211.     // Gate the module clock.
  212.     clock_gating_config(REGS_ECSPI_BASE(dev), CLOCK_OFF);

  213.     return SUCCESS;
  214. }

  215. //! @todo Handle tranfers larger than the FIFO length!
  216. int ecspi_xfer(dev_ecspi_e dev, const uint8_t * tx_buf, uint8_t * rx_buf, uint16_t brs_bts)
  217. {
  218.     uint32_t retv = SUCCESS;

  219.     // Set bytes for burst
  220.     int bytes = brs_bts >> 3;

  221.     // Handle non-byte-aligned bits
  222.     if ((brs_bts & 0x7) != 0)
  223.     {
  224.         bytes++;
  225.     }

  226.     // Check burst length
  227.     if (bytes > ECSPI_FIFO_SIZE * 4)
  228.     {
  229. #ifdef DEBUG
  230.         printf("ecspi_xfer: Burst out of length.\n");
  231. #endif
  232.         retv = ERROR_GENERIC;
  233.     }

  234.     if (retv == SUCCESS)
  235.     {
  236.         // Prepare transfer
  237.         ecspi_start_transfer(dev, brs_bts);

  238.         // Initiate transfer
  239.         uint32_t channel = HW_ECSPI_CONREG(dev).B.CHANNEL_SELECT;

  240.         // Handle different mode transfer
  241.         if ((HW_ECSPI_CONREG(dev).B.CHANNEL_MODE & (1 << channel)) == 0)
  242.         {
  243.             retv = ecspi_xfer_slv(dev, tx_buf, rx_buf, bytes);
  244.         }
  245.         else
  246.         {
  247.             retv = ecspi_xfer_mst(dev, tx_buf, rx_buf, bytes);
  248.         }
  249.     }

  250.     return retv;
  251. }

  252. //static void Ecspi1_txIsr(void){
  253. //        static int i = 0;
  254. //        ecspi_xfer(DEV_ECSPI1, &tx_buf_ecspi1[i], &rx_buf_ecspi1[i], BURST_L);
  255. //        if(i < ECSPI_FIFO_SIZE*4)
  256. //        {
  257. //                i++;
  258. //        }
  259. //        else{
  260. //                i = 0;
  261. //        }
  262. //}
  263. static int i = 0;
  264. static void Ecspi2_rxIsr(void){

  265.         ecspi_xfer(DEV_ECSPI2, &tx_buf_ecspi2[i], &rx_buf_ecspi2[i], BURST_L);
  266.         if(i < (ECSPI_FIFO_SIZE*4-16))
  267.         {
  268.                 i += 1;
  269.         }
  270.         else{
  271.                 i = 0;
  272.         }
  273. }

  274. //spi module initialize @HWX
  275. void Spi_Init(void){
  276. //    ecspi_open(DEV_ECSPI1, &param[0]); //Enable ECSPI1
  277.     ecspi_open(DEV_ECSPI2, &param[1]); //Enable ECSPI2
  278.     // bind the ECSPI1 TDR ISR in GIC
  279. //        GIC_SpiIntInstall(Ecspi1_txIsr, IAR_INT_eCSPI1, 0x54, 0);
  280. //        GIC_IntEnable(IAR_INT_eCSPI1, 1);
  281.     // bind the ECSPI2 RDR ISR in GIC
  282.         GIC_SpiIntInstall(Ecspi2_rxIsr, IAR_INT_eCSPI2, 0x55, 0);
  283.         GIC_IntEnable(IAR_INT_eCSPI2, 1);
  284.         //for ecspi1,datas need to be wrote into norflash

  285. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

1

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部