Пример #1
0
void File::close(void)
{
	fat_close_file(_fd);
#if SD_RAW_WRITE_SUPPORT
	sd_raw_sync();
#endif
}
Пример #2
0
void SDCardFile::close() {
  if (fd != NULL) {
    fat_close_file(fd);
    sd_raw_sync();
    fd = NULL;
  }
}
Пример #3
0
void FAT::write(const char * data)
{
	//Always write to the end of the file.
	fat_seek_file(_file_handle, 0, FAT_SEEK_END);
	fat_write_file(_file_handle, (uint8_t *)data, strlen(data));
	sd_raw_sync();
}
Пример #4
0
uint8_t closeFile(struct fat_file_struct* fd){
	fat_close_file(fd);
	if (!sd_raw_sync()){
		printf_P(PSTR("failed to sync file\r\n"));
		return 0;
	}
	return 1;
}
Пример #5
0
bool FatFsClass::createFile(const char * file_name)
{
	struct fat_dir_entry_struct directory;
	if(fat_create_file(_dd, file_name, &directory)){
		sd_raw_sync();
		return true;
	}
	return false;
}
Пример #6
0
bool FatFsClass::deleteFile(const char * file_name)
{
 	struct fat_dir_entry_struct directory;
	if(find_file_in_dir(file_name, &directory)){
		if(fat_delete_file(_fs, &directory)){
			sd_raw_sync();
			return true;
		}
	}
	return false;
}
Пример #7
0
bool SDCardEntry::createSubDirectory(const char *path, struct fat_dir_entry_struct *new_entry) {
  if (path[0] == '/')
    path++;

  fat_dir_struct *dd = fat_open_dir(SDCard.fs, &dir_entry);
  if (dd == NULL)
    return false;
  
  char subDir[64];
  while (1) {
    const char *pos = strchr(path, '/');
    if (pos == NULL) {
      m_strncpy(subDir, path, sizeof(subDir) - 1);
    } else {
      int len = pos - path;
      memcpy(subDir, path, len);
      subDir[len] = '\0';
      path = pos + 1;
    }
    
    struct fat_dir_entry_struct new_dir_entry;
    
    int result = fat_create_dir(dd, subDir, &new_dir_entry);

    if (result == 0 && strcmp(subDir, new_dir_entry.long_name)) {
      fat_close_dir(dd);
      return false;
    } else {
      memcpy(new_entry, &new_dir_entry, sizeof(new_dir_entry));
      fat_close_dir(dd);
      dd = fat_open_dir(SDCard.fs, &new_dir_entry);

      if (dd == NULL) {
	return false;
      } else {
	if (pos == NULL) {
	  sd_raw_sync();
	  fat_close_dir(dd);
	  return true;
	}
      }
    }
  }
}
Пример #8
0
/**
 * \ingroup sd_raw
 * Reads raw data from the card.
 *
 * \param[in] offset The offset from which to read.
 * \param[out] buffer The buffer into which to write the data.
 * \param[in] length The number of bytes to read.
 * \returns 0 on failure, 1 on success.
 * \see sd_raw_read_interval, sd_raw_write, sd_raw_write_interval
 */
