This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM3352: Read and write exception when a bare-metal program connects to an EMMC card

Part Number: AM3352

Hi team,

Here's an issue from the customer may need your help:

Single board uses SOC_MMCHS_1_regs to interface MTFC8GAKAJCN-4M it (multimedia card chip). And regarding drive, changes were made to the hsMmcSdRw project referenced to the lab AM335X_StarterWare_02_00_01_01.

Transmitting and receiving data in the program is done in the way of query, and card recognition is now functional, but data read and write are not functional.

unsigned char emmc_wr_test(void)
{
    unsigned char sd_size;
    unsigned char state;
//    unsigned char i=0;

   for(sd_size=0;sd_size<128;sd_size++)
   {
       r_buf[sd_size] = 0;
       w_buf[sd_size] =1+sd_size;
   }
   state =MMCSDWriteCmdSend(&ctrlInfo, w_buf,r_buf, 1,1);
   if(!state)
   {
       return state;
   }

   for(sd_size=0;sd_size<128;sd_size++)
   {
      if(r_buf[sd_size]!=w_buf[sd_size])
      {
           state =0;
           break;
      }
   }

   state = 1;
   return state;

}
   /**
* \brief   This function Implements read and write test capability of SD card .
*
* \param    mmcsdCtrlInfo It holds the mmcsd control information.
* \param    ptr           It determines the address from where data has to written
* \param    r_ptr         It determines the address from where data has to read
* \param    block         It determines to which block data to be written
* \param    nblks         It determines the number of blocks to be written
*
* \returns  1 - successfull written of data.
*           0 - failure to write the data.
**/
unsigned int MMCSDWriteCmdSend(mmcsdCtrlInfo *ctrl, void *ptr, void *r_ptr, unsigned int block,
                               unsigned int nblks)
{
    mmcsdCardInfo *card = ctrl->card;
    unsigned int status = 0, i=0;
    unsigned int address;
    mmcsdCmd cmd;
    unsigned char state =0;//mmc card state
    /*
     * Address is in blks for high cap cards and in actual bytes
     * for standard capacity cards
     */
    if (card->highCap)
    {
        address = block;
    }
    else//MMC card Like a low-capacity SD card 
    {
        address = block * card->blkLen;
    }

    /* Clean the data cache. */
    CacheDataCleanBuff((unsigned int) ptr, (512 * nblks));

   // ctrl->xferSetup(ctrl, 0, ptr, 512, nblks);
    /*cmd7      */
    cmd.flags = SD_CMDRSP_BUSY;
    cmd.arg = card->rca << 16;
    cmd.nblks = nblks;
    cmd.idx = SD_CMD(7);
    status = MMCSDCmdSend(ctrl, &cmd);

    //After sending the dats,SD_RSP10=0x00000700;the status here is correct,the status of mmc card is stby
    if (status == 0)
    {
        return 0;
    }

    state =(cmd.rsp[0]>>9)&0x0F;//the value of state is 3,The status of the EMMC card changes to a transmit state, so that the following instructions will make sense 
    HWREG(ctrl->memBase + MMCHS_BLK)|=0x200;//set 512 bytes block length

    if(state !=3)//cmd7 Instruction exception 
    {
        return 0;
    }

      /*cmd13   read card states   */
      cmd.flags = SD_CMDRSP_NONE;
      cmd.arg = card->rca << 16;
      cmd.idx = SD_CMD(13);
      status = MMCSDCmdSend(ctrl, &cmd);

      //After the data is sent, SD_RSP10=0x00000700; the status here is wrong, the status of the MMC card should be trans. How can the status error be corrected here? 
      if (status == 0)
      {
          return 0;
      }
    /*cmd16 Sets the length of the block */
    cmd.flags = SD_CMDRSP_NONE;
    cmd.arg = 0x200;
    cmd.idx = SD_CMD(16);
    status = MMCSDCmdSend(ctrl, &cmd);


    if (status == 0)
    {
        return 0;
    }

    state =(cmd.rsp[0]>>9)&0x0F;
    //After the data is sent, SD_RSP10=0x00000700; the status here is wrong, the status of the MMC card should be trans, currently is stdby. How to change it? 
    /*cmd24 Writes the value of a single block */
    cmd.flags = SD_CMDRSP_WRITE | SD_CMDRSP_DATA;
    cmd.arg = address;
    cmd.nblks = nblks;

    if (nblks > 1)
    {
        cmd.idx = SD_CMD(25);
        cmd.flags |= SD_CMDRSP_ABORT;
    }
    else
    {
        cmd.idx = SD_CMD(24);
    }


    status = MMCSDCmdSend(ctrl, &cmd);
    //After the data is sent, SD_RSP10 = 0x00000900; the status here is correct, and the status of the MMC card is trans ,
    if (status == 0)
    {
        return 0;
    }
//    /*cmd13   read card states   */
//    cmd.flags = SD_CMDRSP_NONE;
//    cmd.arg = card->rca << 16;
//    cmd.idx = SD_CMD(13);
//    status = MMCSDCmdSend(ctrl, &cmd);
//    //After the data is sent, SD_RSP10 = 0x00000900; the status here is incorrect and the status of the MMC card should be RCV. How to correct?
//    if (status == 0)
//    {
//        return 0;
//    }
    //write data  SD_STAT =0,Why is the status value 0? 
//    HWREG(ctrl->memBase + MMCHS_BLK)|=0x200;//set 512 bytes block length
    IntMasterIRQDisable();
    while(!((HWREG(ctrl->memBase + MMCHS_STAT) & MMCHS_STAT_TC) >>MMCHS_STAT_TC_SHIFT))
    {
        for (i = 0; i <128; i++)
        {
            if((HWREG(ctrl->memBase + MMCHS_PSTATE) &MMCHS_PSTATE_BWE)>>MMCHS_PSTATE_BWE_SHIFT)
                    HWREG(ctrl->memBase + MMCHS_DATA) = ((unsigned int*)ptr)[i]; //问题:在这里写入时,看不到Data寄存器的数据变化
            else
            {
                break;
            }
        }
//        if(i == 128)
//        {
//            break;
//        }
    }
    IntMasterIRQEnable();
//   status = ctrl->xferStatusGet(ctrl);
    if((HWREG(ctrl->memBase + MMCHS_STAT) & MMCHS_STAT_TC) >>MMCHS_STAT_TC_SHIFT)
    {
        HWREG(ctrl->memBase + MMCHS_STAT) |=1 <<MMCHS_STAT_TC_SHIFT;
    }

    /*cmd17 read the data*/
       cmd.flags = SD_CMDRSP_READ | SD_CMDRSP_DATA;
       cmd.arg = address;
       cmd.nblks = nblks;

       if (nblks > 1)
       {
           cmd.flags |= SD_CMDRSP_ABORT;
           cmd.idx = SD_CMD(18);
       }
       else
       {
           cmd.idx = SD_CMD(17);
       }

       status = MMCSDCmdSend(ctrl, &cmd);

//       while(!(HWREG(ctrl->memBase + MMCHS_STAT) & MMCHS_STAT_CC));
//
//       HWREG(ctrl->memBase + MMCHS_STAT) |=1 <<MMCHS_STAT_CC_SHIFT;//Clears the command completion flag bit 

       if (status == 0)
       {
           return 0;
       }

       IntMasterIRQDisable();
       while(!((HWREG(ctrl->memBase + MMCHS_STAT) & MMCHS_STAT_TC) >>MMCHS_STAT_TC_SHIFT))
      {
          for (i = 0; i <128; i++)
          {
              if((HWREG(ctrl->memBase + MMCHS_PSTATE) &MMCHS_PSTATE_BRE)>>MMCHS_PSTATE_BRE_SHIFT)
                  ((unsigned int*)r_ptr)[i]= HWREG(ctrl->memBase + MMCHS_DATA); //问题:这里可以读到值,所有的读取值一样,和写入的值不一样
          }

      }
      IntMasterIRQEnable();

//    if (status == 0)
//    {
//        return 0;
//    }

    /* Send a STOP */
    if (cmd.nblks > 1)
    {
        status = MMCSDStopCmdSend(ctrl);

        if (status == 0)
        {
            return 0;
        }
    }

    return 1;
}

1)  As in the above program, what should be done to correct the status bit error of the response after the command is sent?

2)  Is the code about cache required? CacheDataCleanBuff ()?

Thanks.

Best Regards,

Cherry