Exemple #1
0
BYTE SD_Init(){//SD卡初始化函数,成功返回0,失败则返回非0
	BYTE i;
	BYTE cnt = 0;
	BYTE rtn = 0;	
	Port_Init();//初始化引脚
	SPI_SetSpeedLow();//SPI初始化,设定为低速
	do{
		for(i=0;i<10;i++)
			SPI_ByteRW(0xFF);
		rtn=SD_SendCommand(0,0);//发idle命令
		if((cnt++)==0xFF)
			return 1;//超时退出
	}while(rtn!=0x01);
	cnt=0;//清零重试计数器
	do{
		rtn=SD_SendCommand(1,0);//发active命令
		if((cnt++)==0xFF)
			return 2;//超时退出
	}while(rtn);
	SPI_SetSpeedHigh();//设定SPI到高速模式
	SD_SendCommand(59,0);//禁用CRC
	SD_SendCommand(16,512);//设定扇区大小为512

	return 0;//初始化成功
}
Exemple #2
0
UINT8 SD_Init(void) 
{
    _SD_PRESENT=_IN;
    
    /* Check for SD */
    if(SD_PRESENT)
        return(NO_SD_CARD);
    
    /* Initialize SPI Module */
    SPI_Init();

    
    /* Start SD card Init */
    SPI_SS=ENABLE;
    SD_CLKDelay(10);            // Send 80 clocks 
    SPI_SS=DISABLE;
  
    gu8SD_Argument.lword=0;
    SD_CLKDelay(8);  
    
    /* IDLE Command */
    
    SPI_SS=ENABLE;
    if(SD_SendCommand(SD_CMD0|0x40,SD_IDLE))
    {
        SPI_SS=DISABLE;
        return(INIT_FAILS);      
    }
    SPI_SS=DISABLE;
    
    (void)SPI_Receive_byte();  // Dummy SPI cycle
    
    /*  Initialize SD Command */
    SPI_SS=ENABLE;
    while(SD_SendCommand(SD_CMD1|0x40,SD_OK));
    SPI_SS=DISABLE;
    
    (void)SPI_Receive_byte();  // Dummy SPI cycle

    /*  Block Length */
    SPI_SS=ENABLE;
      
    gu8SD_Argument.lword=SD_BLOCK_SIZE;
    if(SD_SendCommand(SD_CMD16|0x40,SD_OK))
    {
        SPI_SS=DISABLE;
        return(INIT_FAILS);      
    }
    
    SPI_SS=DISABLE;
    
    SPI_High_rate();

    SPI_Send_byte(0x00);
    SPI_Send_byte(0x00);
    return(OK);
}
Exemple #3
0
//写入SD卡的N个block(未实际测试过)
//输入:u32 sector 扇区地址(sector值,非物理地址)
//     u8 *buffer 数据存储地址(大小至少512byte)
//     u8 count 写入的block数目
//返回值:0: 成功
//       other:失败
u8 SD_WriteMultiBlock(u32 sector, const u8 *data, u8 count)
{
    u8 r1;
    u16 i;
    //SPIx_SetSpeed(SPI_SPEED_HIGH);//设置为高速模式
    if(SD_Type != SD_TYPE_V2HC)sector = sector<<9;//如果不是SDHC,给定的是sector地址,将其转换成byte地址
    if(SD_Type != SD_TYPE_MMC) r1 = SD_SendCommand(ACMD23, count, 0x00);//如果目标卡不是MMC卡,启用ACMD23指令使能预擦除
    r1 = SD_SendCommand(CMD25, sector, 0x00);//发多块写入指令
    if(r1 != 0x00)return r1;  //应答不正确,直接返回
    SD_CS=0;//开始准备数据传输
    SPIx_ReadWriteByte(0xff);//先放3个空数据,等待SD卡准备好
    SPIx_ReadWriteByte(0xff);
    //--------下面是N个sector写入的循环部分
    do
    {
        //放起始令牌0xFC 表明是多块写入
        SPIx_ReadWriteByte(0xFC);
        //放一个sector的数据
        for(i=0; i<512; i++)
        {
            SPIx_ReadWriteByte(*data++);
        }
        //发2个Byte的dummy CRC
        SPIx_ReadWriteByte(0xff);
        SPIx_ReadWriteByte(0xff);

        //等待SD卡应答
        r1 = SPIx_ReadWriteByte(0xff);
        if((r1&0x1F)!=0x05)
        {
            SD_CS=1;    //如果应答为报错,则带错误代码直接退出
            return r1;
        }
        //等待SD卡写入完成
        if(SD_WaitDataReady()==1)
        {
            SD_CS=1;    //等待SD卡写入完成超时,直接退出报错
            return 1;
        }
    } while(--count);//本sector数据传输完成
    //发结束传输令牌0xFD
    r1 = SPIx_ReadWriteByte(0xFD);
    if(r1==0x00)
    {
        count =  0xfe;
    }
    if(SD_WaitDataReady()) //等待准备好
    {
        SD_CS=1;
        return 1;
    }
    //写入完成,片选置1
    SD_CS=1;
    SPIx_ReadWriteByte(0xff);
    return count;   //返回count值,如果写完则count=0,否则count=1
}
Exemple #4
0
/*****************************************************************************
 *
 ************* SD_Erase_Blocks ***********
 *
 *      Description: Erase multiple sectors (blocks) no the SD card.
 *
 *      Inputs:      u32SD_Start_Block - the sector (block) number of the first
 *                                 block to be erased.
 *                   u32SD_End_Block - the sector (block) number of the last
 *                                    block to be erased.
 *
 *****************************************************************************/
