打印
[AT32F403/403A]

AT32F403A SDIO+SDNAND 口线无数据输出问题请教。

[复制链接]
646|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
SJPU|  楼主 | 2022-9-5 21:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
AT32F403ACGU7 的SDIO2 挂SDNAND芯片 使用GPIOA[7..2]口线,IO配置如下:
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
  IOMUX->remap6_bit.sdio2_gmux = 1;
  /* sdio periph clock enable */
  crm_periph_clock_enable(CRM_SDIO2_PERIPH_CLOCK, TRUE);

  /* configure PA[7..2] */
  uint32_t temp = GPIOA->cfglr & (~0xffffff00);
   temp |=
                   ((2 << 10 ) | (1 <<  8 )    /* PA2   复用推挽输出     */
                   |(2 << 14 ) | (1 << 12 )    /* PA3   复用推挽输出     */
                   |(2 << 18 ) | (1 << 16 )    /* PA4   复用推挽输出     */
                   |(2 << 22 ) | (1 << 20 )    /* PA5   复用推挽输出     */
                   |(2 << 26 ) | (1 << 24 )    /* PA6   复用推挽输出     */
                   |(2 << 30 ) | (1 << 28 ));  /* PA7   复用推挽输出     */
   GPIOA->cfglr =  temp;

在调用官方库的sd_power_on()函数内部:

{
     .............
  /* send cmd55, check sd version */
    sdio_command_init_struct.argument = 0x00;
    sdio_command_init_struct.cmd_index = SD_CMD_APP_CMD;
    sdio_command_init_struct.rsp_type = SDIO_RESPONSE_SHORT;
    sdio_command_init_struct.wait_type = SDIO_WAIT_FOR_NO;

    /* sdio command config */
    sdio_command_config(SDIOx, &sdio_command_init_struct);
    /* enable ccsm */
    sdio_command_state_machine_enable(SDIOx, TRUE);

    /* waiting R1 */
    status = command_rsp1_error(SD_CMD_APP_CMD);
   
  /* check sd card or mmc card */
  if( SD_OK == status)
  {
    /* send acmd41, check voltage operation range */
    while((!valid_voltage) && (count < SD_MAX_VOLT_TRIAL))
    {
      OS_Delay(10);
         /* send cmd55 before acmd41 */
      sdio_command_init_struct.argument = 0x00;
      sdio_command_init_struct.cmd_index = SD_CMD_APP_CMD;
      sdio_command_init_struct.rsp_type = SDIO_RESPONSE_SHORT;
      sdio_command_init_struct.wait_type = SDIO_WAIT_FOR_NO;
      ...........
  }
  .......
}
发SD_CMD_APP_CMD命令 后 SDIO2的状态寄存器中 CMDRSPCMPL为被置为1(收到命令回应)。但命令响应寄存器SDIO_RSPCMD的值却一直是0.则让程序一直发送SD_CMD_APP_CMD,用示波器测试SDIO的clk 和cmd线状态,则两根线的电平固定,并没有波形存在。

此时PA[7..2]口线并没有其他外设同时分配到这几个管脚。
请教一下各位这可能是哪里的原因?

使用特权

评论回复
沙发
dxjian723| | 2022-9-10 21:46 | 只看该作者
遇到同样问题

使用特权

评论回复
板凳
SJPU|  楼主 | 2022-9-11 17:52 | 只看该作者
本帖最后由 SJPU 于 2022-9-11 21:10 编辑

IOMUX->remap6_bit.sdio2_gmux = 1;这一句改成IOMUX->remap6_bit.sdio2_gmux = 3;
#define  MCU_CHIP_403A

#ifdef MCU_CHIP_403A
#  undef SDIOx
#  define  SDIOx SDIO2
#elif (defined MCU_CHIP_407)
#  undef SDIOx
#  define  SDIOx SDIO1
#else
  #error   "Unknown mcu target."
#endif

//static
void sdio_low_init(void)
{

#ifdef MCU_CHIP_403A  /*for AT32F403A */
   /* gpioc and gpiod periph clock enable */
  crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
  /* sdio periph clock enable */
  crm_periph_clock_enable(CRM_SDIO2_PERIPH_CLOCK, TRUE);

  IOMUX->remap6_bit.sdio2_gmux  = 3;
  IOMUX->remap7_bit.swjtag_gmux = 2;
  /* configure PA[7..2] */
  uint32_t temp = GPIOA->cfglr & 0xff ;
   temp |=
                   ((2 << 10 ) | (2 <<  8 )    /* PA2   复用推挽输出     */
                   |(2 << 14 ) | (2 << 12 )    /* PA3   复用推挽输出     */
                   |(2 << 18 ) | (2 << 16 )    /* PA4   复用推挽输出     */
                   |(2 << 22 ) | (2 << 20 )    /* PA5   复用推挽输出     */
                   |(2 << 26 ) | (2 << 24 )    /* PA6   复用推挽输出     */
                   |(2 << 30 ) | (2 << 28 ));  /* PA7   复用推挽输出     */
   GPIOA->cfglr =  temp;

#elif (defined MCU_CHIP_407)     /*for AT32F407 */
  crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_SDIO1_PERIPH_CLOCK, TRUE);
uint32_t temp = GPIOC->cfghr & (~0x00ffffF0);
   temp |=
                   ((2 <<  6 ) | (2 <<  4 )    /* PC8   复用推挽输出     */
                   |(2 << 10 ) | (2 <<  8 )    /* PC9   复用推挽输出     */
                   |(2 << 14 ) | (2 << 12 )    /* PC10  复用推挽输出     */
                   |(2 << 18 ) | (2 << 16 )    /* PC11  复用推挽输出     */
                   |(2 << 22 ) | (2 << 20 ));  /* PC12  复用推挽输出     */
   GPIOC->cfghr =  temp;

   temp = GPIOD->cfglr & (~0xF00);
   temp |=          (2 << 10 ) | (2 << 8 );    /* PD2   复用推挽输出     */
   GPIOD->cfglr =  temp;
#endif
}