uint8_t sd_raw_read(offset_t offset, uint8_t* buffer, uintptr_t length)
{
    offset_t block_address;
    uint16_t block_offset;
    uint16_t read_length;
    while(length > 0)
    {
        /* determine byte count to read at once */
        block_offset = offset & 0x01ff;
        block_address = offset - block_offset;
        read_length = 512 - block_offset; /* read up to block border */
        if(read_length > length)
            read_length = length;
        
#if !SD_RAW_SAVE_RAM
        /* check if the requested data is cached */
        if(block_address != raw_block_address)
#endif
        {
#if SD_RAW_WRITE_BUFFERING
            if(!sd_raw_sync())
                return 0;
#endif

            /* 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);

#if SD_RAW_SAVE_RAM
            /* read byte block */
            uint16_t read_to = block_offset + read_length;
            for(uint16_t i = 0; i < 512; ++i)
            {
                uint8_t b = sd_raw_rec_byte();
                if(i >= block_offset && i < read_to)
                    *buffer++ = b;
            }
#else
            /* read byte block */
            uint8_t* cache = raw_block;
            for(uint16_t i = 0; i < 512; ++i)
                *cache++ = sd_raw_rec_byte();
            raw_block_address = block_address;

            memcpy(buffer, raw_block + block_offset, read_length);
            buffer += read_length;
#endif
            
            /* read crc16 */
            sd_raw_rec_byte();
            sd_raw_rec_byte();
            
            /* deaddress card */
            unselect_card();

            /* let card some time to finish */
            sd_raw_rec_byte();
        }
#if !SD_RAW_SAVE_RAM
        else
        {
            /* use cached data */
            memcpy(buffer, raw_block + block_offset, read_length);
            buffer += read_length;
        }
#endif

        length -= read_length;
        offset += read_length;
    }

    return 1;
}
Пример #9
0
int main()
{
    /* we will just use ordinary idle mode */
    set_sleep_mode(SLEEP_MODE_IDLE);

    /* setup uart */
    uart_init();

    while(1)
    {


        /* setup sd card slot */
        if(!sd_raw_init())
        {
#if DEBUG
            uart_puts_p(PSTR("MMC/SD initialization failed\n"));
#endif
            continue;
        }

        /* open first partition */
        struct partition_struct* partition = partition_open(sd_raw_read,
                                                            sd_raw_read_interval,
#if SD_RAW_WRITE_SUPPORT
                                                            sd_raw_write,
                                                            sd_raw_write_interval,
#else
                                                            0,
                                                            0,
#endif
                                                            0
                                                           );

        if(!partition)
        {
            /* If the partition did not open, assume the storage device
             * is a "superfloppy", i.e. has no MBR.
             */
            partition = partition_open(sd_raw_read,
                                       sd_raw_read_interval,
#if SD_RAW_WRITE_SUPPORT
                                       sd_raw_write,
                                       sd_raw_write_interval,
#else
                                       0,
                                       0,
#endif
                                       -1
                                      );
            if(!partition)
            {
#if DEBUG
                uart_puts_p(PSTR("opening partition failed\n"));
#endif
                continue;
            }
        }

        /* open file system */
        struct fat_fs_struct* fs = fat_open(partition);
        if(!fs)
        {
#if DEBUG
            uart_puts_p(PSTR("opening filesystem failed\n"));
#endif
            continue;
        }

        /* open root directory */
        struct fat_dir_entry_struct directory;
        fat_get_dir_entry_of_path(fs, "/", &directory);

        struct fat_dir_struct* dd = fat_open_dir(fs, &directory);
        if(!dd)
        {
#if DEBUG
            uart_puts_p(PSTR("opening root directory failed\n"));
#endif
            continue;
        }

        /* print some card information as a boot message */
        print_disk_info(fs);

        /* provide a simple shell */
        char buffer[24];
        while(1)
        {
            /* print prompt */
            uart_putc('>');
            uart_putc(' ');

            /* read command */
            char* command = buffer;
            if(read_line(command, sizeof(buffer)) < 1)
                continue;

            /* execute command */
            if(strcmp_P(command, PSTR("init")) == 0)
            {
                break;
            }
            else if(strncmp_P(command, PSTR("cd "), 3) == 0)
            {
                command += 3;
                if(command[0] == '\0')
                    continue;

                /* change directory */
                struct fat_dir_entry_struct subdir_entry;
                if(find_file_in_dir(fs, dd, command, &subdir_entry))
                {
                    struct fat_dir_struct* dd_new = fat_open_dir(fs, &subdir_entry);
                    if(dd_new)
                    {
                        fat_close_dir(dd);
                        dd = dd_new;
                        continue;
                    }
                }

                uart_puts_p(PSTR("directory not found: "));
                uart_puts(command);
                uart_putc('\n');
            }
            else if(strcmp_P(command, PSTR("ls")) == 0)
            {
                /* print directory listing */
                struct fat_dir_entry_struct dir_entry;
                while(fat_read_dir(dd, &dir_entry))
                {
                    uint8_t spaces = sizeof(dir_entry.long_name) - strlen(dir_entry.long_name) + 4;

                    uart_puts(dir_entry.long_name);
                    uart_putc(dir_entry.attributes & FAT_ATTRIB_DIR ? '/' : ' ');
                    while(spaces--)
                        uart_putc(' ');
                    uart_putdw_dec(dir_entry.file_size);
                    uart_putc('\n');
                }
            }
            else if(strncmp_P(command, PSTR("cat "), 4) == 0)
            {
                command += 4;
                if(command[0] == '\0')
                    continue;

                /* search file in current directory and open it */
                struct fat_file_struct* fd = open_file_in_dir(fs, dd, command);
                if(!fd)
                {
                    uart_puts_p(PSTR("error opening "));
                    uart_puts(command);
                    uart_putc('\n');
                    continue;
                }

                /* print file contents */
                uint8_t buffer[8];
                uint32_t offset = 0;
                while(fat_read_file(fd, buffer, sizeof(buffer)) > 0)
                {
                    uart_putdw_hex(offset);
                    uart_putc(':');
                    for(uint8_t i = 0; i < 8; ++i)
                    {
                        uart_putc(' ');
                        uart_putc_hex(buffer[i]);
                    }
                    uart_putc('\n');
                    offset += 8;
                }

                fat_close_file(fd);
            }
            else if(strcmp_P(command, PSTR("disk")) == 0)
            {
                if(!print_disk_info(fs))
                    uart_puts_p(PSTR("error reading disk info\n"));
            }
#if FAT_WRITE_SUPPORT
            else if(strncmp_P(command, PSTR("rm "), 3) == 0)
            {
                command += 3;
                if(command[0] == '\0')
                    continue;

                struct fat_dir_entry_struct file_entry;
                if(find_file_in_dir(fs, dd, command, &file_entry))
                {
                    if(fat_delete_file(fs, &file_entry))
                        continue;
                }

                uart_puts_p(PSTR("error deleting file: "));
                uart_puts(command);
                uart_putc('\n');
            }
            else if(strncmp_P(command, PSTR("touch "), 6) == 0)
            {
                command += 6;
                if(command[0] == '\0')
                    continue;

                struct fat_dir_entry_struct file_entry;
                if(!fat_create_file(dd, command, &file_entry))
                {
                    uart_puts_p(PSTR("error creating file: "));
                    uart_puts(command);
                    uart_putc('\n');
                }
            }
            else if(strncmp_P(command, PSTR("write "), 6) == 0)
            {
                command += 6;
                if(command[0] == '\0')
                    continue;

                char* offset_value = command;
                while(*offset_value != ' ' && *offset_value != '\0')
                    ++offset_value;

                if(*offset_value == ' ')
                    *offset_value++ = '\0';
                else
                    continue;

                /* search file in current directory and open it */
                struct fat_file_struct* fd = open_file_in_dir(fs, dd, command);
                if(!fd)
                {
                    uart_puts_p(PSTR("error opening "));
                    uart_puts(command);
                    uart_putc('\n');
                    continue;
                }

                int32_t offset = strtolong(offset_value);
                if(!fat_seek_file(fd, &offset, FAT_SEEK_SET))
                {
                    uart_puts_p(PSTR("error seeking on "));
                    uart_puts(command);
                    uart_putc('\n');

                    fat_close_file(fd);
                    continue;
                }

                /* read text from the shell and write it to the file */
                uint8_t data_len;
                while(1)
                {
                    /* give a different prompt */
                    uart_putc('<');
                    uart_putc(' ');

                    /* read one line of text */
                    data_len = read_line(buffer, sizeof(buffer));
                    if(!data_len)
                        break;

                    /* write text to file */
                    if(fat_write_file(fd, (uint8_t*) buffer, data_len) != data_len)
                    {
                        uart_puts_p(PSTR("error writing to file\n"));
                        break;
                    }
                }

                fat_close_file(fd);
            }
            else if(strncmp_P(command, PSTR("mkdir "), 6) == 0)
            {
                command += 6;
                if(command[0] == '\0')
                    continue;

                struct fat_dir_entry_struct dir_entry;
                if(!fat_create_dir(dd, command, &dir_entry))
                {
                    uart_puts_p(PSTR("error creating directory: "));
                    uart_puts(command);
                    uart_putc('\n');
                }
            }
#endif
#if SD_RAW_WRITE_BUFFERING
            else if(strcmp_P(command, PSTR("sync")) == 0)
            {
                if(!sd_raw_sync())
                    uart_puts_p(PSTR("error syncing disk\n"));
            }
#endif

            else if(strcmp_P(command, PSTR("sync")) == 0)
            {
                // vytvor adresar mereni_teploty

                // nekonecna smycka - pomoci RTCka kazdou minutu odmer teplotu
            }


            else
            {
                uart_puts_p(PSTR("unknown command: "));
                uart_puts(command);
                uart_putc('\n');
            }
        }

        /* close directory */
        fat_close_dir(dd);

        /* close file system */
        fat_close(fs);

        /* close partition */
        partition_close(partition);
    }

    return 0;
}
Пример #10
0
/**
 * \ingroup sd_raw
 * Reads raw data from the card.
 *
 * \param[in] offset The offset from which to read.
 * \param[out] buffer The buffer into which to write the data.
 * \param[in] length The number of bytes to read.
 * \returns 0 on failure, 1 on success.
 * \see sd_raw_read_interval, sd_raw_write, sd_raw_write_interval
 */
