Skip to content

Commit

Permalink
Merge branch 'release-2.0-nightly' into release-2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidZemon committed Oct 18, 2015
2 parents 7756c20 + 64240d5 commit deefc11
Show file tree
Hide file tree
Showing 14 changed files with 408 additions and 127 deletions.
8 changes: 5 additions & 3 deletions CMakeModules/PropellerToolchain.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ if (NOT DEFINED GCC_PATH)

file(TO_CMAKE_PATH "/opt/parallax/bin" DEFAULT_LINUX_PATH_1)
file(TO_CMAKE_PATH "C:\\PropGCC\\bin" DEFAULT_WINDOWS_PATH_1)
file(TO_CMAKE_PATH "C:\\Program Files\\SimpleIDE\\propeller-gcc\\bin" DEFAULT_WINDOWS_PATH_2)
file(TO_CMAKE_PATH "C:\\Program Files (x86)\\SimpleIDE\\propeller-gcc\\bin" DEFAULT_WINDOWS_PATH_3)
file(TO_CMAKE_PATH "C:\\parallax\\bin" DEFAULT_WINDOWS_PATH_2)
file(TO_CMAKE_PATH "C:\\Program Files\\SimpleIDE\\propeller-gcc\\bin" DEFAULT_WINDOWS_PATH_3)
file(TO_CMAKE_PATH "C:\\Program Files (x86)\\SimpleIDE\\propeller-gcc\\bin" DEFAULT_WINDOWS_PATH_4)

if (NOT GCC_PATH)
find_path(GCC_PATH
Expand All @@ -28,7 +29,8 @@ if (NOT DEFINED GCC_PATH)
"${DEFAULT_LINUX_PATH_1}"
"${DEFAULT_WINDOWS_PATH_1}"
"${DEFAULT_WINDOWS_PATH_2}"
"${DEFAULT_WINDOWS_PATH_3}")
"${DEFAULT_WINDOWS_PATH_3}"
"${DEFAULT_WINDOWS_PATH_4}")
endif ()
endif ()

Expand Down
1 change: 1 addition & 0 deletions Examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_subdirectory(Libpropeller_Pwm32)
add_subdirectory(PropWare_Blinky)
add_subdirectory(PropWare_DuplexUART)
add_subdirectory(PropWare_FileReader)
add_subdirectory(PropWare_FileWriter)
add_subdirectory(PropWare_HD44780)
add_subdirectory(PropWare_I2C)
add_subdirectory(PropWare_L3G)
Expand Down
12 changes: 12 additions & 0 deletions Examples/PropWare_FileWriter/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cmake_minimum_required (VERSION 3.0.0)
find_package(PropWare REQUIRED)

set(BOARD dna)
set(MODEL cmm)
set(COMMON_FLAGS "-Os")
set(C_FLAGS )
set(CXX_FLAGS )

project(FileWriter_Demo)

create_simple_executable(${PROJECT_NAME} ${PROJECT_NAME})
89 changes: 89 additions & 0 deletions Examples/PropWare_FileWriter/FileWriter_Demo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* @file FileReader_Demo.cpp
*
* @author David Zemon
*
* @copyright
* The MIT License (MIT)<br>
* <br>Copyright (c) 2013 David Zemon<br>
* <br>Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:<br>
* <br>The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.<br>
* <br>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#include <PropWare/PropWare.h>
#include <PropWare/printer/printer.h>

#define TEST_PROPWARE

//#define TEST_SIMPLE

#if (defined TEST_PROPWARE)

#include <PropWare/filesystem/sd.h>
#include <PropWare/filesystem/fat/fatfs.h>
#include <PropWare/filesystem/fat/fatfilewriter.h>
#include <PropWare/filesystem/fat/fatfilereader.h>

#elif (defined TEST_SIMPLE)
#include <simple/simpletools.h>
#endif

using namespace PropWare;

#define error_checker(x) err = x; if (err) {pwOut << __FILE__ << ':' << __LINE__ << " Error: " << err << '\n'; return 1;}