UINT8 SD_Erase_Blocks(UINT32 u32SD_Start_Block, UINT32 u32SD_End_Block) {
	UINT8 res;
	UINT16 u16Counter;

	SPI_SS = ENABLE;

	/* Set the address of the first write block to be erased */
	gu8SD_Argument.lword = u32SD_Start_Block; // Set ERASE_WR_BLK_START_ADDR 
											  //   command argument
	gu8SD_Argument.lword = gu8SD_Argument.lword << SD_BLOCK_SHIFT; // Convert sector number to
																   // byte address

	if (SD_SendCommand(SD_CMD32 | 0x40, SD_OK)) // ERASE_WR_BLK_START_ADDR command
			{
		SPI_SS = DISABLE;
		return (WRITE_COMMAND_FAILS);
	}

	SD_CLKDelay(1); // 8 dummy clocks

	/* Set the address of the last write block to be erased */
	gu8SD_Argument.lword = u32SD_End_Block; // Set ERASE_WR_BLK_END_ADDR 
											//   command argument
	gu8SD_Argument.lword = gu8SD_Argument.lword << SD_BLOCK_SHIFT; // Convert sector number to
																   // byte address

	if (SD_SendCommand(SD_CMD33 | 0x40, SD_OK)) // ERASE_WR_BLK_END_ADDR command
			{
		SPI_SS = DISABLE;
		return (WRITE_COMMAND_FAILS);
	}

	SD_CLKDelay(1); // 8 dummy clocks

	/* Send the erase command */
	gu8SD_Argument.lword = 0x00000000; // stuff bits 

	if (SD_SendCommand(SD_CMD38 | 0x40, SD_OK)) // ERASE command
			{
		SPI_SS = DISABLE;
		return (WRITE_COMMAND_FAILS);
	}

	/* Wait while card is busy. Indicated by reading 0x00 from SD Card */
	u16Counter = 0; // Counter to see if it is doing something
	do {
		res = SPI_Receive_byte();
		u16Counter++;
	} while (res == 0x00); // Wait while the card is busy

	SPI_SS = DISABLE;

	SD_CLKDelay(1); // 8 dummy clocks

	return (OK);
}
uint_8 SD_ReadCSD(void)
{
#ifdef MCU_MKL25Z4
    uint_8 i;
    
    SPI_set_SS();

    if(SD_SendCommand(SD_CMD9|0x40,SD_OK))
    {
        SPI_clr_SS() ;
        return(4);      
    }
    
    while(i!=0xFE)
        i=SPI_Receive_byte();
    
    for(i=0;i<16;i++)
        vSD_CSD[i]=SPI_Receive_byte();

    (void)SPI_Receive_byte();  /* Dummy SPI cycle */
    (void)SPI_Receive_byte();  /* Dummy SPI cycle */

    SPI_clr_SS() ;
    
    (void)SPI_Receive_byte();  /* Dummy SPI cycle */
    
    return(0);
#else
   uint_8 i = 0;
   /*Body*/
   if(SD_SendCommand(SD_CMD9|0x40,SD_OK))
   {
      return(4);
   }/*EndIf*/

   while(i!=0xFE)
   i=SPI_Receive_byte();

   for(i=0;i<16;i++)
   vSD_CSD[i]=SPI_Receive_byte();

   (void)SPI_Receive_byte();
   (void)SPI_Receive_byte();

   (void)SPI_Receive_byte();

   return(0);
#endif
}/*EndBody*/
Exemple #6
0
UINT8 
SD_Read_Block(UINT32 u16SD_Block,UINT8 *pu8DataPointer) 
{
    UINT8 u8Temp=0;
    UINT16 u16Counter;
    T32_8 gu8SD_Argument;

    SD_ENABLE;

    gu8SD_Argument.lword=u16SD_Block;
    gu8SD_Argument.lword=gu8SD_Argument.lword<< SD_BLOCK_SHIFT;

    if(SD_SendCommand(SD_CMD17|0x40,gu8SD_Argument,SD_OK))
    {
        SD_DISABLE;
        return(READ_COMMAND_FAILS);      
    }
    
    while(u8Temp!=0xFE)
        u8Temp=ReadSPIByte(SDhandle);
    
    for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++)
        *pu8DataPointer++=ReadSPIByte(SDhandle);

    (void)ReadSPIByte(SDhandle);  // Dummy SPI cycle
    (void)ReadSPIByte(SDhandle);  

    SD_DISABLE;

    (void)ReadSPIByte(SDhandle);  // Dummy SPI cycle
    
    return(OK);
}
Exemple #7
0
void SD_Write_Block(PTR_LBA_APP_STRUCT lba_data_ptr)
{
    /* Body */
    uint_32 u32Counter;
    SPI_set_SS();
    gu8SD_Argument.lword = lba_data_ptr->offset; 
    if(SD_SendCommand(SD_CMD24|0x40,SD_OK))
    {
        SPI_clr_SS() ;
        return;   /* Command IDLE fail */
    } /* EndIf */
    SPI_Send_byte(0xFE);
    for(u32Counter=0;u32Counter<lba_data_ptr->size;u32Counter++)  
    {
        SPI_Send_byte(*(lba_data_ptr->buff_ptr + u32Counter));
    } /* EndFor */
    SPI_Send_byte(0xFF);    /* checksum Bytes not needed */
    SPI_Send_byte(0xFF);
    if((SPI_Receive_byte() & 0x0F) != 0x05)
    {
        SPI_clr_SS() ;
        return;     /* Command fail */
    } /* EndIf */
    while(SPI_Receive_byte()==0x00)
    {
        __RESET_WATCHDOG();   /* Dummy SPI cycle */
    } /* EndWhile */
    SPI_clr_SS() ;
    return;
} /* EndBody */
Exemple #8
0
BYTE SD_WriteOneSector(DWORD sector,BYTE* buf){//写一个扇区(buf为512字节),成功返回0
	BYTE rtn;
	WORD i,cnt=0;
	SPI_SetSpeedHigh();//设定SPI到高速模式
	rtn=SD_SendCommand(24,sector<<9);//读命令
	if(rtn!=0x00)
		return rtn;
	CS_LOW();
	SPI_ByteRW(0xFF);
	SPI_ByteRW(0xFF);
	SPI_ByteRW(0xFF);
	SPI_ByteRW(0xFE);//发开始符
	for(i=0;i<512;i++){//送512字节数据
		SPI_ByteRW(*(buf++));
	}	
	SPI_ByteRW(0xFF);//dummy crc
	SPI_ByteRW(0xFF);
	rtn=SPI_ByteRW(0xFF);
	
	if((rtn & 0x1F)!=0x05){//等待是否成功
		CS_HIGH();
		return rtn;
	}
	//等待操作完
	while(!SPI_ByteRW(0xFF)){
		if((cnt++)==0xFFFF){
			CS_HIGH();
			return 1;//超时退出
		}
	}
	CS_HIGH();
	SPI_ByteRW(0xFF);//额外8个时钟周期
	return 0;
}
Exemple #9
0
void SD_Read_Block(PTR_LBA_APP_STRUCT lba_data_ptr)
{
    /* Body */
    uint_8 u8Temp=0;
    uint_32 u32Counter;
    SPI_set_SS();
    gu8SD_Argument.lword = lba_data_ptr->offset; 
    if(SD_SendCommand(SD_CMD17|0x40,SD_OK))
    {
        SPI_clr_SS() ;
        return;     /* Command IDLE fail */
    } /* EndIf */
    while(u8Temp!=0xFE)  
    {      
        u8Temp = SPI_Receive_byte(); 
    } /* EndWhile */
    for(u32Counter=0;u32Counter<lba_data_ptr->size;u32Counter++)  
    {
        *(lba_data_ptr->buff_ptr + u32Counter) = SPI_Receive_byte(); 
    } /* EndFor */
    (void)SPI_Receive_byte();  /* Dummy SPI cycle */
    (void)SPI_Receive_byte();  /* Dummy SPI cycle */
    SPI_clr_SS() ;
    (void)SPI_Receive_byte();  /* Dummy SPI cycle */
    return;
} /* EndBody */
Exemple #10
0
/*****************************************************************************
 *
 *     *** SD_Read_CSD ***
 *
 *     Read the SD Card Card-Specific Data Register (CSD).
 *
 *     The CSD is a 16 byte SD Card register that is read with the 
 *       CMD9 SEND_CSD command.
 *
 *     Output: If read successful return OK with CSD register in gu8SD_CSD[0-16]
 *                with MSB in gu8SD_CSD[0].
 *             Else return READ_COMMAND_FAILS.
 *
 *
 ******************************************************************************/