uint8_t sd_raw_read(offset_t offset, uint8_t* buffer, uintptr_t length)
{
#if !SD_RAW_SAVE_RAM
    uint8_t attempts = 0;
#endif
    offset_t block_address;
    uint16_t block_offset;
    uint16_t read_length;

    while(length > 0)
    {

        /* determine byte count to read at once */
        block_offset = offset & 0x01ff;
        block_address = offset - block_offset;
        read_length = 512 - block_offset; /* read up to block border */
        if(read_length > length)
            read_length = length;

#if !SD_RAW_SAVE_RAM
        /* check if the requested data is cached */
        if(block_address != raw_block_address)
#endif
        {
#if SD_RAW_WRITE_BUFFERING
            if(!sd_raw_sync())
                return 0;
#endif

	read_block:
            /* 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();
		sd_errno = SDR_ERR_BADRESPONSE;
                return 0;
            }

            /* wait for data block (start byte 0xfe) */
            uint16_t tries = 0;
            while(sd_raw_rec_byte() != 0xfe)
	    {
		if(tries++ >= 0x7FFF)
		{
		    unselect_card();
		    sd_errno = SDR_ERR_COMMS;
		    return 0;
		}
	    }

#if SD_RAW_SAVE_RAM
            /* read byte block */
            uint16_t read_to = block_offset + read_length;
            for(uint16_t i = 0; i < 512; ++i)
            {
                uint8_t b = sd_raw_rec_byte();
                if(i >= block_offset && i < read_to)
                    *buffer++ = b;
            }

	    /* ignore crc bytes */
	    sd_raw_rec_byte();
	    sd_raw_rec_byte();
#else
            /* read byte block */
            uint8_t* cache = raw_block;
            for(uint16_t i = 0; i < 512; ++i)
                *cache++ = sd_raw_rec_byte();
            raw_block_address = block_address;

            /* read crc16 */
	    if ( sd_use_crc ) {
		uint16_t crc = sd_raw_rec_byte() << 8;
		crc |= sd_raw_rec_byte();
		if ( crc != sd_crc16(raw_block, (uint16_t)512) ) {
		    unselect_card();
		    if ( ++attempts < 5 ) {
			sd_raw_rec_byte(); // pause a little
			goto read_block;
		    }
		    sd_errno = SDR_ERR_CRC;
		    return 0;
		}
	    }
	    else
	    {
		/* ignore crc bytes */
		sd_raw_rec_byte();
		sd_raw_rec_byte();
	    }

            memcpy(buffer, raw_block + block_offset, read_length);
            buffer += read_length;
#endif

	    /* deaddress card */
            unselect_card();

            /* let card some time to finish */
            sd_raw_rec_byte();
        }
#if !SD_RAW_SAVE_RAM
        else
        {
            /* use cached data */
            memcpy(buffer, raw_block + block_offset, read_length);
            buffer += read_length;
        }
#endif

        length -= read_length;
        offset += read_length;
    }

    return 1;
}
Пример #11
0
/**
 * \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
}
Пример #12
0
/**
 * \ingroup sd_raw
 * Reads raw data from the card.
 *
 * \param[in] offset The offset from which to read.
 * \param[out] buffer The buffer into which to write the data.
 * \param[in] length The number of bytes to read.
 * \returns 0 on failure, 1 on success.
 * \see sd_raw_read_interval, sd_raw_write, sd_raw_write_interval
 */
