diff --git a/g2core/board/G2v9/0_hardware.cpp b/g2core/board/G2v9/0_hardware.cpp index 445dad43..c56cec19 100644 --- a/g2core/board/G2v9/0_hardware.cpp +++ b/g2core/board/G2v9/0_hardware.cpp @@ -33,11 +33,11 @@ #include "controller.h" #include "text_parser.h" #include "board_xio.h" -#include "sd_card.h" #include "MotateUtilities.h" #include "MotateUniqueID.h" #include "MotatePower.h" +#include "board_spi.h" /* * hardware_init() - lowest level hardware init @@ -45,13 +45,8 @@ SPIBus_used_t spiBus; -extern SDCard sd_card; - -SDCard sd_card { - spiBus, - Motate::SPIChipSelectPin{} -}; - +Motate::SPIChipSelectPin sdcs{}; +SDCard_used_t sd_card{spiBus, sdcs}; void hardware_init() { diff --git a/g2core/board/G2v9/board_spi.h b/g2core/board/G2v9/board_spi.h new file mode 100644 index 00000000..3b75db7a --- /dev/null +++ b/g2core/board/G2v9/board_spi.h @@ -0,0 +1,42 @@ +/* + * * gpio.h - SPI definitions for this board + * For: /board/g2v9 + * This file is part of the g2core project + * + * Copyright (c) 2019 Robert Giseburt + * + * This file ("the software") is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 as published by the + * Free Software Foundation. You should have received a copy of the GNU General Public + * License, version 2 along with the software. If not, see . + * + * As a special exception, you may use this file as part of a software library without + * restriction. Specifically, if other files instantiate templates or use macros or + * inline functions from this file, or you compile this file and link it with other + * files to produce an executable, this file does not by itself cause the resulting + * executable to be covered by the GNU General Public License. This exception does not + * however invalidate any other reasons why the executable file might be covered by the + * GNU General Public License. + * + * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY + * 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 BOARD_SPI_H_ONCE +#define BOARD_SPI_H_ONCE + +#include "MotateSPI.h" +#include "sd_card.h" + +/**** SPI Setup ****/ +typedef Motate::SPIBus SPIBus_used_t; +extern SPIBus_used_t spiBus; + +typedef SDCard> SDCard_used_t; +extern SDCard_used_t sd_card; + +#endif // BOARD_SPI_H_ONCE diff --git a/g2core/board/G2v9/hardware.h b/g2core/board/G2v9/hardware.h index 7da4c625..5658c940 100644 --- a/g2core/board/G2v9/hardware.h +++ b/g2core/board/G2v9/hardware.h @@ -60,8 +60,8 @@ *************************/ #include "MotatePins.h" -#include "MotateSPI.h" #include "MotateTimers.h" // for TimerChanel<> and related... +#include "MotateUtilities.h" // for TimerChanel<> and related... using Motate::TimerChannel; @@ -119,14 +119,6 @@ typedef TimerChannel<5,0> fwd_plan_timer_type; // request exec timer in stepper. pin_number indicator_led_pin_num = Motate::kLED_USBRXPinNumber; static PWMOutputPin IndicatorLed; -/**** SPI Setup ****/ -typedef Motate::SPIBus SPIBus_used_t; -extern SPIBus_used_t spiBus; - -// typedef Motate::SPIChipSelectPinMux SPI_CS_PinMux_used_t; -// extern SPI_CS_PinMux_used_t spiCSPinMux; - - /**** Motate Global Pin Allocations ****/ //static OutputPin spi_ss1_pin; diff --git a/g2core/boards.mk b/g2core/boards.mk index 3f612b1a..a08c112b 100644 --- a/g2core/boards.mk +++ b/g2core/boards.mk @@ -53,6 +53,7 @@ endif ifeq ("$(CONFIG)","MiniMill") ifeq ("$(BOARD)","NONE") BOARD=g2v9k + BANTAM=1 endif SETTINGS_FILE="settings_minimill.h" endif diff --git a/g2core/device/sd_card/diskio.cpp b/g2core/device/sd_card/diskio.cpp index 382541b1..39144c0a 100644 --- a/g2core/device/sd_card/diskio.cpp +++ b/g2core/device/sd_card/diskio.cpp @@ -4,16 +4,15 @@ #include #include -// SD Card -extern SDCard sd_card; +#include "board_spi.h" // Card Detect Pin Motate::InputPin cdPin; - + /*-------------------------------------------------------------------------- - + Module Private Functions - + ---------------------------------------------------------------------------*/ static volatile @@ -34,20 +33,20 @@ int rcvr_datablock ( /* 1:OK, 0:Failed */ ) { volatile INT token; - + uint32_t start = Motate::SysTickTimer.getValue(); do { /* Wait for data packet in timeout of 100ms */ - token = sd_card.read(SPIMessage::DeassertAfter, 0xFF); + token = sd_card.read(SPIMessage::DeassertAfter); } while ((token != 0xFE) && Motate::SysTickTimer.getValue()-start < 100); if(token != 0xFE) { return 0; /* If not valid data token, return with error */ } - + sd_card.read((uint8_t*)buff, btr); - - sd_card.read(SPIMessage::RemainAsserted, 0xFF); /* Discard CRC */ - sd_card.read(SPIMessage::RemainAsserted, 0xFF); - + + sd_card.read(SPIMessage::RemainAsserted); /* Discard CRC */ + sd_card.read(SPIMessage::RemainAsserted); + return 1; /* Return with success */ } @@ -67,9 +66,9 @@ int xmit_datablock ( /* 1:OK, 0:Failed */ BYTE resp = 0; BYTE *buff_temp = (BYTE *)buff; //ms: fix bool stop = (token == 0xFD); - + sd_card.write(token, stop); /* Xmit data token */ - + if (token != 0xFD) { /* Is data token */ sd_card.write(buff_temp, 512); sd_card.write(0xFF); /* CRC (Dummy) */ @@ -77,15 +76,15 @@ int xmit_datablock ( /* 1:OK, 0:Failed */ do { resp = sd_card.read() & 0x1F; /* Receive data response */ } while (resp == 0 || resp == 0x1F); - if (resp != 0x05) /* If not accepted, return with error */ - return 0; + if (resp != 0x05) /* If not accepted, return with error */ + return 0; } - + return 1; } #endif - +alignas(4) uint8_t data[6]; /*-----------------------------------------------------------------------*/ /* Send a command packet to MMC */ @@ -106,37 +105,37 @@ uint8_t send_cmd ( /* Returns command response (bit7==1:Send failed)*/ res = send_cmd(CMD55, 0); if (res > 1) return res; } - + // wait until card is ready to receive command - uint32_t start = Motate::SysTickTimer.getValue(); - while ((sd_card.read(SPIMessage::DeassertAfter, 0xFF) != 0xFF) && Motate::SysTickTimer.getValue() - start < 1000) {}; + Motate::Timeout timeout; + timeout.set(1000); + while ((sd_card.read(SPIMessage::DeassertAfter) != 0xFF) && !timeout.isPast()) {}; // choose the command CRC uint8_t n = 0x01; /* Dummy CRC + Stop */ if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */ if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */ - + // send command packet - uint8_t data[6] = { - (uint8_t)(0x40 | cmd), - (uint8_t)((arg >> 24) & 0xFF), - (uint8_t)((arg >> 16) & 0xFF), - (uint8_t)((arg >> 8) & 0xFF), - (uint8_t)(arg & 0xFF), - n - }; + data[0] = (0x40 | cmd); + data[1] = ((arg >> 24) & 0xFF); + data[2] = ((arg >> 16) & 0xFF); + data[3] = ((arg >> 8) & 0xFF); + data[4] = (arg & 0xFF); + data[5] = n; + sd_card.write(data, 6, SPIMessage::RemainAsserted); - + // receive response - if (cmd == CMD12) sd_card.read(SPIMessage::RemainAsserted, 0xFF); /* Skip a stuff byte when stop reading */ + if (cmd == CMD12) sd_card.read(SPIMessage::RemainAsserted); /* Skip a stuff byte when stop reading */ uint8_t tries = 0xFF; /* Wait for a valid response in timeout of 10 attempts */ do - res = sd_card.read(SPIMessage::RemainAsserted, 0xFF); + res = sd_card.read(SPIMessage::RemainAsserted); while ((res & 0x80) && --tries); // 7th bit is low in all valid responses - + if (ocr) sd_card.read(ocr, 4); - + return res; /* Return with the response value */ } @@ -147,7 +146,7 @@ uint8_t send_cmd_until_specific_response(uint8_t command, uint32_t args, uint8_t do { resp = send_cmd(command, args, ocr); } while (resp != response && attempts--); - + return (resp == response); } @@ -160,16 +159,16 @@ DSTATUS disk_initialize ( BYTE drv /* Physical drive number (0) */ ) { - BYTE n, ty, cmd, ocr[4]; - + BYTE ty, cmd, ocr[4]; + if (drv) return STA_NOINIT; /* Supports only single drive */ if (disk_status(drv) & STA_NODISK) return Stat; /* No card in the socket */ - + // initialization has to be performed at a slower speed sd_card.setOptions(SD_INIT_SPEED); - - for (n = 10; n; n--) sd_card.read(); /* 80 dummy clocks */ - + + sd_card.setSDMode(); /* 80 dummy clocks */ + ty = 0; if (send_cmd_until_specific_response(CMD0, 0, 1)) { /* Enter Idle state */ if (send_cmd(CMD8, 0x1AA, &ocr[0]) == 1) { /* SDv2? */ @@ -196,13 +195,13 @@ DSTATUS disk_initialize ( } } CardType = ty; - + if (ty) { /* Initialization succeeded */ Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ } - + sd_card.setOptions(SD_ACTIVE_SPEED); - + return Stat; } @@ -216,7 +215,7 @@ DSTATUS disk_status ( ) { if (drv != SD0) return STA_NOINIT; - + if (cdPin.getInputValue()) { Stat = STA_NODISK | STA_NOINIT; } else { @@ -242,12 +241,12 @@ DRESULT disk_read ( { if (drv || !count) return RES_PARERR; if (disk_status(drv) & (STA_NODISK | STA_NOINIT)) return RES_NOTRDY; - + if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ - + BYTE cmd; cmd = count > 1 ? CMD18 : CMD17; /* READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */ - + if (send_cmd_until_specific_response(cmd, sector, 0)) { do { if (!rcvr_datablock(buff, 512)) break; @@ -255,7 +254,7 @@ DRESULT disk_read ( } while (--count); if (cmd == CMD18) send_cmd(CMD12, 0); /* STOP_TRANSMISSION */ } - + return count ? RES_ERROR : RES_OK; } @@ -274,12 +273,12 @@ DRESULT disk_write ( ) { if (drv || !count) return RES_PARERR; - + if (disk_status(drv) & (STA_NODISK | STA_NOINIT)) return RES_NOTRDY; if (Stat & STA_PROTECT) return RES_WRPRT; - + if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ - + if (count == 1) { /* Single block write */ if (send_cmd_until_specific_response(CMD24, sector, 0) && xmit_datablock(buff, 0xFE)) @@ -296,7 +295,7 @@ DRESULT disk_write ( count = 1; } } - + return count ? RES_ERROR : RES_OK; } #endif @@ -316,17 +315,17 @@ DRESULT disk_ioctl ( DRESULT res; BYTE n, csd[16], *ptr = (BYTE*)buff; DWORD cs; - - + + if (drv) return RES_PARERR; if (disk_status(drv) & (STA_NODISK | STA_NOINIT)) return RES_NOTRDY; - + res = RES_ERROR; switch (ctrl) { case CTRL_SYNC : /* Make sure that no pending write process */ res = RES_OK; break; - + case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */ @@ -340,7 +339,7 @@ DRESULT disk_ioctl ( res = RES_OK; } break; - + case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */ if (CardType & CT_SD2) { /* SDv2 */ if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */ @@ -362,30 +361,30 @@ DRESULT disk_ioctl ( } } break; - + case MMC_GET_TYPE : /* Get card type flags (1 byte) */ *ptr = CardType; res = RES_OK; break; - + case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */ if (send_cmd(CMD9, 0) == 0 /* READ_CSD */ && rcvr_datablock(ptr, 16)) res = RES_OK; break; - + case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */ if (send_cmd(CMD10, 0) == 0 /* READ_CID */ && rcvr_datablock(ptr, 16)) res = RES_OK; break; - + case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */ if (send_cmd(CMD58, 0, ptr) == 0) { /* READ_OCR */ res = RES_OK; } break; - + case MMC_GET_SDSTAT : /* Receive SD status as a data block (64 bytes) */ if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */ sd_card.read(); @@ -393,13 +392,13 @@ DRESULT disk_ioctl ( res = RES_OK; } break; - + default: res = RES_PARERR; } - + // deselect(); - + return res; } #endif diff --git a/g2core/device/sd_card/ff.h b/g2core/device/sd_card/ff.h index 8c9bd0bb..ce787f09 100644 --- a/g2core/device/sd_card/ff.h +++ b/g2core/device/sd_card/ff.h @@ -17,6 +17,8 @@ #ifndef _FATFS #define _FATFS 80376 /* Revision ID */ +#include + #ifdef __cplusplus extern "C" { #endif @@ -119,7 +121,7 @@ typedef struct { DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */ DWORD database; /* Data start sector */ DWORD winsect; /* Current sector appearing in the win[] */ - BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ + alignas(4) BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ } FATFS; @@ -147,7 +149,7 @@ typedef struct { UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */ #endif #if !_FS_TINY - BYTE buf[_MAX_SS]; /* File private data read/write window */ + alignas(4) BYTE buf[_MAX_SS]; /* File private data read/write window */ #endif } FIL; diff --git a/g2core/device/sd_card/sd_card.h b/g2core/device/sd_card/sd_card.h index efd8e7af..7aa37b37 100644 --- a/g2core/device/sd_card/sd_card.h +++ b/g2core/device/sd_card/sd_card.h @@ -10,6 +10,8 @@ #ifndef sd_card_h #define sd_card_h +#include "MotateSPI.h" + using Motate::SPIMessage; using Motate::SPIInterrupt; using Motate::SPIDeviceMode; @@ -17,7 +19,7 @@ using Motate::SPIDeviceMode; /* Definitions */ #define SCRIBBLE_BUF_MAX 10 // Maximum number of bytes expected for toss -template +template struct SDCard final { private: // SPI and message handling properties @@ -34,20 +36,20 @@ struct SDCard final { // Timer to keep track of when we need to do another periodic update Motate::Timeout check_timer; - public: + chipSelect_t &_chip_select; + + public: // Primary constructor - templated to take any SPIBus and chipSelect type - template - SDCard(SPIBus_t &spi_bus, const chipSelect_t &_cs) - : _device{spi_bus.getDevice(_cs, // pass it the chipSelect - 4000000, - SPIDeviceMode::kSPIMode0 | SPIDeviceMode::kSPI8Bit, - 0, // min_between_cs_delay_ns - 0, // cs_to_sck_delay_ns - 0 // between_word_delay_ns - )} - { - init(); - }; + template + SDCard(SPIBus_t &spi_bus, chipSelect_t &chip_select) + : _device{spi_bus.getDevice(chip_select, // pass it the chip select + 100000, SPIDeviceMode::kSPIMode0 | SPIDeviceMode::kSPI8Bit, + 400, // min_between_chip_select_delay_ns + 400, // cs_to_sck_delay_ns + 80 // between_word_delay_ns + )}, + _chip_select{chip_select} + { init(); }; // Allow the default move constructor SDCard(SDCard &&other) = default; @@ -57,11 +59,11 @@ struct SDCard final { // Toss out buffer uint8_t _scribble_buffer[SCRIBBLE_BUF_MAX]; + uint8_t _out_buffer[512]; bool _spi_write = false; bool _spi_read = false; - bool _deassert_cs = false; - uint8_t _send_as_noop = 0x0; + bool _deassert_chip_select = SPIMessage::DeassertAfter; uint16_t _num_bytes = 0; uint8_t *_spi_data; @@ -72,19 +74,14 @@ struct SDCard final { _transmitting = true; // preemptively say we're transmitting .. as a mutex // We write before we read -- so we don't lose what we set in the registers when writing - if (_spi_write) { + if (_spi_write) { _spi_write = false; - _message.setup(_spi_data, _scribble_buffer, _num_bytes, _deassert_cs, SPIMessage::EndTransaction); + _message.setup(_spi_data, nullptr, _num_bytes, _deassert_chip_select, SPIMessage::EndTransaction); } else if (_spi_read) { _spi_read = false; - // Populate scribble buffer with no op bytes - for (int i = 0; i < _num_bytes; i++) { - _scribble_buffer[i] = _send_as_noop; - } - - _message.setup(_scribble_buffer, _spi_data, _num_bytes, _deassert_cs, SPIMessage::EndTransaction); + _message.setup(nullptr, _spi_data, _num_bytes, _deassert_chip_select, SPIMessage::EndTransaction); // otherwise we're done here } else { @@ -100,16 +97,33 @@ struct SDCard final { // Establish default values _spi_write = false; _spi_read = false; - _deassert_cs = false; - _send_as_noop = 0x0; + _deassert_chip_select = false; _num_bytes = 0; - + // mark that init has finished and set the timer _inited = true; + } + + void setSDMode() { + // _device._spi_bus->misoPin.setOptions(Motate::kPullUp); + for (size_t i = 100000; i--;) { + /* code */ + } + const auto cs_mode = _chip_select.getMode(); + _chip_select.setMode(Motate::kOutput); + _chip_select.set(); + // _device._spi_bus->misoPin.setMode(Motate::kOutput); + // _device._spi_bus->misoPin.set(); + + alignas(4) uint8_t tossme[12]; + this->read(tossme, 10); /* 80 dummy clocks */ + + _chip_select.setMode(cs_mode); + // _device._spi_bus->misoPin.setOptions(Motate::kNormal); }; - void setOptions(const uint32_t baud, const uint16_t options = (SPIDeviceMode::kSPIMode0 | SPIDeviceMode::kSPI8Bit), uint32_t min_between_cs_delay_ns = 0, uint32_t cs_to_sck_delay_ns = 0, uint32_t between_word_delay_ns = 0) { - _device.setOptions(baud, options, min_between_cs_delay_ns, cs_to_sck_delay_ns, between_word_delay_ns); + void setOptions(const uint32_t baud, const uint16_t options = (SPIDeviceMode::kSPIMode0 | SPIDeviceMode::kSPI8Bit), uint32_t min_between_chip_select_delay_ns = 400, uint32_t cs_to_sck_delay_ns = 400, uint32_t between_word_delay_ns = 80) { + _device.setOptions(baud, options, min_between_chip_select_delay_ns, cs_to_sck_delay_ns, between_word_delay_ns); } void messageDoneCallback() { @@ -120,54 +134,58 @@ struct SDCard final { _startNextReadWrite(); }; - void read(uint8_t *data, const uint16_t num_bytes, const bool deassert_cs = SPIMessage::RemainAsserted, const uint8_t send_as_noop = 0x0) { - + void read(uint8_t *data, const uint16_t num_bytes, const bool deassert_chip_select = SPIMessage::DeassertAfter) { + // Configure multi byte read _spi_read = true; _spi_data = data; - _deassert_cs = deassert_cs; - _send_as_noop = send_as_noop; + _deassert_chip_select = deassert_chip_select; _num_bytes = num_bytes; // Set up read _startNextReadWrite(); + + while (_transmitting) { + ; + } }; - uint8_t read(const bool deassert_cs = SPIMessage::RemainAsserted, const uint8_t send_as_noop = 0x0) { - - uint8_t data[1] = {0x00}; - + uint8_t read(const bool deassert_chip_select = SPIMessage::DeassertAfter) { // Configure and set up single byte read - read(data, 1, deassert_cs, send_as_noop); - - return data[0]; + read(_scribble_buffer, 1, deassert_chip_select); + + return _scribble_buffer[0]; }; - void write(uint8_t *data, const uint16_t num_bytes, const bool deassert_cs = SPIMessage::RemainAsserted) { + void write(uint8_t *data, const uint16_t num_bytes, const bool deassert_chip_select = SPIMessage::DeassertAfter) { // Configure multi byte write _spi_write = true; _spi_data = data; - _deassert_cs = deassert_cs; + _deassert_chip_select = deassert_chip_select; _num_bytes = num_bytes; // Set up write _startNextReadWrite(); + + while (_transmitting) { + ; + } }; - void write(uint8_t data, const bool deassert_cs = SPIMessage::RemainAsserted) { - + void write(uint8_t data, const bool deassert_chip_select = SPIMessage::DeassertAfter) { + _scribble_buffer[0] = data; // Configure and set up single byte write - write(&data, 1, deassert_cs); + write(_scribble_buffer, 1, deassert_chip_select); }; - + // this would be called by the project or from a SysTickHandler void periodicCheck() { if (!_inited || (check_timer.isSet() && !check_timer.isPast())) { // not yet, too soon return; } - + //TEMP //uint8_t rd = 0x2; //uint8_t noop = 0xA5; diff --git a/g2core/persistence.cpp b/g2core/persistence.cpp index 7104e2b1..3dc45f6b 100644 --- a/g2core/persistence.cpp +++ b/g2core/persistence.cpp @@ -29,12 +29,26 @@ #include "canonical_machine.h" #include "report.h" #include "util.h" +#include "board_spi.h" +#include "ff.h" /*********************************************************************************** **** STRUCTURE ALLOCATIONS ******************************************************** ***********************************************************************************/ -nvmSingleton_t nvm; +//**** persistence singleton **** + +struct nvmSingleton_t { + float tmp_value; + FATFS fat_fs; + FIL file; + uint8_t file_index; + alignas(4) uint8_t io_buffer[IO_BUFFER_SIZE]; + index_t changed_nv_indexes[MAX_WRITE_CHANGES]; + uint16_t changed_nvs; + uint32_t last_write_systick; + uint8_t write_failures; +} nvm; /*********************************************************************************** **** GENERIC STATIC FUNCTIONS AND VARIABLES *************************************** @@ -129,7 +143,7 @@ stat_t write_persistent_value(nvObj_t *nv) */ stat_t write_persistent_values_callback() -{ +{ // Check the disk status to ensure we catch card-detect pin changes. // FIXME: it would be much better to do this with an interrupt! f_polldisk(); @@ -137,7 +151,7 @@ stat_t write_persistent_values_callback() if (Motate::SysTickTimer.getValue() - nvm.last_write_systick < MIN_WRITE_INTERVAL) return (STAT_NOOP); // this check may not be necessary on ARM, but just in case... if (cm->cycle_type != CYCLE_NONE) return(STAT_NOOP); // can't write when machine is moving - + if(write_persistent_values() == STAT_OK) { nvm.changed_nvs = 0; nvm.write_failures = 0; @@ -192,7 +206,7 @@ stat_t prepare_persistence_file() // would slow down consecutive reads. However, we still need to re-validate before // every use to ensure that the card status hasn't changed. if (f_is_open(&nvm.file) && validate(&nvm.file) == FR_OK) return STAT_OK; - + // mount volume if necessary if (!nvm.fat_fs.fs_type) { fs_ritorno(f_mount(&nvm.fat_fs, "", 1), "mount"); /* Give a work area to the default drive */ @@ -201,7 +215,7 @@ stat_t prepare_persistence_file() uint8_t index = active_file_index(); fs_ritorno(f_open(&nvm.file, filenames[index], FA_READ | FA_OPEN_EXISTING), "open input"); nvm.file_index = index; - + // if CRC doesn't match, delete file and return error if (validate_persistence_file() != STAT_OK) { f_close(&nvm.file); @@ -217,7 +231,7 @@ stat_t prepare_persistence_file() /* * validate_persistence_file() * - * ARM only. Helper function that checks the CRC and byte count of the + * ARM only. Helper function that checks the CRC and byte count of the * persistence file. Assumes the file is already open. */ stat_t validate_persistence_file() @@ -228,7 +242,7 @@ stat_t validate_persistence_file() fs_ritorno(f_lseek(&nvm.file, 0), "crc check seek"); while (!f_eof(&nvm.file)) { fs_ritorno(f_read(&nvm.file, &nvm.io_buffer, IO_BUFFER_SIZE, &br), "file read during CRC check"); - + if (f_eof(&nvm.file)) { br -= std::min((UINT)CRC_LEN, br); // don't include old CRC in current CRC calculation memcpy(&filecrc, nvm.io_buffer+br, CRC_LEN); // copy old CRC out of read buffer @@ -237,7 +251,7 @@ stat_t validate_persistence_file() crc = crc32(crc, nvm.io_buffer, br); br_sum += br; } - + // how did we do? if (br_sum != nv_index_max() * NVM_VALUE_LEN) { DEBUG_PRINT("bad byte count in file: %i\n", br_sum); @@ -249,7 +263,7 @@ stat_t validate_persistence_file() /* * write_persistent_values() - * + * * ARM only. Writes all the values from the write cache to the SD card. Since we can't * rewrite individual pieces of data in the middle of an existing file, this requires * rewriting all the data into a new file. @@ -257,7 +271,7 @@ stat_t validate_persistence_file() stat_t write_persistent_values() { DEBUG_PRINT("writing new version\n"); - + FIL f_out; UINT bw; nvObj_t *nv = nv_reset_nv_list(); // sets *nv to the start of the body @@ -271,12 +285,12 @@ stat_t write_persistent_values() if (prepare_persistence_file() == STAT_OK) { fs_ritorno(f_lseek(&nvm.file, 0), "f_lseek to input file start"); } - + // open new file for writing updated values fs_ritorno(f_open(&f_out, filenames[NEXT_FILE_INDEX], FA_WRITE | FA_OPEN_ALWAYS), "open output"); fs_ritorno(f_sync(&f_out), "sync output file"); DEBUG_PRINT("opened %s for writing\n", filenames[NEXT_FILE_INDEX]); - + uint32_t crc = 0; uint16_t step = IO_BUFFER_SIZE/NVM_VALUE_LEN; @@ -286,7 +300,7 @@ stat_t write_persistent_values() UINT br = 0; f_read(&nvm.file, &nvm.io_buffer, io_byte_count, &br); DEBUG_PRINT("read %i bytes from old file\n", br); - + // if we didn't get enough bytes from the old file, pad the buffer with defaults // to keep the length correct // FIXME: integrate this with default-setting code in config.cpp @@ -321,16 +335,16 @@ stat_t write_persistent_values() changed_nvs_idx++; } } - + // write updated values to output file and sync fs_ritorno(f_write(&f_out, &nvm.io_buffer, io_byte_count, &bw), "new file write"); if (bw != io_byte_count) return (STAT_PERSISTENCE_ERROR); fs_ritorno(f_sync(&f_out), "out sync"); - + // update CRC crc = crc32(crc, nvm.io_buffer, io_byte_count); } - + // write CRC in final 4 bytes fs_ritorno(f_write(&f_out, &crc, CRC_LEN, &bw), "write crc"); DEBUG_PRINT("wrote crc: %lu\n", crc); @@ -345,8 +359,8 @@ stat_t write_persistent_values() nvm.file_index = 0; } - // Restore units mode + // Restore units mode cm_set_distance_mode(saved_distance_mode); return (STAT_OK); -} \ No newline at end of file +} diff --git a/g2core/persistence.h b/g2core/persistence.h index 61fe4871..6ac332ad 100644 --- a/g2core/persistence.h +++ b/g2core/persistence.h @@ -29,8 +29,8 @@ #define PERSISTENCE_H_ONCE #include "config.h" // needed for nvObj_t definition -#include "ff.h" -#include "util.h" // FIXME: this won't compile if included after +// #include "ff.h" +// #include "util.h" // FIXME: this won't compile if included after #define NVM_VALUE_LEN 4 // NVM value length (float, fixed length) #define NVM_BASE_ADDR 0x0000 // base address of usable NVM @@ -40,20 +40,6 @@ #define MAX_WRITE_FAILURES 3 #define MAX_WRITE_CHANGES IO_BUFFER_SIZE // maximum number of write values that change - ms: TODO -//**** persistence singleton **** - -typedef struct nvmSingleton { - float tmp_value; - FATFS fat_fs; - FIL file; - uint8_t file_index; - uint8_t io_buffer[IO_BUFFER_SIZE]; - index_t changed_nv_indexes[MAX_WRITE_CHANGES]; - uint16_t changed_nvs; - uint32_t last_write_systick; - uint8_t write_failures; -} nvmSingleton_t; - //**** persistence function prototypes **** void persistence_init(void); @@ -62,3 +48,4 @@ stat_t write_persistent_value(nvObj_t *nv); stat_t write_persistent_values_callback(); #endif // End of include guard: PERSISTENCE_H_ONCE +//