UINT8 SD_Read_CSD(void) {
	UINT8 u8Temp = 0, u8Counter;

	SPI_SS = ENABLE;

	gu8SD_Argument.lword = 0x00000000;

	if (SD_SendCommand(SD_CMD9 | 0x40, SD_OK)) {
		SPI_SS = DISABLE;
		return (READ_COMMAND_FAILS);
	}

	while (u8Temp != 0xFE)
		u8Temp = SPI_Receive_byte();

	for (u8Counter = 0; u8Counter < 16; u8Counter++)
		gu8SD_CSD[u8Counter] = SPI_Receive_byte();

	(void) ReadSPIByte(); // Dummy SPI cycle for CRC
	(void) ReadSPIByte();

	SPI_SS = DISABLE;

	SD_CLKDelay(1); // 8 dummy clocks

	return (OK);
}
Exemple #11
0
UINT8 SD_Read_Block(UINT32 u16SD_Block,UINT8 *pu8DataPointer) 
{
    UINT8 u8Temp=0;
    UINT16 u16Counter;

    SPI_SS=ENABLE;

    gu8SD_Argument.lword=u16SD_Block;
    gu8SD_Argument.lword=gu8SD_Argument.lword<< SD_BLOCK_SHIFT;

    if(SD_SendCommand(SD_CMD17|0x40,SD_OK))
    {
        SPI_SS=DISABLE;
        return(READ_COMMAND_FAILS);      
    }
    
    while(u8Temp!=0xFE)
        u8Temp=SPI_Receive_byte();
    
    for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++)
        *pu8DataPointer++=SPI_Receive_byte();

    (void)SPI_Receive_byte();  // Dummy SPI cycle
    (void)SPI_Receive_byte();  

    SPI_SS=DISABLE;

    (void)SPI_Receive_byte();  // Dummy SPI cycle
    
    return(OK);
}
Exemple #12
0
UINT8 SD_ReadSector(UINT32 u32SD_Block,UINT8 pu8DataPointer[]) {
  volatile UINT8 u8Temp = 0;

  __RESET_WATCHDOG(); /* feeds the dog */
	
  if (!gSDCard.SDHC) u32SD_Block <<= SD_BLOCK_SHIFT;
     
  SPI_SS = ENABLE;
  //Utilizo u8Temp para capturar respuesta de la tarjeta SD (fines depurativos)
  u8Temp = SD_SendCommand(SD_CMD17_READ_BLOCK, u32SD_Block, NULL, 0); 
  if((u8Temp & SD_R1_ERROR_MASK) != SD_OK) {
    SPI_SS = DISABLE;    
    return (SD_FAIL_READ);
  }
  
	while(u8Temp != 0xFE) u8Temp = SPI_ReceiveByte(); 
	//La SD responde 0xFF...0xFF mientras accede al sector y 0xFE cuando esta lista. 
	//Los datos que envía a continuación corresponden al sector solicitado. 
	
  if (SD_ReadData(pu8DataPointer,SD_BLOCK_SIZE) != SD_OK) return (SD_FAIL_READ);
  
  SPI_SS = DISABLE;
  
  return (SD_OK);
}
Exemple #13
0
void SD_Read_Block(PTR_LBA_APP_STRUCT lba_data_ptr)
{
    uint_8 u8Temp=0;
    uint_32 u32Counter;

    gu8SD_Argument.lword = lba_data_ptr->offset; 

    if(SD_SendCommand(SD_CMD17|0x40,SD_OK))
    {       
        return; // Command IDLE fail
    }
    
    while(u8Temp!=0xFE)  
    {      
        u8Temp = SPI_Receive_byte(); 
    }
    
    for(u32Counter=0;u32Counter<lba_data_ptr->size;u32Counter++)  
    {
        *(lba_data_ptr->buff_ptr + u32Counter) = SPI_Receive_byte(); 
    }
        
    (void)SPI_Receive_byte();  // Dummy SPI cycle
    (void)SPI_Receive_byte();  // Dummy SPI cycle

    (void)SPI_Receive_byte();  // Dummy SPI cycle
    
    return;
}
Exemple #14
0
//获取SD卡的CSD信息,包括容量和速度信息
//输入:u8 *cid_data(存放CID的内存,至少16Byte)
//返回值:0:NO_ERR
//       1:TIME_OUT
//       other:错误信息
u8 SD_GetCSD(u8 *csd_data)
{
    u8 r1;
    r1=SD_SendCommand(CMD9,0,0xFF);//发CMD9命令,读CSD
    if(r1)return r1;  //没返回正确应答,则退出,报错
    SD_ReceiveData(csd_data, 16, RELEASE);//接收16个字节的数据
    return 0;
}
Exemple #15
0
//获取SD卡的CID信息,包括制造商信息
//输入: u8 *cid_data(存放CID的内存,至少16Byte)
//返回值:0:NO_ERR
//		 1:TIME_OUT
//       other:错误信息
u8 SD_GetCID(u8 *cid_data)
{
    u8 r1;
    //发CMD10命令,读CID
    r1 = SD_SendCommand(CMD10,0,0xFF);
    if(r1 != 0x00)return r1;  //没返回正确应答,则退出,报错
    SD_ReceiveData(cid_data,16,RELEASE);//接收16个字节的数据
    return 0;
}
sd_result_t SD_DMA_SingleBlockRead(SD_Card *card, sd_block_t addr, SD_Data_Block *data) {
    uint8_t result;
    uint8_t args[4];
    uint16_t i=0;

    if (card->State != SD_IDLE) {
        DBG_ERR_printf("SBR failed: Card not in idle state, state is 0x%02x", card->State);
        return SD_FAILED;
    }

    if (!card->SDHC) {
        addr = addr * card->BlockSize;
    }

    args[0] = (uint8_t)((addr >> 24) & 0xff);
    args[1] = (uint8_t)((addr >> 16) & 0xff);
    args[2] = (uint8_t)((addr >> 8) & 0xff);
    args[3] = (uint8_t)((addr >> 0) & 0xff);

    SD_SPI_Open(card);
    result = SD_SendCommand(card, SD_CMD_READ_SINGLE_BLOCK, args, 0x00);
    if (result != 0x00) {
        DBG_ERR_printf("SBR failed: Bad response to READ_SINGLE_BLOCK - got 0x%02x", result);

        SD_SPI_Terminate(card);
        SD_SPI_Close(card);

        return SD_PHY_ERR;
    }

    // wait for the start block token
    result = 0xff;
    while (result != SD_TOKEN_START_BLOCK && i < SD_BLOCK_TIMEOUT) {
        result = SD_SPI_Transfer(card, SD_DUMMY_BYTE);
        i++;
    }
    if (result != SD_TOKEN_START_BLOCK) {
        DBG_ERR_printf("SBR failed: Card did not send block, got 0x%02x", result);

        SD_SPI_Terminate(card);
        SD_SPI_Close(card);

        return SD_PHY_ERR;
    }

    data->StartOffset = 2;
    data->BlockLen = 514;
    SD_DMA_ReceiveBlock(card, data);

    SD_DMA_OnBlockRead();

    card->State = SD_DMA_SBR;
    card->SubState = 0;

    return SD_BUSY;
}
Exemple #17
0
uint_8 SD_Init(void) 
{
    /* Body */
    SPI_Init();                 /* SPI Initialization */
    SPI_set_SS();
    SD_CLKDelay(10);            /* Send 80 clocks  */
    SPI_clr_SS() ;
    gu8SD_Argument.lword = 0;
    SD_CLKDelay(8);  
    /* IDLE Command */
    SPI_set_SS();
    if(SD_SendCommand(SD_CMD0|0x40,SD_IDLE))
    {
        SPI_clr_SS() ;
        return(1);          /* Command IDLE fail */
    } /* EndIf */
    SPI_clr_SS() ;
    (void)SPI_Receive_byte();   /* Dummy SPI cycle */
    /*  Initialize SD Command */
    SPI_set_SS();
    while(SD_SendCommand(SD_CMD1|0x40,SD_OK))
    {
        __RESET_WATCHDOG();
    } /* EndWhile */
    SPI_clr_SS() ;
    (void)SPI_Receive_byte();  /* Dummy SPI cycle */
    /*  Block Length */
    SPI_set_SS();
    gu8SD_Argument.lword = SD_BLOCK_SIZE;
    if(SD_SendCommand(SD_CMD16|0x40,SD_OK))
    {
        SPI_clr_SS() ;
        return(1);      /* Command IDLE fail */
    } /* EndIf */
    SPI_clr_SS() ;
    SPI_High_rate();
    SPI_Send_byte(0x00);
    SPI_Send_byte(0x00);
    return(0);
} /* EndBody */
Exemple #18
0
uint_8 SD_Init(void) 
{

    SPI_Init();             	// SPI Initialization

    SD_CLKDelay(10);            // Send 80 clocks 

    gu8SD_Argument.lword = 0;
    SD_CLKDelay(8);  
    
    /* IDLE Command */
    if(SD_SendCommand(SD_CMD0|0x40,SD_IDLE))
    {
        return(1);      		// Command IDLE fail
    }
    
    (void)SPI_Receive_byte();  	// Dummy SPI cycle
    
    /*  Initialize SD Command */
     while(SD_SendCommand(SD_CMD1|0x40,SD_OK))
    {
        Watchdog_Reset();
    }
    
    (void)SPI_Receive_byte();  // Dummy SPI cycle

    /*  Block Length */
    gu8SD_Argument.lword = SD_BLOCK_SIZE;
    if(SD_SendCommand(SD_CMD16|0x40,SD_OK))
    {       
        return(1);      // Command IDLE fail
    }
    
    SPI_High_rate();
    
    SPI_Send_byte(0x00);
    SPI_Send_byte(0x00);
    //(void)SPI_Receive_byte();  // Dummy SPI cycle
    return(0);
}
Exemple #19
0
//读SD卡的多个block(实际测试过)
//输入:u32 sector 扇区地址(sector值,非物理地址)
//     u8 *buffer 数据存储地址(大小至少512byte)
//     u8 count 连续读count个block
//返回值:0: 成功
//       other:失败
u8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count)
{
    u8 r1;
    //SPIx_SetSpeed(SPI_SPEED_HIGH);//设置为高速模式
    //如果不是SDHC,将sector地址转成byte地址
    if(SD_Type!=SD_TYPE_V2HC)sector = sector<<9;
    //SD_WaitDataReady();
    //发读多块命令
    r1 = SD_SendCommand(CMD18, sector, 0);//读命令
    if(r1 != 0x00)return r1;
    do//开始接收数据
    {
        if(SD_ReceiveData(buffer, 512, NO_RELEASE) != 0x00)break;
        buffer += 512;
    } while(--count);
    //全部传输完毕,发送停止命令
    SD_SendCommand(CMD12, 0, 0);
    //释放总线
    SD_CS=1;
    SPIx_ReadWriteByte(0xFF);
    if(count != 0)return count;   //如果没有传完,返回剩余个数
    else return 0;
}
Exemple #20
0
UINT8 SD_Write_Block(UINT32 u16SD_Block,UINT8 *pu8DataPointer) 
{
    UINT16 u16Counter;
    UINT8 SD_response;

    SPI_SS=ENABLE;

    gu8SD_Argument.lword=u16SD_Block;
    gu8SD_Argument.lword=gu8SD_Argument.lword<< SD_BLOCK_SHIFT;

    if(SD_SendCommand(SD_CMD24|0x40,SD_OK))
    {
        SPI_SS=DISABLE;
        return(WRITE_COMMAND_FAILS);      
    }
    
    WriteSPIByte(0xFE);
    
    for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++)
        WriteSPIByte(*pu8DataPointer++);

    WriteSPIByte(0xFF);    // checksum Bytes not needed
    WriteSPIByte(0xFF);

    
    /* Buggy, replaced with //--
    for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++) ;
    
    if((ReadSPIByte() & 0x0F) != 0x05)
    {
        SPI_SS=DISABLE;
        return(WRITE_DATA_FAILS);      
    }
    */

    //-- 
    SD_response=0xFF; // #001 created this variable
    while (SD_response==0xFF) SD_response=ReadSPIByte(); // #001 wait for SD response <> 0xFF
    if((SD_response & 0x0F) != 0x05)  // #001 checks if response = 0101 = data accepted
    {
        SPI_SS=DISABLE;
        return(WRITE_DATA_FAILS);    
    }
    //-- Thx to Celso Monteiro

    while(SPI_Receive_byte()==0x00) ;  // Dummy SPI cycle

    SPI_SS=DISABLE;
    return(OK);
}
Exemple #21
0
//读SD卡的一个block
//输入:u32 sector 取地址(sector值,非物理地址)
//     u8 *buffer 数据存储地址(大小至少512byte)
//返回值:0: 成功
//       other:失败
u8 SD_ReadSingleBlock(u32 sector, u8 *buffer)
{
    u8 r1;
    //设置为高速模式
    SPIx_SetSpeed(SPI_SPEED_4);
    //如果不是SDHC,给定的是sector地址,将其转换成byte地址
    if(SD_Type!=SD_TYPE_V2HC)
    {
        sector = sector<<9;
    }
    r1 = SD_SendCommand(CMD17, sector, 0);//读命令
    if(r1 != 0x00)return r1;
    r1 = SD_ReceiveData(buffer, 512, RELEASE);
    if(r1 != 0)return r1;   //读数据出错!
    else return 0;
}
Exemple #22
0
/***************************************************************************************
 *
 *     *** SD_CBufferDataSectorWrite ***
 *
 *     Description: Write a 512 bytes from the circular buffer as a data sector.
 *                  Assume:
 *                         - SD Card has been previously erased.
 *                         - Write a full sector at a time.
 *
 *     Entry: void. 
 *
 ****************************************************************************************/
