Files
edgetx-gx12/radio/src/targets/simu/simueeprom.cpp
T

179 lines
4.2 KiB
C++

/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "opentx.h"
const char * eepromFile = NULL;
FILE * fp = NULL;
uint32_t eeprom_pointer;
uint8_t * eeprom_buffer_data;
volatile int32_t eeprom_buffer_size;
bool eeprom_read_operation;
bool eeprom_thread_running = true;
#if defined(EEPROM_SIZE)
uint8_t eeprom[EEPROM_SIZE];
#else
uint8_t * eeprom = NULL;
#endif
sem_t * eeprom_write_sem;
void eepromReadBlock (uint8_t * buffer, size_t address, size_t size)
{
assert(size);
if (fp) {
// TRACE("EEPROM read (pos=%d, size=%d)", pointer_eeprom, size);
if (fseek(fp, address, SEEK_SET) < 0)
perror("error in fseek");
if (fread(buffer, size, 1, fp) <= 0)
perror("error in fread");
}
else {
memcpy(buffer, &eeprom[address], size);
}
}
void eepromSimuWriteBlock(uint8_t * buffer, size_t address, size_t size)
{
assert(size);
if (fp) {
// TRACE("EEPROM write (pos=%d, size=%d)", pointer_eeprom, size);
if (fseek(fp, address, SEEK_SET) < 0)
perror("error in fseek");
if (fwrite(buffer, size, 1, fp) <= 0)
perror("error in fwrite");
}
else {
memcpy(&eeprom[address], buffer, size);
}
}
volatile uint8_t eepromTransferComplete = 1;
void * eeprom_thread_function(void *)
{
while (!sem_wait(eeprom_write_sem)) {
if (!eeprom_thread_running)
return NULL;
assert(eeprom_buffer_size);
if (eeprom_read_operation) {
eepromReadBlock(eeprom_buffer_data, eeprom_pointer, eeprom_buffer_size);
}
else {
eepromSimuWriteBlock(eeprom_buffer_data, eeprom_pointer, eeprom_buffer_size);
}
eepromTransferComplete = 1;
}
return 0;
}
uint8_t eepromReadStatus()
{
return 1;
}
uint8_t eepromIsTransferComplete()
{
return eepromTransferComplete;
}
void eepromTransmitData(uint32_t address, uint8_t * buffer, uint32_t size, bool read)
{
eeprom_pointer = address;
eeprom_buffer_data = buffer;
eeprom_buffer_size = size;
eeprom_read_operation = read;
eepromTransferComplete = 0;
sem_post(eeprom_write_sem);
}
#if defined(EEPROM_BLOCK_SIZE)
void eepromBlockErase(uint32_t address)
{
static uint8_t erasedBlock[EEPROM_BLOCK_SIZE]; // can't be on the stack!
memset(erasedBlock, 0xff, sizeof(erasedBlock));
eepromTransmitData(address, erasedBlock, EEPROM_BLOCK_SIZE, false);
}
#endif
void eepromStartRead(uint8_t * buffer, size_t address, size_t size)
{
assert(size);
eepromTransmitData(address, buffer, size, true);
}
void eepromStartWrite(uint8_t * buffer, size_t address, size_t size)
{
assert(size);
eepromTransmitData(address, buffer, size, false);
}
void eepromWriteBlock(uint8_t * buffer, size_t address, size_t size)
{
eepromStartWrite(buffer, address, size);
while (!eepromIsTransferComplete()) {
sleep(1/*ms*/);
}
}
pthread_t eeprom_thread_pid;
void StartEepromThread(const char * filename)
{
eepromFile = filename;
if (eepromFile) {
fp = fopen(eepromFile, "rb+");
if (!fp)
fp = fopen(eepromFile, "wb+");
if (!fp)
perror("error in fopen");
}
#ifdef __APPLE__
eeprom_write_sem = sem_open("eepromsem", O_CREAT, S_IRUSR | S_IWUSR, 0);
#else
eeprom_write_sem = (sem_t *)malloc(sizeof(sem_t));
sem_init(eeprom_write_sem, 0, 0);
#endif
eeprom_thread_running = true;
assert(!pthread_create(&eeprom_thread_pid, NULL, &eeprom_thread_function, NULL));
}
void StopEepromThread()
{
eeprom_thread_running = false;
sem_post(eeprom_write_sem);
pthread_join(eeprom_thread_pid, NULL);
#ifdef __APPLE__
sem_close(eeprom_write_sem);
#else
sem_destroy(eeprom_write_sem);
free(eeprom_write_sem);
#endif
if (fp) fclose(fp);
}