uint8_t sd_raw_read(uint32_t offset, uint8_t* buffer, uint16_t length)
{
    uint32_t block_address;
    uint16_t block_offset;
    uint16_t read_length;
    while(length > 0)
    {
        /* determine byte count to read at once */
        block_address = offset & 0xfffffe00;
        block_offset = offset & 0x01ff;
        read_length = 512 - block_offset; /* read up to block border */
        if(read_length > length)
            read_length = length;
        
#if !SD_RAW_SAVE_RAM
        /* check if the requested data is cached */
        if(block_address != raw_block_address)
#endif
        {
#if SD_RAW_WRITE_BUFFERING
            if(!sd_raw_sync())
                return 0;
#endif

            /* address card */
            select_card();

            /* send single block request */
            if(sd_raw_send_command_r1(CMD_READ_SINGLE_BLOCK, block_address))
            {
                unselect_card();
                spi_rec_byte();
                return 0;
            }

            /* wait for data block (start byte 0xfe) */
            uint16_t i;
            for(i = 0; i < 0x1fff; ++i)
            {
                if(spi_rec_byte() == 0xfe)
                    break;
            }
            if(i >= 0x1fff)
            {
                unselect_card();
                spi_rec_byte();
                return 0;
            }

#if SD_RAW_SAVE_RAM
            /* read byte block */
            uint16_t read_to = block_offset + read_length;
            for(uint16_t i = 0; i < 512; ++i)
            {
                uint8_t b = spi_rec_byte();
                if(i >= block_offset && i < read_to)
                    *buffer++ = b;
            }
#else
            /* read byte block */
            spi_rec_data(raw_block, 512);
            raw_block_address = block_address;

            memcpy(buffer, raw_block + block_offset, read_length);
            buffer += read_length;
#endif
            
            /* read crc16 */
            spi_rec_byte();
            spi_rec_byte();
            
            /* deaddress card */
            unselect_card();
            spi_rec_byte();
        }
#if !SD_RAW_SAVE_RAM
        else
        {
            /* use cached data */
            memcpy(buffer, raw_block + block_offset, read_length);
            buffer += read_length;
        }
#endif

        length -= read_length;
        offset += read_length;
    }

    return 1;
}
Пример #13
0
//0 for success, negative for failure
int readLogCon(void) {
  char keyword[64];
  char value[64];                            
  char stringBuf[512];

  struct fat16_file_struct fd;
  int len;
  int s=0;
  int t=0;
  keyword[0]=0;
  value[0]=0;
  int result;
  if(root_file_exists(LOGCON_NAME)) {
    //There already is a logcon file, open it and suck int in
    result = root_open(&fd,LOGCON_NAME);
    
    if(result<0) return result;
    len = fat16_read_file(&fd, (unsigned char *)stringBuf, 512);
    if(len<0) return -1;
    fat16_close_file(&fd);
  } else {
    //No existing logcon file, write a fresh one
    result=root_open_new(&fd,LOGCON_NAME);
    if(result<0) return result;
    stringBuf[0]=0;

    //Write out each default line
    for(int i=0;strlen(fTable[i].tag)>0;i++) {
      strcat(stringBuf,fTable[i].tag);
      strcat(stringBuf,"=");
      strcat(stringBuf,fTable[i].def);
      strcat(stringBuf,"\r\n");
    }

    //write it out to the file
    len=strlen(stringBuf);
    fat16_write_file(&fd, (unsigned char*)stringBuf, len);
    fat16_close_file(&fd);
    sd_raw_sync();
  }

  //Either way, the logcon file is now in stringBuf and
  //its length is in len
  
  s=0;
  t=0;
  char inValue=0;
  for(s = 0; s < len; s++) {
    if(stringBuf[s] == '=') {
      keyword[t]=0;
      inValue=1;
      t=0;
    } else if(stringBuf[s]=='\n') {
      value[t]=0;
      inValue=0;
      t=0;
      result=processLine(keyword,value);
      if(result<0) return result;
    } else {
      if(inValue) {
        value[t]=stringBuf[s];
      } else {
        keyword[t]=stringBuf[s];
      }
      t++;
    }
  }
  return 0;
}
Пример #14
0
int main()
{
    /* setup uart */
    uart_init();
    /* setup stdio */
    uart_connect_stdio();

    /* setup sd card slot */
    if(!sd_raw_init())
    {
#if DEBUG
        printf_P(PSTR("MMC/SD initialization failed\n"));
#endif
        return 1;
    }

    /* open first partition */
    struct partition_struct* partition = partition_open(sd_raw_read,
                                                        sd_raw_read_interval,
                                                        sd_raw_write,
                                                        0);

    if(!partition)
    {
        /* If the partition did not open, assume the storage device
         * is a "superfloppy", i.e. has no MBR.
         */
        partition = partition_open(sd_raw_read,
                                   sd_raw_read_interval,
                                   sd_raw_write,
                                   -1
                                  );
        if(!partition)
        {
#if DEBUG
            printf_P(PSTR("opening partition failed\n"));
#endif
            return 1;
        }
    }

    /* open file system */
    struct fat16_fs_struct* fs = fat16_open(partition);
    if(!fs)
    {
#if DEBUG
        printf_P(PSTR("opening filesystem failed\n"));
#endif
        return 1;
    }

    /* open root directory */
    struct fat16_dir_entry_struct directory;
    fat16_get_dir_entry_of_path(fs, "/", &directory);

    struct fat16_dir_struct* dd = fat16_open_dir(fs, &directory);
    if(!dd)
    {
#if DEBUG
        printf_P(PSTR("opening root directory failed\n"));
#endif
        return 1;
    }
    
    /* provide a simple shell */
    char buffer[24];
    while(1)
    {
        /* print prompt */
        uart_putc('>');
        uart_putc(' ');

        /* read command */
        char* command = buffer;
        if(read_line(command, sizeof(buffer)) < 1)
            continue;

        /* execute command */
        if(strncmp_P(command, PSTR("cd "), 3) == 0)
        {
            command += 3;
            if(command[0] == '\0')
                continue;

            /* change directory */
            struct fat16_dir_entry_struct subdir_entry;
            if(find_file_in_dir(fs, dd, command, &subdir_entry))
            {
                struct fat16_dir_struct* dd_new = fat16_open_dir(fs, &subdir_entry);
                if(dd_new)
                {
                    fat16_close_dir(dd);
                    dd = dd_new;
                    continue;
                }
            }

            printf_P(PSTR("directory not found: %s\n"), command);
        }
        else if(strcmp_P(command, PSTR("ls")) == 0)
        {
            /* print directory listing */
            struct fat16_dir_entry_struct dir_entry;
            while(fat16_read_dir(dd, &dir_entry))
            {
                printf_P(PSTR("%10lu  %s%c\n"),
                         dir_entry.file_size,
                         dir_entry.long_name,
                         (dir_entry.attributes & FAT16_ATTRIB_DIR) ? '/' : ' '
                        );
            }
        }
        else if(strncmp_P(command, PSTR("cat "), 4) == 0)
        {
            command += 4;
            if(command[0] == '\0')
                continue;
            
            /* search file in current directory and open it */
            struct fat16_file_struct* fd = open_file_in_dir(fs, dd, command);
            if(!fd)
            {
                printf_P(PSTR("error opening %s\n"), command);
                continue;
            }

            /* print file contents */
            uint8_t buffer[8];
            uint32_t offset = 0;
            while(fat16_read_file(fd, buffer, sizeof(buffer)) > 0)
            {
                printf_P(PSTR("%08lx: %02x %02x %02x %02x %02x %02x %02x %02x\n"),
                         offset,
                         buffer[0],
                         buffer[1],
                         buffer[2],
                         buffer[3],
                         buffer[4],
                         buffer[5],
                         buffer[6],
                         buffer[7]
                        );
                offset += 8;
            }

            fat16_close_file(fd);
        }
#if FAT16_WRITE_SUPPORT
        else if(strncmp_P(command, PSTR("rm "), 3) == 0)
        {
            command += 3;
            if(command[0] == '\0')
                continue;
            
            struct fat16_dir_entry_struct file_entry;
            if(find_file_in_dir(fs, dd, command, &file_entry))
            {
                if(fat16_delete_file(fs, &file_entry))
                    continue;
            }

            printf_P(PSTR("error deleting file: %s\n"), command);
        }
        else if(strncmp_P(command, PSTR("touch "), 6) == 0)
        {
            command += 6;
            if(command[0] == '\0')
                continue;

            struct fat16_dir_entry_struct file_entry;
            if(!fat16_create_file(dd, command, &file_entry))
                printf_P(PSTR("error creating file: %s\n"), command);
        }
        else if(strncmp_P(command, PSTR("write "), 6) == 0)
        {
            command += 6;
            if(command[0] == '\0')
                continue;

            char* offset_value = command;
            while(*offset_value != ' ' && *offset_value != '\0')
                ++offset_value;

            if(*offset_value == ' ')
                *offset_value++ = '\0';
            else
                continue;

            /* search file in current directory and open it */
            struct fat16_file_struct* fd = open_file_in_dir(fs, dd, command);
            if(!fd)
            {
                printf_P(PSTR("error opening %s\n"), command);
                continue;
            }

            int32_t offset = strtol(offset_value, 0, 0);
            if(!fat16_seek_file(fd, &offset, FAT16_SEEK_SET))
            {
                printf_P(PSTR("error seeking on %s\n"), command);
                fat16_close_file(fd);
                continue;
            }

            /* read text from the shell and write it to the file */
            uint8_t data_len;
            while(1)
            {
                /* give a different prompt */
                uart_putc('<');
                uart_putc(' ');

                /* read one line of text */
                data_len = read_line(buffer, sizeof(buffer));
                if(!data_len)
                    break;

                /* write text to file */
                if(fat16_write_file(fd, (uint8_t*) buffer, data_len) != data_len)
                {
                    printf_P(PSTR("error writing to file\n"));
                    break;
                }
            }

            fat16_close_file(fd);
        }
#endif
#if SD_RAW_WRITE_BUFFERING
        else if(strcmp_P(command, PSTR("sync")) == 0)
        {
            if(!sd_raw_sync())
                printf_P(PSTR("error syncing disk\n"));
        }
#endif
        else
        {
            printf_P(PSTR("unknown command: %s\n"), command);
        }
    }

    /* close file system */
    fat16_close(fs);

    /* close partition */
    partition_close(partition);
    
    return 0;
}
Пример #15
0
/**
 * \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;
}
Пример #16
0
/**
 * \ingroup sd_raw
 * Reads raw data from the card.
 *
 * \param[in] offset The offset from which to read.
 * \param[out] buffer The buffer into which to write the data.
 * \param[in] length The number of bytes to read.
 * \returns 0 on failure, 1 on success.
 * \see sd_raw_read_interval, sd_raw_write, sd_raw_write_interval
 */
