/** * @brief Writes block(s) to a specified address in an SD card, in polling mode. * @param pData: Pointer to the buffer that will contain the data to transmit * @param WriteAddr: Address from where data is to be written * @param BlockSize: SD card data block size, that should be 512 * @param NumOfBlocks: Number of SD blocks to write * @retval SD status */ uint8_t BSP_SD_WriteBlocks(uint32_t* p32Data, uint64_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks) { uint32_t counter = 0, offset = 0; uint8_t rvalue = MSD_ERROR; uint8_t *pData = (uint8_t *)p32Data; /* Data transfer */ while (NumberOfBlocks--) { /* Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write blocks and Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */ if (SD_IO_WriteCmd(SD_CMD_WRITE_SINGLE_BLOCK, WriteAddr + offset, 0xFF, SD_RESPONSE_NO_ERROR) != HAL_OK) { return MSD_ERROR; } /* Send dummy byte */ SD_IO_WriteByte(SD_DUMMY_BYTE); /* Send the data token to signify the start of the data */ SD_IO_WriteByte(SD_START_DATA_SINGLE_BLOCK_WRITE); /* Write the block data to SD : write count data by block */ for (counter = 0; counter < BlockSize; counter++) { /* Send the pointed byte */ SD_IO_WriteByte(*pData); /* Point to the next location where the byte read will be saved */ pData++; } /* Set next write address */ offset += BlockSize; /* Put CRC bytes (not really needed by us, but required by SD) */ SD_IO_ReadByte(); SD_IO_ReadByte(); /* Read data response */ if (SD_GetDataResponse() == SD_DATA_OK) { /* Set response value to success */ rvalue = MSD_OK; } else { /* Set response value to failure */ rvalue = MSD_ERROR; } } /* Send dummy byte: 8 Clock pulses of delay */ SD_IO_WriteDummy(); /* Returns the reponse */ return rvalue; }
/** * @brief Write a buffer (many blocks) in the SD card. * @note The amount of data to write should be a multiple of SD card BLOCK * size (512 Byte). * @param pBuffer : pointer to the buffer containing the data to be written on the SD. * @param WriteAddr : address to write on. * @param NumByteToWrite : number of data to write. * @retval SD Response: * - SD_RESPONSE_FAILURE: Sequence failed. * - SD_RESPONSE_NO_ERROR: Sequence succeed. */ uint8_t SD_WriteBuffer(uint8_t *pBuffer, uint32_t WriteAddr, uint32_t NumByteToWrite) { uint32_t i = 0, NbrOfBlock = 0, Offset = 0; uint8_t rvalue = SD_RESPONSE_FAILURE; /* Calculate number of blocks to write */ NbrOfBlock = NumByteToWrite / SD_BLOCK_SIZE; /* SD chip select low */ SD_CS_LOW(); /* Data transfer */ while (NbrOfBlock--) { /* Send CMD24 (SD_WRITE_BLOCK) to write blocks */ SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, WriteAddr + Offset, 0xFF); /* Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */ if (SD_GetResponse(SD_RESPONSE_NO_ERROR)) { return SD_RESPONSE_FAILURE; } /* Send dummy byte */ SD_WriteByte(SD_DUMMY_BYTE); /* Send the data token to signify the start of the data */ SD_WriteByte(SD_START_DATA_SINGLE_BLOCK_WRITE); /* Write the block data to SD : write count data by block */ for (i = 0; i < SD_BLOCK_SIZE; i++) { /* Send the pointed byte */ SD_WriteByte(*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 SD) */ SD_ReadByte(); SD_ReadByte(); /* Read data response */ if (SD_GetDataResponse() == SD_DATA_OK) { /* Set response value to success */ rvalue = SD_RESPONSE_NO_ERROR; } else { /* Set response value to failure */ rvalue = SD_RESPONSE_FAILURE; } } /* SD chip select high */ SD_CS_HIGH(); /* Send dummy byte: 8 Clock pulses of delay */ SD_WriteByte(SD_DUMMY_BYTE); /* Returns the response */ return rvalue; }
/** * @brief Writes a block on the SD * @param pBuffer: pointer to the buffer containing the data to be written on * the SD. * @param WriteAddr: address to write on. * @param BlockSize: the SD card Data block size. * @retval The SD Response: * - SD_RESPONSE_FAILURE: Sequence failed * - SD_RESPONSE_NO_ERROR: Sequence succeed */ uint8_t SD_WriteBlock(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t BlockSize) { uint32_t i = 0; uint8_t rvalue = SD_RESPONSE_FAILURE; /*!< SD chip select low */ SD_CS_LOW(); /*!< Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write multiple block */ SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, WriteAddr, 0xFF); /*!< Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */ if (!SD_GetResponse(SD_RESPONSE_NO_ERROR)) { /*!< Send a dummy byte */ SD_WriteByte(SD_DUMMY_BYTE); /*!< Send the data token to signify the start of the data */ SD_WriteByte(0xFE); /*!< Write the block data to SD : write count data by block */ for (i = 0; i < BlockSize; i++) { /*!< Send the pointed byte */ SD_WriteByte(*pBuffer); /*!< Point to the next location where the byte read will be saved */ pBuffer++; } /* Send DUMMY bytes when the number of data to be written are lower than the SD card BLOCK size (512 Byte) */ for (; i != SD_BLOCK_SIZE; i++) { /* Send the pointed byte */ SD_WriteByte(SD_DUMMY_BYTE); } /*!< Put CRC bytes (not really needed by us, but required by SD) */ SD_ReadByte(); SD_ReadByte(); /*!< Read data response */ if (SD_GetDataResponse() == SD_DATA_OK) { rvalue = SD_RESPONSE_NO_ERROR; } } /*!< SD chip select high */ SD_CS_HIGH(); /*!< Send dummy byte: 8 Clock pulses of delay */ SD_WriteByte(SD_DUMMY_BYTE); /*!< Returns the response */ return rvalue; }
/** * @brief Writes many blocks on the SD * @param pBuffer: pointer to the buffer containing the data to be written on * the SD. * @param WriteAddr: address to write on. * @param BlockSize: the SD card Data block size. * @param NumberOfBlocks: number of blocks to be written. * @retval The SD Response: * - SD_RESPONSE_FAILURE: Sequence failed * - SD_RESPONSE_NO_ERROR: Sequence succeed */ SD_Error SD_WriteMultiBlocks(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks) { uint32_t i = 0, Offset = 0; SD_Error rvalue = SD_RESPONSE_FAILURE; /*!< SD chip select low */ SD_CS_LOW(); /*!< Data transfer */ while (NumberOfBlocks--) { if(flag_SDHC == 1) { /* Send CMD24 (MSD_WRITE_BLOCK) to write blocks */ SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, (WriteAddr + Offset)/512, 0xFF); } else { /*!< Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write blocks */ SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, WriteAddr + Offset, 0xFF); } /*!< Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */ if (SD_GetResponse(SD_RESPONSE_NO_ERROR)) { return SD_RESPONSE_FAILURE; } /*!< Send dummy byte */ SD_WriteByte(SD_DUMMY_BYTE); /*!< Send the data token to signify the start of the data */ SD_WriteByte(SD_START_DATA_SINGLE_BLOCK_WRITE); /*!< Write the block data to SD : write count data by block */ for (i = 0; i < BlockSize; i++) { /*!< Send the pointed byte */ SD_WriteByte(*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 SD) */ SD_ReadByte(); SD_ReadByte(); /*!< Read data response */ if (SD_GetDataResponse() == SD_DATA_OK) { /*!< Set response value to success */ rvalue = SD_RESPONSE_NO_ERROR; } else { /*!< Set response value to failure */ rvalue = SD_RESPONSE_FAILURE; } } /*!< SD chip select high */ SD_CS_HIGH(); /*!< Send dummy byte: 8 Clock pulses of delay */ SD_WriteByte(SD_DUMMY_BYTE); /*!< Returns the reponse */ return rvalue; }