u8 MSD_WriteBuffer(u8* pBuffer, u32 WriteAddr, u32 NumByteToWrite) { u32 i = 0, NbrOfBlock = 0, Offset = 0; u8 rvalue = MSD_RESPONSE_FAILURE; /* Calculate number of blocks to write */ NbrOfBlock = NumByteToWrite / BLOCK_SIZE; /* MSD chip select low */ spi_ss(_FLASH_NUM0,0); /* Data transfer */ while (NbrOfBlock --) { /* Send CMD24 (MSD_WRITE_BLOCK) to write blocks */ MSD_SendCmd(MSD_WRITE_BLOCK, WriteAddr + Offset, 0xFF); /* Check if the MSD acknowledged the write block command: R1 response (0x00: no errors) */ if (MSD_GetResponse(MSD_RESPONSE_NO_ERROR)) { return MSD_RESPONSE_FAILURE; } /* Send dummy byte */ spi_send(DUMMY); /* Send the data token to signify the start of the data */ spi_send(MSD_START_DATA_SINGLE_BLOCK_WRITE); /* Write the block data to MSD : write count data by block */ for (i = 0; i < BLOCK_SIZE; i++) { /* Send the pointed byte */ spi_send(*pBuffer); /* Point to the next location where the byte read will be saved */ pBuffer++; } /* Set next write address */ Offset += 512; /* Put CRC bytes (not really needed by us, but required by MSD) */ spi_send(DUMMY); spi_send(DUMMY); /* Read data response */ if (MSD_GetDataResponse() == MSD_DATA_OK) { /* Set response value to success */ rvalue = MSD_RESPONSE_NO_ERROR; } else { /* Set response value to failure */ rvalue = MSD_RESPONSE_FAILURE; } } /* MSD chip select high */ spi_ss(_FLASH_NUM0,1); /* Send dummy byte: 8 Clock pulses of delay */ spi_send(DUMMY); /* Returns the reponse */ return rvalue; }
/******************************************************************************* MicroSD Write a Block return: 0x00=success *******************************************************************************/ u8 MSD_WriteBlock(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite) { u32 i=0; u8 rvalue = MSD_RESPONSE_FAILURE; mutex++; while (mutex > 1); MSD_CS_LOW(); Delay_us(); MSD_SendCmd(MSD_WRITE_BLOCK, WriteAddr, 0xFF);//Send CMD24 if(!MSD_GetResponse(MSD_RESPONSE_NO_ERROR)){ MSD_WriteByte(DUMMY); //Send dummy byte: 8 Clock pulses of delay MSD_WriteByte(0xFE); for(i=0; i<NumByteToWrite; i++) { MSD_WriteByte(*pBuffer); pBuffer++; } MSD_ReadByte(); MSD_ReadByte(); //DUMMY CRC bytes if(MSD_GetDataResponse()==MSD_DATA_OK) rvalue=MSD_RESPONSE_NO_ERROR; } MSD_CS_HIGH(); MSD_WriteByte(DUMMY); //Send dummy byte: 8 Clock pulses of delay mutex--; return rvalue; }
/******************************************************************************* * Function Name : MSD_WriteBlock * Description : Writes a block on the MSD * Input : - pBuffer : pointer to the buffer containing the data to be * written on the MSD. * - WriteAddr : address to write on. * - NumByteToWrite: number of data to write * Output : None * Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed * - MSD_RESPONSE_NO_ERROR: Sequence succeed *******************************************************************************/ u8 MSD_WriteBlock(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite) { u32 i = 0; u8 rvalue = MSD_RESPONSE_FAILURE; return 0; /* MSD chip select low */ spi_ss(_FLASH_NUM0,0); /* Send CMD24 (MSD_WRITE_BLOCK) to write multiple block */ MSD_SendCmd(MSD_WRITE_BLOCK, WriteAddr, 0xFF); /* Check if the MSD acknowledged the write block command: R1 response (0x00: no errors) */ if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR)) { /* Send a dummy byte */ spi_send(DUMMY); /* Send the data token to signify the start of the data */ spi_send(0xFE); /* Write the block data to MSD : write count data by block */ for (i = 0; i < NumByteToWrite; i++) { /* Send the pointed byte */ spi_send(*pBuffer); /* Point to the next location where the byte read will be saved */ pBuffer++; } /* Put CRC bytes (not really needed by us, but required by MSD) */ spi_send(DUMMY); spi_send(DUMMY); /* Read data response */ if (MSD_GetDataResponse() == MSD_DATA_OK) { rvalue = MSD_RESPONSE_NO_ERROR; } } /* MSD chip select high */ spi_ss(_FLASH_NUM0,1); /* Send dummy byte: 8 Clock pulses of delay */ spi_send(DUMMY); /* Returns the reponse */ return rvalue; }
/************************************************************************************ * Function Name : MSD_WriteMultipleBlock_DMA(uint32_t sector, uc8 *buffer,u16 NumByteToWrite) * Description : None * Input : - sector: * - buffer: * Output : None * Return : None * Attention : None ************************************************************************************/ int MSD_WriteMultipleBlock_DMA(uint32_t sector, uc8 *buffer, u8 NbrOfSector, u16 NumByteToWrite) { uint8 r1; // uint16_t i=0; uint32_t retry; u8 value = 0; // INT8U err; u8 rvalue = MSD_RESPONSE_FAILURE; DMA_InitTypeDef DMA_InitStructure; //定义DMA初始化结构体 /*begin:yangfei added 2012.11.29*/ // debug("MSD_WriteMultipleBlock_DMA\r\n"); _card_enable(); DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = NumByteToWrite; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel5, &DMA_InitStructure); /* Enable DMA1 Channel5 Transfer Complete interrupt */ DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); /*end:yangfei added 2012.11.29*/ //SPI_DMA_Send_Init(buffer,MSD_BLOCKSIZE); /* if ver = SD2.0 HC, sector need <<9 */ if(CardInfo.CardType != CARDTYPE_SDV2HC) { sector = sector << 9; } if(CardInfo.CardType != CARDTYPE_MMC) { _send_command(ACMD23, NbrOfSector, 0); } /* Send CMD25 : Write multiple block command */ MSD_SendCmd(CMD25, sector, 0xff); //_spi_read_write(DUMMY_BYTE); //_spi_read_write(DUMMY_BYTE); if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR)) { _spi_read_write(DUMMY_BYTE); /* Start data write token: 0xFE */ _spi_read_write(0xFC); /*begin:yangfei added 2012.11.28*/ DMA_Cmd(DMA1_Channel5, ENABLE); #ifdef DMA1_IRQ OSFlagPend(Sem_SD_DMA, (OS_FLAGS)1, OS_FLAG_WAIT_SET_ALL, 0, &err); //请求信号量集的第0位置1 DMA_ClearFlag(DMA1_FLAG_TC5); #else while(!DMA_GetFlagStatus(DMA1_FLAG_TC5)) ; DMA_ClearFlag(DMA1_FLAG_TC5); #endif /* 2Bytes dummy CRC */ _spi_read_write(DUMMY_BYTE); _spi_read_write(DUMMY_BYTE); value = MSD_GetDataResponse(); if (value == MSD_DATA_OK) { rvalue = MSD_RESPONSE_NO_ERROR; } // debug("value=%x\r\n",value); } /* Send end of transmit token: 0xFD */ r1 = _spi_read_write(0xFD); if(r1 == 0x00) { return 4; } /*begin:yangfei added 2012.12.07 for wait programm finished else write error*/ /* Wait all the data programm finished */ retry = 0; while(_spi_read_write(DUMMY_BYTE) == 0x00) { /* Timeout return */ if(retry++ == 0x40000) { _card_disable(); return 3; } } /* chip disable and dummy byte */ _card_disable(); _spi_read_write(DUMMY_BYTE); /*yangfei added*/ DMA_Cmd(DMA1_Channel5, DISABLE); return rvalue; }