small updates to try to catch errors.

Some changes to the library, and added CRC calculation to the copytest
sketch so it calculates and compares CRC value of in and out file.
This commit is contained in:
victorpv 2017-05-24 23:57:40 -05:00
parent 5e3bd42982
commit 0b09ae7b7d
5 changed files with 312 additions and 62 deletions

View File

@ -0,0 +1,114 @@
// =============================================================================
//
// Copyright (c) 2013-2016 Christopher Baker <http://christopherbaker.net>
//
// 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:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// 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 "CRC32.h"
#if defined(PROGMEM)
#define FLASH_PROGMEM PROGMEM
#define FLASH_READ_DWORD(x) (pgm_read_dword_near(x))
#else
#define FLASH_PROGMEM
#define FLASH_READ_DWORD(x) (*(uint32_t*)(x))
#endif
static const uint32_t crc32_table[] FLASH_PROGMEM = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
uint32_t CRC32::calculate(const void* data, size_t size)
{
CRC32 crc;
crc.update(data, size);
return crc.finalize();
}
void CRC32::reset()
{
state = ~0L;
}
void CRC32::update(uint8_t data)
{
// via http://forum.arduino.cc/index.php?topic=91179.0
uint8_t tbl_idx;
tbl_idx = state ^ (data >> (0 * 4));
state = FLASH_READ_DWORD(crc32_table + (tbl_idx & 0x0f)) ^ (state >> 4);
tbl_idx = state ^ (data >> (1 * 4));
state = FLASH_READ_DWORD(crc32_table + (tbl_idx & 0x0f)) ^ (state >> 4);
}
void CRC32::update(const void* data, size_t size)
{
const uint8_t* d = (const uint8_t*)data;
while (size--) {
update(*d++);
}
}
uint32_t CRC32::finalize(const void* data, size_t size)
{
update(data, size);
return finalize();
}
uint32_t CRC32::finalize() const
{
return ~state;
}
// Deprecated API
uint32_t CRC32::checksum(const uint8_t* data, size_t size)
{
CRC32 crc;
crc.update(data, size);
return crc.finalize();
}
uint32_t CRC32::update(uint32_t checksum, uint8_t data)
{
// via http://forum.arduino.cc/index.php?topic=91179.0
uint8_t tbl_idx;
tbl_idx = checksum ^ (data >> (0 * 4));
checksum = pgm_read_dword_near(crc32_table + (tbl_idx & 0x0f)) ^ (checksum >> 4);
tbl_idx = checksum ^ (data >> (1 * 4));
checksum = pgm_read_dword_near(crc32_table + (tbl_idx & 0x0f)) ^ (checksum >> 4);
return checksum;
}
uint32_t CRC32::update(uint32_t checksum, const uint8_t* data, size_t size)
{
while(size--) checksum = update(checksum, *data++);
return checksum;
}

View File

@ -0,0 +1,66 @@
// =============================================================================
//
// Copyright (c) 2013-2016 Christopher Baker <http://christopherbaker.net>
//
// 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:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// 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.
//
// =============================================================================
#ifndef CRC32_H
#define CRC32_H
#if defined(SPARK) || defined(PARTICLE)
#include "application.h"
#elif defined(ARDUINO)
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#endif
class CRC32
{
public:
static uint32_t calculate(const void* data, size_t size);
public:
CRC32() { reset(); }
void reset();
void update(uint8_t data);
void update(const void* data, size_t size);
uint32_t finalize(const void* data, size_t size);
uint32_t finalize() const;
// Deprecated API
__attribute__ ((deprecated))
static uint32_t checksum(const uint8_t* data, size_t size);
__attribute__ ((deprecated))
static uint32_t update(uint32_t checksum, uint8_t data);
__attribute__ ((deprecated))
static uint32_t update(uint32_t checksum, const uint8_t* data, size_t size);
private:
uint32_t state;
};
#endif

View File

