/** * \ingroup sd_raw * Writes raw data to the card. * * \note If write buffering is enabled, you might have to * call sd_raw_sync() before disconnecting the card * to ensure all remaining data has been written. * * \param[in] offset The offset where to start writing. * \param[in] buffer The buffer containing the data to be written. * \param[in] length The number of bytes to write. * \returns 0 on failure, 1 on success. * \see sd_raw_write_interval, sd_raw_read, sd_raw_read_interval */ uint8_t sd_raw_write(uint32_t offset, const uint8_t* buffer, uint16_t length) { #if SD_RAW_WRITE_SUPPORT if(get_pin_locked()) return 0; uint32_t block_address; uint16_t block_offset; uint16_t write_length; uint16_t i; while(length > 0) { /* determine byte count to write at once */ block_address = offset & 0xfffffe00; block_offset = offset & 0x01ff; write_length = 512 - block_offset; /* write up to block border */ if(write_length > length) write_length = length; /* Merge the data to write with the content of the block. * Use the cached block if available. */ if(block_address != raw_block_address) { #if SD_RAW_WRITE_BUFFERING if(!raw_block_written) { if(!sd_raw_write(raw_block_address, raw_block, sizeof(raw_block))) return 0; } #endif if(block_offset || write_length < 512) { if(!sd_raw_read(block_address, raw_block, sizeof(raw_block))) return 0; } raw_block_address = block_address; } if(buffer != raw_block) { memcpy(raw_block + block_offset, buffer, write_length); #if SD_RAW_WRITE_BUFFERING raw_block_written = 0; if(length == write_length) return 1; #endif } buffer += write_length; /* address card */ select_card(); /* send single block request */ if(sd_raw_send_command_r1(CMD_WRITE_SINGLE_BLOCK, block_address)) { unselect_card(); return 0; } /* send start byte */ sd_raw_send_byte(0xfe); /* write byte block */ uint8_t* cache = raw_block; for(i = 0; i < 512; ++i) sd_raw_send_byte(*cache++); /* write dummy crc16 */ sd_raw_send_byte(0xff); sd_raw_send_byte(0xff); /* wait while card is busy */ while(sd_raw_rec_byte() != 0xff); sd_raw_rec_byte(); /* deaddress card */ unselect_card(); length -= write_length; offset += write_length; #if SD_RAW_WRITE_BUFFERING raw_block_written = 1; #endif } return 1; #else return 0; #endif }
/** * \ingroup sd_raw * Writes raw data to the card. * * \note If write buffering is enabled, you might have to * call sd_raw_sync() before disconnecting the card * to ensure all remaining data has been written. * * \param[in] offset The offset where to start writing. * \param[in] buffer The buffer containing the data to be written. * \param[in] length The number of bytes to write. * \returns 0 on failure, 1 on success. * \see sd_raw_write_interval, sd_raw_read, sd_raw_read_interval */ uint8_t sd_raw_write(uint32_t offset, const uint8_t* buffer, uint16_t length) { #if SD_RAW_WRITE_SUPPORT if(get_pin_locked()) return 0; uint32_t block_address; uint16_t block_offset; uint16_t write_length; while(length > 0) { /* determine byte count to write at once */ block_address = offset & 0xfffffe00; block_offset = offset & 0x01ff; write_length = 512 - block_offset; /* write up to block border */ if(write_length > length) write_length = length; /* Merge the data to write with the content of the block. * Use the cached block if available. */ if(block_address != raw_block_address) { #if SD_RAW_WRITE_BUFFERING if(!sd_raw_sync()) return 0; #endif if(block_offset || write_length < 512) { if(!sd_raw_read(block_address, raw_block, sizeof(raw_block))) return 0; } raw_block_address = block_address; } if(buffer != raw_block) { memcpy(raw_block + block_offset, buffer, write_length); #if SD_RAW_WRITE_BUFFERING raw_block_written = 0; if(length == write_length) return 1; #endif } /* address card */ select_card(); /* send single block request */ if(sd_raw_send_command_r1(CMD_WRITE_SINGLE_BLOCK, block_address)) { unselect_card(); spi_rec_byte(); return 0; } /* send start byte */ spi_send_byte(0xfe); /* write byte block */ spi_send_data(raw_block, 512); /* write dummy crc16 */ spi_send_byte(0xff); spi_send_byte(0xff); /* wait while card is busy */ /* uint16_t i; for(i = 0; i < 0x7fff; ++i) { if(spi_rec_byte() == 0xff) break; } if(i >= 0x7fff) { unselect_card(); spi_rec_byte(); return 0; } */ // obiger code reicht bei langsamen Karten nicht aus! // daher nachfolgende alte Version mit endlos Warteschleife // Wil. while(spi_rec_byte() != 0xff); spi_rec_byte(); /* deaddress card */ unselect_card(); buffer += write_length; offset += write_length; length -= write_length; #if SD_RAW_WRITE_BUFFERING raw_block_written = 1; #endif } return 1; #else return 0; #endif }
/** * \ingroup sd_raw * Checks wether the memory card is locked for write access. * * \returns 1 if the card is locked, 0 if it is not. */ uint8_t sd_raw_locked() { return get_pin_locked() == 0x00; }
/** * \ingroup sd_raw * Checks wether the memory card is locked for write access. * * \returns 1 if the card is locked, 0 if it is not. */ uint8_t sd_raw_locked(void) { return get_pin_locked() != 0x00; }