int main () {
#ifdef TEST_PROPWARE
ErrorCode err;
const SD driver;
FatFS filesystem(&driver);
SD::Buffer writeBuffer;
SD::MetaData writeMetaData;
writeBuffer.buf = (uint8_t *) malloc(driver.get_sector_size());
writeBuffer.meta = &writeMetaData;

error_checker(filesystem.mount());

FatFileReader reader(filesystem, "fat_test.txt");
reader.open();

FatFileWriter writer(filesystem, "new2.txt", &writeBuffer);
if (writer.exists()) {
pwOut << "File already exists: " << writer.get_name() << '\n';
pwOut << "Deleting now\n";
error_checker(writer.remove());
error_checker(writer.flush());
}

error_checker(writer.open());

while (!reader.eof())
writer.put_char(reader.get_char());

writer.close();
filesystem.unmount();
#elif (defined TEST_SIMPLE)
sd_mount(0, 1, 2, 3);

FILE *f = fopen("fat_test.txt", "r");

while (!feof(f))
pwOut << (char) fgetc(f);
#endif

pwOut << "All done!\n";
return 0;
}
127 changes: 68 additions & 59 deletions PropWare/filesystem/fat/fatfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ class FatFile : virtual public File {
return this->m_name;
}

/**
* @brief Determine if a file exists (file does not have to be open - opening a file that does not exist
* will create it)
*/
bool exists () const {
uint16_t temp = 0;
return NO_ERROR == this->find(this->get_name(), &temp);
Expand Down Expand Up @@ -187,7 +191,6 @@ class FatFile : virtual public File {
this->m_buf->buf);

// Claim this buffer as our own
this->m_contentMeta.id = this->m_id;
this->m_contentMeta.curTier1Offset = 0;
this->m_contentMeta.curTier2 = this->firstTier2;
this->m_contentMeta.curTier2Addr = this->m_fs->compute_tier1_from_tier2(this->firstTier2);
Expand Down Expand Up @@ -269,8 +272,8 @@ class FatFile : virtual public File {
// Root dir of FAT16; Not last sector
else {
// Any error from reading the data block will be returned to calling function
check_errors(this->m_fs->get_driver()->flush(buf));
return this->m_fs->get_driver()->read_data_block(++(buf->meta->curTier1Offset), buf->buf);
check_errors(this->m_driver->flush(buf));
return this->m_driver->read_data_block(++(buf->meta->curTier1Offset), buf->buf);
}
}
// We are looking at a generic data cluster.
Expand All @@ -281,7 +284,7 @@ class FatFile : virtual public File {
if (tier1sPerTier2 == buf->meta->curTier1Offset) {
return this->inc_cluster();
} else
return this->m_fs->get_driver()->read_data_block(
return this->m_driver->read_data_block(
buf->meta->curTier1Offset + buf->meta->curTier2Addr, buf->buf);
}
}
Expand All @@ -307,7 +310,7 @@ class FatFile : virtual public File {
return FatFS::READING_PAST_EOC;

// Increment cluster
check_errors(this->m_fs->get_driver()->flush(buf));
check_errors(this->m_driver->flush(buf));

buf->meta->curTier2 = buf->meta->nextTier2;
// Only look ahead to the next cluster if the current alloc unit is not EOC
Expand All @@ -318,7 +321,7 @@ class FatFile : virtual public File {
buf->meta->curTier2Addr = this->m_fs->compute_tier1_from_tier2(buf->meta->curTier2);
buf->meta->curTier1Offset = 0;

return this->m_fs->get_driver()->read_data_block(buf->meta->curTier2Addr, buf->buf);
return this->m_driver->read_data_block(buf->meta->curTier2Addr, buf->buf);
}

const bool buffer_holds_directory_start () const {
Expand All @@ -344,7 +347,35 @@ class FatFile : virtual public File {
check_errors(this->m_fs->get_fat_value(this->m_fsBufMeta->curTier2, &this->m_fsBufMeta->nextTier2));

this->m_buf->meta = dirMeta;
check_errors(this->m_fs->get_driver()->reload_buffer(this->m_buf));
check_errors(this->m_driver->reload_buffer(this->m_buf));
}

return NO_ERROR;
}

PropWare::ErrorCode load_sector_under_ptr () {
PropWare::ErrorCode err;

// Determine if the currently loaded sector is what we need
const uint32_t requiredSector = (uint32_t) this->m_ptr >> this->m_driver->get_sector_size_shift();

// If the buffer is being used by another file, flush it
// We're not reloading yet because it could potentially lead to redundant reads
bool wrongData = false;
if (this->m_buf->meta != &this->m_contentMeta) {
check_errors(this->m_driver->flush(this->m_buf));
this->m_buf->meta = &this->m_contentMeta;
wrongData = true;
}

if (requiredSector != this->m_curTier1) {
check_errors(this->load_sector_from_offset(requiredSector, this->m_buf->meta));
wrongData = false;
}

// Make sure the buffer gets reloaded
if (wrongData) {
check_errors(this->m_driver->reload_buffer(this->m_buf));
}

return NO_ERROR;
Expand All @@ -353,15 +384,20 @@ class FatFile : virtual public File {
/**
* @brief Load a requested sector into the buffer independent of the current sector or cluster
*
* @param[in] offset How many sectors past the first one should be skipped (sector number of the file)
* @param[in] offset How many sectors past the first one should be skipped (sector number of the
* file)
* @param[in] *bufferMetadata Currently loaded buffer's metadata
*
* @pre Buffer belonging to `bufferMetadata` must be loaded
*
* @return Returns 0 upon success, error code otherwise
*
*/
PropWare::ErrorCode load_sector_from_offset (const uint32_t requiredSector) {
PropWare::ErrorCode err;
const uint8_t tier1sPerTier2 = this->m_fs->m_tier1sPerTier2Shift;
unsigned int requiredCluster = requiredSector >> tier1sPerTier2;
PropWare::ErrorCode load_sector_from_offset (const uint32_t requiredSector,
BlockStorage::MetaData *bufferMetadata) {
PropWare::ErrorCode err;
const uint8_t sectorsPerCluster = this->m_fs->m_tier1sPerTier2Shift;
unsigned int requiredCluster = requiredSector >> sectorsPerCluster;

check_errors(this->m_driver->flush(this->m_buf));

Expand All @@ -370,69 +406,41 @@ class FatFile : virtual public File {
// Desired cluster comes after the currently loaded one - this is easy and requires continuing to look
// forward through the FAT from the current position
do {
this->m_buf->meta->curTier2 = this->m_buf->meta->nextTier2;
check_errors(this->m_fs->get_fat_value(this->m_buf->meta->curTier2,
&(this->m_buf->meta->nextTier2)));
bufferMetadata->curTier2 = bufferMetadata->nextTier2;
check_errors(this->m_fs->get_fat_value(bufferMetadata->curTier2,
&(bufferMetadata->nextTier2)));

++this->m_curTier2;
} while (this->m_curTier2 < requiredCluster);
pwOut << "New cluster = " << this->m_curTier2 << "\n\n";
this->m_buf->meta->curTier2Addr = this->m_fs->compute_tier1_from_tier2(this->m_buf->meta->curTier2);
bufferMetadata->curTier2Addr = this->m_fs->compute_tier1_from_tier2(bufferMetadata->curTier2);
} else if (this->m_curTier2 > requiredCluster) {
// Desired cluster is an earlier cluster than the currently
// loaded one - this requires starting from the beginning and
// working forward
this->m_curTier2 = 0;
this->m_buf->meta->curTier2 = this->firstTier2;
check_errors(this->m_fs->get_fat_value(this->m_buf->meta->curTier2, &(this->m_buf->meta->nextTier2)));
// Desired cluster is an earlier cluster than the currently loaded one - this requires starting from
// the beginning and working forward
this->m_curTier2 = 0;
bufferMetadata->curTier2 = this->firstTier2;
check_errors(this->m_fs->get_fat_value(bufferMetadata->curTier2, &(bufferMetadata->nextTier2)));
while (requiredCluster--) {
++this->m_curTier2;
this->m_buf->meta->curTier2 = this->m_buf->meta->nextTier2;
check_errors(this->m_fs->get_fat_value(this->m_buf->meta->curTier2,
&(this->m_buf->meta->nextTier2)));
bufferMetadata->curTier2 = bufferMetadata->nextTier2;
check_errors(this->m_fs->get_fat_value(bufferMetadata->curTier2,
&(bufferMetadata->nextTier2)));
}
this->m_buf->meta->curTier2Addr = this->m_fs->compute_tier1_from_tier2(this->m_buf->meta->curTier2);
bufferMetadata->curTier2Addr = this->m_fs->compute_tier1_from_tier2(bufferMetadata->curTier2);
}

// Followed by finding the correct sector
this->m_buf->meta->curTier1Offset = (uint8_t) (requiredSector % (1 << tier1sPerTier2));
this->m_curTier1 = requiredSector;
bufferMetadata->curTier1Offset = (uint8_t) (requiredSector % (1 << sectorsPerCluster));
this->m_curTier1 = requiredSector;

check_errors(this->m_driver->read_data_block(
this->m_buf->meta->curTier2Addr + this->m_buf->meta->curTier1Offset, this->m_buf->buf));
bufferMetadata->curTier2Addr + bufferMetadata->curTier1Offset, this->m_buf->buf));

return 0;
}

PropWare::ErrorCode load_sector_under_ptr () {
PropWare::ErrorCode err;

// Determine if the currently loaded sector is what we need
const uint32_t requiredSector = (uint32_t) this->m_ptr >> this->m_driver->get_sector_size_shift();

bool wrongData = false;
if (this->m_buf->meta != &this->m_contentMeta) {
check_errors(this->m_driver->flush(this->m_buf));
this->m_buf->meta = &this->m_contentMeta;
wrongData = true;
}

if (requiredSector != this->m_curTier1) {
check_errors(this->load_sector_from_offset(requiredSector));
wrongData = false;
}

// Make sure the buffer gets reloaded
if (wrongData) {
check_errors(this->m_driver->reload_buffer(this->m_buf));
}

return NO_ERROR;
}

PropWare::ErrorCode load_directory_sector () {
PropWare::ErrorCode err;
if (&this->m_dirEntryMeta != this->m_buf->meta) {
if (this->m_buf->meta != &this->m_dirEntryMeta) {
this->m_driver->flush(this->m_buf);
this->m_buf->meta = &this->m_dirEntryMeta;
check_errors(this->m_driver->reload_buffer(this->m_buf));
Expand Down Expand Up @@ -494,8 +502,9 @@ class FatFile : virtual public File {
this->m_logger->print(ARCHIVE_CHAR_);
}

void print_status (const bool printBlocks = false) const {
this->File::print_status("FatFileReader", printBlocks);
void print_status (const bool printBlocks = false, const bool printParentStatus = true) const {
if (printParentStatus)
this->File::print_status("FatFile", printBlocks);

this->m_logger->println("FAT-specific");
this->m_logger->println("------------");
Expand Down
22 changes: 14 additions & 8 deletions PropWare/filesystem/fat/fatfilereader.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,28 @@ class FatFileReader : virtual public FatFile, virtual public FileReader {
return FatFS::EOC_END == err ? Filesystem::FILENAME_NOT_FOUND : err;

// `name` was found successfully
return this->open_existing_file(fileEntryOffset);
check_errors(this->open_existing_file(fileEntryOffset));
this->m_open = true;
return NO_ERROR;
}

PropWare::ErrorCode safe_get_char (char &c) {
PropWare::ErrorCode err;

check_errors(this->load_sector_under_ptr());
if (this->m_open) {
check_errors(this->load_sector_under_ptr());

// Get the character
const uint16_t bufferOffset = (uint16_t) (this->m_ptr % this->m_driver->get_sector_size());
c = this->m_buf->buf[bufferOffset];
// Get the character
const uint16_t bufferOffset = (uint16_t) (this->m_ptr % this->m_driver->get_sector_size());
c = this->m_buf->buf[bufferOffset];

// Finally done. Increment the pointer
++(this->m_ptr);
// Finally done. Increment the pointer
++(this->m_ptr);

return NO_ERROR;
return NO_ERROR;
} else {
return FILE_NOT_OPEN;
}
}
};

Expand Down
Loading

0 comments on commit deefc11

Please sign in to comment.