void SD_CBufferDataSectorWrite(void) {
	UINT16 u16Counter;

	SPI_SS = ENABLE;

	gu8SD_Argument.lword = u32DataSector++; // Set WRITE_BLOCK command argument
											//     to the current data segment
	gu8SD_Argument.lword = gu8SD_Argument.lword << SD_BLOCK_SHIFT; // Convert sector number to
																   // byte address

	if (SD_SendCommand(SD_CMD24 | 0x40, SD_OK)) // WRITE_BLOCK command
			{
		SPI_SS = DISABLE;
		return;
	}

	WriteSPIByte(0xFE); // Start Block Token

	for (u16Counter = 0; u16Counter < BLOCK_SIZE; u16Counter++) // Write the block
		WriteSPIByte(FromCBuffer());

	WriteSPIByte(0xFF); // checksum Bytes not needed
	WriteSPIByte(0xFF);

//    for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++);

//    if((ReadSPIByte() & 0x0F) != 0x05)                // Read the status token.
	// Correct response is 0x05
	// Foust p5.
	while ((SPI_Receive_byte() & 0x0F) != 0x05)
		;
//    {
//        SPI_SS=DISABLE;
//        return;      
//    }

	while (SPI_Receive_byte() == 0x00)
		; // Wait while the card is busy

	SPI_SS = DISABLE;

	SD_CLKDelay(1); // 8 dummy clocks

	return;

}
Exemple #23
0
BYTE ReadBegin(DWORD sector){//读数据前的初始化
	BYTE rtn;
	WORD cnt=0;
	SPI_SetSpeedHigh();//设定SPI到高速模式
	rtn = SD_SendCommand(17,sector<<9);//读命令
	if(rtn!=0x00)
		return 1;
	CS_LOW();
	//等数据的开始
	while(SPI_ByteRW(0xFF)!=0xFE){
		if((cnt++)==0xFFFF){
			CS_HIGH();
			return 2;//超时退出
		}
	}
	return 0;
}
Exemple #24
0
UINT8 
SD_Write_Block(UINT32 u16SD_Block,UINT8 *pu8DataPointer) 
{
    UINT16 u16Counter;
    T32_8 gu8SD_Argument;
    
    /* Check for Write Protection */
    if(SD_PROTECTED)
        return(WRITE_PROTECTED);
    
    
    SD_ENABLE;

    gu8SD_Argument.lword=u16SD_Block;
    gu8SD_Argument.lword=gu8SD_Argument.lword<< SD_BLOCK_SHIFT;

    if(SD_SendCommand(SD_CMD24|0x40,gu8SD_Argument,SD_OK))
    {
        SD_DISABLE;
        return(WRITE_COMMAND_FAILS);      
    }
    
    WriteSPIByte(SDhandle,0xFE);
    
    for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++)
        WriteSPIByte(SDhandle,*pu8DataPointer++);

    WriteSPIByte(SDhandle,0xFF);    // checksum Bytes not needed
    WriteSPIByte(SDhandle,0xFF);

    for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++)
    ;
    
    if((ReadSPIByte(SDhandle) & 0x0F) != 0x05)
    {
        SD_DISABLE;
        return(WRITE_DATA_FAILS);      
    }

    while(ReadSPIByte(SDhandle)==0x00)
    ;  // Dummy SPI cycle

    SD_DISABLE;
    return(OK);
}
Exemple #25
0
// Read a 512 bytes sector on the SD Card
//  uiSector : Sector number
//  pbyReadData : pointer to a 512 bytes buffer that will be filled with secotr data if successful
// return : true if data read successully, false otherwise
int SD_Read(UINT32 uiSector, UINT8* pbyReadData)
{
    int bSuccess = 1;
    UINT32 uiAddress = uiSector * 512;
    
    SD_Ncc();
    // Send single read command
    SD_SendCommand(17, uiAddress);
    UINT8 uiResponse = SD_GetR1Response();
    if (uiResponse != 0)
    {
        printf("SD Card read data failed. Error code : %02X\n", uiResponse);
        return 0;
    }
    
    // Wait for data token
    UINT8 uiDataToken = 0;
    int iNbTry = 0;
    while (uiDataToken != 0xFE && iNbTry < 2000)
    {
        uiDataToken = SD_ReadByte();
        iNbTry++;
    }
    
    if (uiDataToken != 0xFE)
    {
        printf("SD Card read data timeout. Error code : %02X\n", uiDataToken);
        return 0;
    }
     
    // Read sector
    int i;
    for (i = 0; i < 512; i++)
    {
        pbyReadData[i] = SD_ReadByte();
    }
    
    // Dummy read CRC
    SD_ReadByte();
    SD_ReadByte();
    
    return bSuccess;
}
Exemple #26
0
/*****************************************************************************
 *
 **************SD_Write_Block************
 *
 *      Description: Write a 512 byte sector (block) to the SD card.
 *
 *      Inputs:      u16SD_Block - the sector (block) number where the block is
 *                                 to be written.
 *                   pu8DataPointer - the 512 byte buffer that is to be written
 *                                    to the SD card.
 *
 *****************************************************************************/