但是在403A上, SDIO2发送命令后SD卡一直不回应,SDIO报命令超时错误。
相同代码但在407上命令没问题,但用官方的sdio示例,写卡有问题:
sd_error_status_type sdio_command_data_send(sdio_command_struct_type *sdio_cmd_init_t, \
                                            sdio_data_struct_type* sdio_data_init_t, uint32_t *buf)
{
  .........

else if(device_mode == SD_TRANSFER_DMA_MODE)
  {
    if(sdio_data_init_t->transfer_direction == SDIO_DATA_TRANSFER_TO_CARD)
    {
      sd_dma_config(buf, length, DMA_DIR_MEMORY_TO_PERIPHERAL);
      SDIOx->inten |= SDIO_INTR_STS_WRITE_MASK;
      transfer_error = SD_OK;
      transfer_end = 0;
      sdio_dma_enable(SDIOx, TRUE);
    }

    while(!(SDIOx->sts & SDIOx->inten) && timeout)
    {
      timeout--;

      if(transfer_end)
      {
        break;
      }
    }

    if(timeout == 0)
    {
      sd_init();
      return SD_DATA_TIMEOUT;
    }

    if(transfer_error != SD_OK)
    {
      status = transfer_error;
    }
  }

  return status;
}
DMA传输写操作,DMA好像已经传输完毕了(数据传输量寄存器已经减为0,中断标志位也置1),SDIO的DTCNTR和BUFCNTR寄存器也减为0了,但SDIO却一直处于DOTX状态,然后就产生数据超时中断。不知为何。

完整的DMA代码如下:
if(device_mode == SD_TRANSFER_DMA_MODE)
  {

    transfer_error = SD_OK;
    transfer_end = 0;
    if(sdio_data_init_t->transfer_direction == SDIO_DATA_TRANSFER_TO_CONTROLLER)
    { /* 读操作 如果使用中断的话,应该使用DMA中断  */

       /* sdio command config */
      sdio_data_config(SDIOx, sdio_data_init_t);
      /* enable dcsm */
      sdio_data_state_machine_enable(SDIOx, TRUE);

      sd_dma_config(buf, length, DMA_DIR_PERIPHERAL_TO_MEMORY);
      SDIOx->inten |= SDIO_INTR_STS_READ_MASK;
      SDIOx->inten &= ~((1 << 8) |(1 << 10)); //禁止数据完成中断
      sdio_dma_enable(SDIOx, TRUE);
      /* sdio command config */
      sdio_command_config(SDIOx, sdio_cmd_init_t);
      /* enable ccsm */
      sdio_command_state_machine_enable(SDIOx, TRUE);
      status = command_rsp1_error(sdio_cmd_init_t->cmd_index);
      if(status != SD_OK)
      {
        return status;
      }
    }
    if(sdio_data_init_t->transfer_direction == SDIO_DATA_TRANSFER_TO_CARD)
    { /* 写操作 如使用中断方式,则使用SDIO传输完成中断 */

       sdio_data_config(SDIOx, sdio_data_init_t);
        /* enable dcsm */
       sdio_data_state_machine_enable(SDIOx, TRUE);

       /* sdio command config */
       sdio_command_config(SDIOx, sdio_cmd_init_t);
       /* enable ccsm */
       sdio_command_state_machine_enable(SDIOx, TRUE);

       status = command_rsp1_error(sdio_cmd_init_t->cmd_index);
       if(status != SD_OK)
       {
        return status;
       }
       sd_dma_config(buf, length, DMA_DIR_MEMORY_TO_PERIPHERAL);
       SDIOx->inten |= SDIO_INTR_STS_WRITE_MASK;
       sdio_dma_enable(SDIOx, TRUE);
    }

    OS_TASKEVENT event = OS_EVENT_GetMaskTimed(&sdio_event,
                           SDIO_EVENT_RECV_OK | SDIO_EVENT_SEND_OK,
                           20000);//200ms
    if(event == 0 )
    {
    //  sd_init();
      return SD_DATA_TIMEOUT;
    }

    if(transfer_error != SD_OK)
    {
      status = transfer_error;
    }
    return SD_OK;

  }
DMA读卡没问题,但写卡一直是这个问题。命令通道,数据通道,DMA通道 ,三者无论按什么次序配置都不好用。
希望官方有技术支持给解决一下。

改用PIO方式操作 也是读取没问题 ,写入不行。也是在数据写SDIOx->buf写完后,SDIO一直处于DOTX状态 ,然后就是数据超时中断。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

62

帖子

2

粉丝