uint8_t sd_raw_read(offset_t offset, uint8_t* buffer, uintptr_t length)
{
  offset_t block_address;
  uint16_t block_offset;
  uint16_t read_length;
  while(length > 0)
  {
    /* determine byte count to read at once */
    block_offset = offset & 0x01ff;
    block_address = offset - block_offset;
    read_length = 512 - block_offset; /* read up to block border */
    if(read_length > length)
      read_length = length;

    /* check if the requested data is cached */
    if(block_address != raw_block_address)
    {
#if SD_RAW_WRITE_BUFFERING
      if(!sd_raw_sync())
        return 0;
#endif

      /* 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
        {
          return 0;
        }

      /* wait for data block (start byte 0xfe) */
      //while(sd_raw_rec_byte() != 0xfe);
      sd_raw_send_byte(0xef);

      /* read byte block */
      uint8_t* cache = raw_block;
      for(uint16_t i = 0; i < 512; ++i)
      {
	  while(!(SPSR & (1<<SPIF)));
	  *cache++ = SPDR;
      }
      raw_block_address = block_address;

      /* read crc16 */
      sd_raw_send_byte(0xab);
      sd_raw_send_byte(0xcd);


      memcpy(buffer, raw_block + block_offset, read_length);
      buffer += read_length;
    }    
    else
    {
      /* use cached data */
      memcpy(buffer, raw_block + block_offset, read_length);
      buffer += read_length;
    }

    length -= read_length;
    offset += read_length;
  }

  return 1;
}
Пример #17
0
/**
 * \ingroup sd_raw_read_block
 * Reads block of raw data from the card.
 *
 * \param[in] block_address the address of the block to read
 * \param[in] block_offset The offset from which to read.
 * \param[out] raw_buffer The buffer into which to write the data.
 * \param[in] read_length The number of bytes to read.
 * \returns 0 on failure, 1 on success.
 * \see sd_raw_read_interval, sd_raw_write, sd_raw_write_interval
 */
