SdErrorCode initCard() { if (!sd_raw_init()) { if (!sd_raw_available()) { reset(); return SD_ERR_NO_CARD_PRESENT; } else { reset(); return SD_ERR_INIT_FAILED; } } else if (!openPartition()) { reset(); return SD_ERR_PARTITION_READ; } else if (!openFilesys()) { reset(); return SD_ERR_OPEN_FILESYSTEM; } else if (!openRoot()) { reset(); return SD_ERR_NO_ROOT; /* we need to keep locked as the last check */ } else if (sd_raw_locked()) { return SD_ERR_CARD_LOCKED; } return SD_SUCCESS; }
uint8_t sd_write_block(unsigned long block_address, unsigned char buffer[512]) { //unsigned int block_offset = (block_address*512) & 0x01FF; //block_address = (block_address*512) - block_offset; block_address *= 512; if(sd_raw_locked()) return 0; /* address card */ select_card(); /* send single block request */ #if SD_RAW_SDHC if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address))) #else if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, block_address)) #endif { unselect_card(); return 0; } /* send start byte */ sd_raw_send_byte(0xfe); /* write byte block */ uint16_t i; for(i = 0; i < 512; i++) sd_raw_send_byte(buffer[i]); /* 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(); return 1; }
uint8_t sd_read_block(unsigned long block_address, unsigned char buffer[512]) { //unsigned int block_offset = (block_address*512) & 0x01FF; //block_address = (block_address*512) - block_offset; block_address *= 512; if(sd_raw_locked()) return 0; /* address card */ select_card(); /* send single block request */ #if SD_RAW_SDHC if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address))) #else if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, block_address)) #endif { unselect_card(); return 0; } /* wait for data block (start byte 0xfe) */ while(sd_raw_rec_byte() != 0xfe); /* read byte block */ uint16_t i; for(i = 0; i < 512; i++) buffer[i] = sd_raw_rec_byte(); /* read crc16 */ sd_raw_rec_byte(); sd_raw_rec_byte(); /* deaddress card */ unselect_card(); /* let card some time to finish */ sd_raw_rec_byte(); return 1; }
/** * \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(offset_t offset, const uint8_t* buffer, uintptr_t length) { if(sd_raw_locked()) return 0; offset_t block_address; uint16_t block_offset; uint16_t write_length; while(length > 0) { /* determine byte count to write at once */ block_offset = offset & 0x01ff; block_address = offset - block_offset; 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_SDHC if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address))) #else if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, block_address)) #endif { unselect_card(); return 0; } /* send start byte */ sd_raw_send_byte(0xfe); /* write byte block */ uint8_t* cache = raw_block; for(uint16_t 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(); buffer += write_length; offset += write_length; length -= write_length; #if SD_RAW_WRITE_BUFFERING raw_block_written = 1; #endif } return 1; }
bool RepRapSDCard::isLocked(void) { return sd_raw_locked() == 1; }