UINT8 SD_Write_Block(UINT32 u16SD_Block, UINT8 *pu8DataPointer) {
	UINT16 u16Counter;

	SPI_SS = ENABLE;

	gu8SD_Argument.lword = u16SD_Block; // Set WRITE_BLOCK command argument
	gu8SD_Argument.lword = gu8SD_Argument.lword << SD_BLOCK_SHIFT; // Convert sector number to
																   // byte address

	if (SD_SendCommand(SD_CMD24 | 0x40, SD_OK)) // WRITE_BLOCK command
			{
		SPI_SS = DISABLE;
		return (WRITE_COMMAND_FAILS);
	}

	WriteSPIByte(0xFE); // Start Block Token

	for (u16Counter = 0; u16Counter < BLOCK_SIZE; u16Counter++) // Write the block
		WriteSPIByte(*pu8DataPointer++);

	WriteSPIByte(0xFF); // checksum Bytes not needed
	WriteSPIByte(0xFF);

	for (u16Counter = 0; u16Counter < BLOCK_SIZE; u16Counter++)
		;

	if ((ReadSPIByte() & 0x0F) != 0x05) // Read the status token.
										// Correct response is 0x05
										// Foust p5.
			{
		SPI_SS = DISABLE;
		return (WRITE_DATA_FAILS);
	}

	while (SPI_Receive_byte() == 0x00)
		; // Wait while the card is busy

	SPI_SS = DISABLE;

	SD_CLKDelay(1); // 8 dummy clocks

	return (OK);
}
Exemple #27
0
//在指定扇区,从offset开始读出bytes个字节
//输入:u32 sector 扇区地址(sector值,非物理地址)
//     u8 *buf     数据存储地址(大小<=512byte)
//     u16 offset  在扇区里面的偏移量
//     u16 bytes   要读出的字节数
//返回值:0: 成功
//       other:失败
u8 SD_Read_Bytes(unsigned long address,unsigned char *buf,unsigned int offset,unsigned int bytes)
{
    u8 r1;
    u16 i=0;
    r1=SD_SendCommand(CMD17,address<<9,0);//发送读扇区命令
    if(r1)return r1;  //应答不正确,直接返回
    SD_CS=0;//选中SD卡
    if(SD_GetResponse(0xFE))//等待SD卡发回数据起始令牌0xFE
    {
        SD_CS=1; //关闭SD卡
        return 1;//读取失败
    }
    for(i=0; i<offset; i++)SPIx_ReadWriteByte(0xff); //跳过offset位
    for(; i<offset+bytes; i++)*buf++=SPIx_ReadWriteByte(0xff); //读取有用数据
    for(; i<512; i++) SPIx_ReadWriteByte(0xff); 	 //读出剩余字节
    SPIx_ReadWriteByte(0xff);//发送伪CRC码
    SPIx_ReadWriteByte(0xff);
    SD_CS=1;//关闭SD卡
    return 0;
}
Exemple #28
0
void SD_Write_Block(PTR_LBA_APP_STRUCT lba_data_ptr)
{
    uint_32 u32Counter;

    gu8SD_Argument.lword = lba_data_ptr->offset; 

    
    
    while(SPI_Receive_byte()==0x00)
    {
        Watchdog_Reset();
    }    
    
    if(SD_SendCommand(SD_CMD24|0x40,SD_OK))
    {
        return;   // Command IDLE fail
    }
    
    SPI_Send_byte(0xFE);
    
    for(u32Counter=0;u32Counter<lba_data_ptr->size;u32Counter++)  
    {
        SPI_Send_byte(*(lba_data_ptr->buff_ptr + u32Counter));
    }

    SPI_Send_byte(0xFF);    // checksum Bytes not needed
    SPI_Send_byte(0xFF);

    
    if((SPI_Receive_byte() & 0x0F) != 0x05)
    {       
    //    return;     // Command fail
    }

    while(SPI_Receive_byte()==0x00)
    {
        Watchdog_Reset();
    }      // Dummy SPI cycle
       	
    return;
}
Exemple #29
0
//把SD卡设置到挂起模式
//返回值:0,成功设置
//       1,设置失败
u8 SD_Idle_Sta(void)
{
    u16 i;
    u8 retry;
    for(i=0; i<0xf00; i++); //纯延时,等待SD卡上电完成
    //先产生>74个脉冲,让SD卡自己初始化完成
    for(i=0; i<10; i++)SPIx_ReadWriteByte(0xFF);
    //-----------------SD卡复位到idle开始-----------------
    //循环连续发送CMD0,直到SD卡返回0x01,进入IDLE状态
    //超时则直接退出
    retry = 0;
    do
    {
        //发送CMD0,让SD卡进入IDLE状态
        i = SD_SendCommand(CMD0, 0, 0x95);
        retry++;
    } while((i!=0x01)&&(retry<200));
    //跳出循环后,检查原因:初始化成功?or 重试超时?
    if(retry==200)return 1; //失败
    return 0;//成功
}
Exemple #30
0
uint_8 SD_ReadCSD(void)
{
    uint_8 i;
    
    /*Body*/
    if(SD_SendCommand(SD_CMD9|0x40,SD_OK))
    {
        return(4);
    }
    
    while(i!=0xFE)
        i=SPI_Receive_byte();
    
    for(i=0;i<16;i++)
        vSD_CSD[i]=SPI_Receive_byte();

    (void)SPI_Receive_byte();
    (void)SPI_Receive_byte();
    (void)SPI_Receive_byte();
    
    return(0);
}/*EndBody*/