uint8_t sd_raw_read_block(offset_t block_address, offset_t block_offset, uint8_t* raw_buffer, uintptr_t read_length) {


#if SD_RAW_WRITE_BUFFERING
            if(!sd_raw_sync())
                return 0;
#endif

            /* 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;
            }
            
            uint16_t tries = 0;

            /* wait for data block (start byte 0xfe) */
            while((sd_raw_rec_byte() != 0xfe)){
				if(tries >= 0x7FFF){
					unselect_card();
					return 0;
				}
				tries++;
			}
            

#if SD_RAW_SAVE_RAM
            /* read byte block */
            uint16_t read_to = block_offset + read_length;
            for(uint16_t i = 0; i < 512; ++i)
            {
                uint8_t b = sd_raw_rec_byte();
                if(i >= block_offset && i < read_to)
                    *buffer++ = b;
            }
#else
            /* read byte block */
          //  uint8_t* cache = raw_block;
            uint8_t* cache = raw_buffer;
            for(uint16_t i = 0; i < 512; ++i)
                *cache++ = sd_raw_rec_byte();
#endif
      
            /* 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;
}
Пример #18
0
int load_fw(char* filename)
{
    struct fat16_file_struct * fd;
    int read;
    int i;
    char* addy;
    addy = (char*)STARTADDR;

    /* Erase all sectors we could use */
    prep_command[1]=ERASE_SECT_START;
    prep_command[2]=ERASE_SECT_STOP;
    iap_fn(prep_command,result);
    iap_fn(erase_command,result);

    /* Open the file */
    fd = root_open(filename);

    /* Clear the buffer */
    for(i=0;i<READBUFSIZE;i++)
    {
        readbuf[i]=0;
    }

    /* Read the file contents, and print them out */
    while( (read=fat16_read_file(fd,(unsigned char*)readbuf,READBUFSIZE)) > 0 )
    {

        // Print Data to UART (DEBUG)
        /*for(i=0; i<read; i++)
        {
            rprintf("%c",readbuf[i]);
        }*/

        /* Write Data to Flash */

        /* Prepare Current Sector */
        /* This assumes that we are always only writing to one sector!
                     * This is only true if our write size necessarily aligns
                     * on proper boundaries. Be careful */
        prep_command[1] = SECTOR_NUMBER(((int)addy));
        prep_command[2] = prep_command[1];
        iap_fn(prep_command,result);


        /* *** Should check result here... but I'm not */
        /* If all went according to plan, the sector is primed for write
                     * (or erase)
                     */


        /* Now write data */
        write_command[1]=(unsigned int)addy;
        write_command[2]=(unsigned int)readbuf;
        write_command[3]=READBUFSIZE;
        iap_fn(write_command,result);

        /* *** Should check result here... but I'm not */
        /* If all went according to plan, data is in flash,
                     * and the sector is locked again
                     */


        /* Done with current data, so clear buffer
                     *  this is because we ALWAYS write out the
                     *  entire buffer, and we don't want to write
                     *  garbage data on reads smaller than READBUFSIZE
                     */
        for(i=0;i<READBUFSIZE;i++)
        {
            readbuf[i]=0;
        }


        /* Now update the address-- */
        addy = addy + READBUFSIZE;

        /* And we should probably bounds-check... *SIGH*/
        if((unsigned int)addy > (unsigned int) 0x0007CFFF)
        {
            break;
        }

    }

    /* All data copied to FLASH */
    /* Debug: Report the flash contents */
    /*  addy = (char*)STARTADDR;*/

    /*  PRINTF0("Dirty Screech\n\r");*/
    /*  delay_ms(10000);*/
    /*  while(addy<(char*)0x00050000)*/
    /*  {*/
    /*    __putchar(*addy++);*/
    /*  }*/
    /*  PRINTF0("Dirty Screech completed\n\r");*/


    /* Close the file! */
    sd_raw_sync();
    fat16_close_file(fd);
    root_delete(filename);

    return 0;
}
Пример #19
0
void RepRapSDCard::close_file(File f)
{
  //fat_resize_file(f,f->pos);
  fat_close_file(f);
  sd_raw_sync();
}