summaryrefslogtreecommitdiff
path: root/trunk/users/bruce/GCode_Interpreter_SD/RepRapSDCard.cpp
blob: bcdfd8debf805cdd18f656ee8640b807427eee78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#include <HardwareSerial.h>
#include "RepRapSDCard.h"
#include "fat.h"
#include "sd_raw.h"
#include "partition.h"
#include <string.h>

/*!
  Initializes SD card, returns an SDStatus (SDOK or an error).
  Will also open a partition, filesystem and root dir.
*/
uint8_t RepRapSDCard::init()
{
  if (!sd_raw_init()) {
    if (!sd_raw_available()) {
      Serial.println("No card present"); 
      return NO_CARD;
    }
    else
    {
      Serial.println("Card init failed"); 
      return INIT_FAILED;
    }
  }
  else if (!this->open_partition())
  {
    Serial.println("No partition"); 
    return NO_PARTITION;
  }
  else if (!this->open_filesys())
  {
    Serial.println("Can't open filesys"); 
    return NO_FILESYS;
  }
  else if (!this->openDir("/"))
  {
    Serial.println("Can't open /");
    return NO_ROOT;
  }
  return SDOK;
}

/*!
  Opens the first partition and stores it in this->partition.
  Returns true on success, false on error.
*/
bool RepRapSDCard::open_partition()
{
  this->partition = partition_open(sd_raw_read,
                                   sd_raw_read_interval,
                                   sd_raw_write,
                                   sd_raw_write_interval,
                                   0);

  if (!this->partition) {
    // If the partition did not open, assume the storage device
    // is a "superfloppy", i.e. has no MBR.
    this->partition = partition_open(sd_raw_read,
                                     sd_raw_read_interval,
                                     sd_raw_write,
                                     sd_raw_write_interval,
                                     -1);
  }
  
  if (!this->partition) return false;
  return true;
}

/*!
  Open file system. A partition must be opened first.
  Stores the filesystem in this->filesystem.
  Returns true on success, false on error.
*/
bool RepRapSDCard::open_filesys()
{
  this->filesystem = fat_open(this->partition);
  if (!this->filesystem) return false;
  return true;
}

/*!
  Prints SD card hardware and filesystem info to Serial
 */
void RepRapSDCard::printInfo()
{
  if (!this->filesystem) return;

  struct sd_raw_info disk_info;
  if (!sd_raw_get_info(&disk_info)) return;

  Serial.print("manuf:  0x"); 
  Serial.println(disk_info.manufacturer, HEX);
  Serial.print("oem:    ");
  Serial.println((char*) disk_info.oem);
  Serial.print("prod:   ");
  Serial.println((char*) disk_info.product);
  Serial.print("rev:    ");
  Serial.println(disk_info.revision, HEX);
  Serial.print("serial: 0x");
  Serial.println(disk_info.serial, HEX);
  Serial.print("date:   ");
  Serial.print(disk_info.manufacturing_month, DEC);
  Serial.println(disk_info.manufacturing_year, DEC);
  Serial.print("size:   ");
  Serial.print(disk_info.capacity / 1024 / 1024, DEC);
  Serial.println("MB");
  Serial.print("copy:   ");
  Serial.println(disk_info.flag_copy, DEC);
  Serial.print("wr.pr.: ");
  Serial.print(disk_info.flag_write_protect_temp, DEC);
  Serial.println(disk_info.flag_write_protect);
  Serial.print("format: ");
  Serial.println(disk_info.format, DEC);
  Serial.print("free:   ");
  Serial.print(fat_get_fs_free(this->filesystem), DEC);
  Serial.print("/");
  Serial.println(fat_get_fs_size(this->filesystem), DEC);
}

/*!
  Opens the given directory and stores the open dir in this->cwd.
  If cwd already points to an open dir, this will be closed prior
  to opening the given dir.
*/
bool RepRapSDCard::openDir(const char *path)
{
  struct fat_dir_entry_struct dir;

  if (this->cwd) fat_close_dir(this->cwd);
  fat_get_dir_entry_of_path(this->filesystem, path, &dir);
  this->cwd = fat_open_dir(this->filesystem, &dir);
  if (!this->cwd) return false;
  return true;
}

/*!
  Finds the next entry in the current open directory.
  The filename (first 11 characters) are written to \e name.
  Files with attributes SYSTEM, HIDDEN or VOLUME are skipped.
*/
bool
RepRapSDCard::getNextEntry(char *name)
{
  fat_dir_entry_struct dir_entry;

  while (fat_read_dir(this->cwd, &dir_entry) &&
         dir_entry.attributes & 
         (FAT_ATTRIB_SYSTEM | FAT_ATTRIB_HIDDEN | FAT_ATTRIB_VOLUME)) { } 
  if (dir_entry.long_name[0] == '\0') return false;
     
  strncpy(name, dir_entry.long_name, 12);
  name[12] = 0;
  return true;
}

/*!
  Opens the given file.
  NB! Since the max number of allowed open files may be 1, make sure to
  close all open files before calling this method.
*/
File *RepRapSDCard::openFile(const char* name)
{
  struct fat_dir_entry_struct file_entry;

  fat_reset_dir(this->cwd);
  while (fat_read_dir(this->cwd, &file_entry)) {
    // FIXME: Compare only 12 first chars
    if (strcmp(file_entry.long_name, name) == 0) {
      break;
    }
  }

  if (file_entry.long_name[0] == '\0') return NULL;

  return fat_open_file(this->filesystem, &file_entry);
}




uint8_t RepRapSDCard::create_file(char *name)
{
  struct fat_dir_entry_struct file_entry;
  return fat_create_file(cwd, name, &file_entry);
}