@ -8,10 +8,12 @@
*/
#include "SDIO.h"
#include "STM32SdFatSdio.h"
#include "CRC32/CRC32.h"
STM32SdFatSdio sd;
SdFile myFileIn;
SdFile myFileOut;
CRC32 crc;
#define BUFSIZE 32*1024
@ -35,6 +37,9 @@ void setup() {
if (!sd.begin()) {
sd.initErrorHalt();
}
}
void loop() {
Serial.println("*************************************************");
Serial.println("Opening the read file..");
// open the file for Read
@ -66,8 +71,59 @@ void setup() {
Serial.println("*************************************************");
Serial.print("Done in ");
Serial.print(t);
Serial.print(" msecs");
}
Serial.println(" msecs");
void loop() {
/*
* CRC Calculations
*/
Serial.println("*************************************************");
Serial.println("Running CRC calculations...");
t = millis();
if (!myFileIn.open("test_in.bin", O_RDONLY)) {
sd.errorHalt("opening test_in.bin for CRC calculation failed");
}
crc.reset();
while ((nr = myFileIn.read(buf, BUFSIZE)) > 0) {
crc.update(buf,nr);
}
uint32_t checksumIn = crc.finalize();
myFileIn.close();
if (!myFileIn.open("test_out.bin", O_RDONLY)) {
sd.errorHalt("opening test_out.bin for CRC calculation failed");
}
crc.reset();
while ((nr = myFileIn.read(buf, BUFSIZE)) > 0) {
crc.update(buf,nr);
}
uint32_t checksumOut = crc.finalize();
t = millis() - t;
Serial.print("File in CRC: ");
Serial.println(checksumIn, HEX);
Serial.print("File out CRC: ");
Serial.println(checksumOut, HEX);
if (checksumIn != checksumOut) {
Serial.println("**CHECKSUM DID NOT MATCH!");
}
Serial.println("*************************************************");
Serial.print("Done in ");
Serial.print(t);
Serial.print(" msecs");
myFileIn.close();
Serial.println("Type any character to start\n");
while (!Serial.available()) {
SysCall::yield();
}
if (!myFileOut.open("test_out.bin", O_RDWR)) {
sd.errorHalt("opening test_out.bin for delete failed");
}
if (!myFileOut.remove()) {
sd.errorHalt("removing test_out.bin failed");
}
}

View File

@ -20,7 +20,9 @@ inline bool setSdErrorCode(uint8_t code, uint32_t line) {
uint8_t SDIOClass::begin() {
//GPIO_InitTypeDef GPIO_InitStruct;
if (hsd.State == HAL_SD_STATE_READY){
return true;
}
__HAL_RCC_SDIO_CLK_ENABLE();
stm32AfSDIO4BitInit(SDIO, NULL, 0, NULL, 0,
@ -77,11 +79,14 @@ uint8_t SDIOClass::begin() {
/*
* Up to here
*/
_useDMA = false;
_useDMA = true;
m_errorCode = SD_CARD_ERROR_NONE;
return true;
}
uint8_t SDIOClass::end() {
return (HAL_SD_DeInit(&hsd) == HAL_OK);
}
uint8_t SDIOClass::readBlocks(uint32_t block, uint8_t* dst, size_t nb) {
if (((uint32_t)dst & 0x3U) != 0){
@ -94,7 +99,8 @@ uint8_t SDIOClass::readBlocks(uint32_t block, uint8_t* dst, size_t nb) {
return false;
}
return HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER;
//common with dma, so it's down at the end
//return HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER;
}
else {
hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY;
@ -108,7 +114,7 @@ uint8_t SDIOClass::readBlocks(uint32_t block, uint8_t* dst, size_t nb) {
// We need to block here, until we implement a callback feature
uint32_t tickstart = HAL_GetTick();
while (hsd.State == HAL_SD_STATE_BUSY){
if((HAL_GetTick() - tickstart) >= sd_timeout)
if((HAL_GetTick() - tickstart) >= sdRdTimeout * nb)
{
/* Abort transfer and send return error */
HAL_SD_Abort(&hsd);
@ -118,9 +124,12 @@ uint8_t SDIOClass::readBlocks(uint32_t block, uint8_t* dst, size_t nb) {
if (hsd.State != HAL_SD_STATE_READY ) {
return false;
}
return HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER;
if (__HAL_SD_GET_FLAG(&hsd,SDIO_FLAG_DCRCFAIL)) {
//return false;
while (1); //stay here
}
}
return HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER;
}
uint8_t SDIOClass::writeBlocks(uint32_t block, const uint8_t* src, size_t nb) {
@ -133,7 +142,8 @@ uint8_t SDIOClass::writeBlocks(uint32_t block, const uint8_t* src, size_t nb) {
if (state != HAL_OK) {
return false;
}
return HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER;
//common with dma, so it's down at the end
//return HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER;
}
else {
hdma_sdio.Init.Direction = DMA_MEMORY_TO_PERIPH;
@ -147,13 +157,13 @@ uint8_t SDIOClass::writeBlocks(uint32_t block, const uint8_t* src, size_t nb) {
/*
* We need to block here, until we implement a callback feature
* TODO: better check if the card is still in programming mode.
* Also confirm the timeout to wait from the specs, currently sd_timeout=100
* Also confirm the timeout to wait from the specs, currently sd_timeout
* It may need to be multiplied by a factor depending on number of blocks.
* Finally, perhaps rename sd_timeout to something else
*/
uint32_t tickstart = HAL_GetTick();
while (hsd.State == HAL_SD_STATE_BUSY){
if((HAL_GetTick() - tickstart) >= sd_timeout)
if((HAL_GetTick() - tickstart) >= sdWrTimeout * nb+1)
{
/* Abort transfer and send return error */
HAL_SD_Abort(&hsd);
@ -163,9 +173,13 @@ uint8_t SDIOClass::writeBlocks(uint32_t block, const uint8_t* src, size_t nb) {
if (hsd.State != HAL_SD_STATE_READY) {
return false;
}
}
if (__HAL_SD_GET_FLAG(&hsd,SDIO_FLAG_DCRCFAIL)) {
//return false;
while (1); //stay here
}
while (HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_PROGRAMMING);
return HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER;
}
}
bool SDIOClass::erase(uint32_t firstBlock, uint32_t lastBlock) {

View File

@ -7,7 +7,7 @@
#define sdRdTimeout 100
#define sdWrTimeout 500
#define sdErTimeout 250
#define sd_timeout 2000 // timeout in ms in the new HAL API
#define sd_timeout 250 // timeout in ms in the new HAL API
/*
* Auxiliary macros to derive several names from the same values