diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index 03947e196..38aa68fed 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -33,8 +33,9 @@ IF ( SDL_FOUND ) INCLUDE_DIRECTORIES( ${SDL_INCLUDE_DIR} ) MESSAGE("SDL Include Path: " ${SDL_INCLUDE_DIR} ) ADD_DEFINITIONS( -DJOYSTICKS ) + ADD_DEFINITIONS( -DSIMU_AUDIO ) ELSE() - MESSAGE( "SDL not found! Joysticks support will be disabled" ) + MESSAGE( "SDL not found! Joysticks support will be disabled. Simulator audio will not work." ) ENDIF() FIND_PACKAGE(Qt4 4.8.4 REQUIRED) diff --git a/companion/src/firmwares/opentx/opentxSky9xsimulator.cpp b/companion/src/firmwares/opentx/opentxSky9xsimulator.cpp index 53f8f2c78..e16ccad12 100644 --- a/companion/src/firmwares/opentx/opentxSky9xsimulator.cpp +++ b/companion/src/firmwares/opentx/opentxSky9xsimulator.cpp @@ -198,7 +198,7 @@ bool Open9xSky9xSimulator::timer10ms() #include "simulatorimport.h" } -uint8_t * Open9xSky9xSimulator::getLcd() +::uint8_t * Open9xSky9xSimulator::getLcd() { #define GETLCD_IMPORT #include "simulatorimport.h" @@ -215,6 +215,7 @@ void Open9xSky9xSimulator::start(QByteArray & eeprom, bool tests) g_rotenc[0] = 0; memcpy(Open9xSky9x::eeprom, eeprom.data(), std::min(sizeof(Open9xSky9x::eeprom), eeprom.size())); StartEepromThread(NULL); + StartAudioThread(); StartMainThread(tests); } @@ -222,12 +223,14 @@ void Open9xSky9xSimulator::start(const char * filename, bool tests) { g_rotenc[0] = 0; StartEepromThread(filename); + StartAudioThread(); StartMainThread(tests); } void Open9xSky9xSimulator::stop() { StopMainThread(); + StopAudioThread(); StopEepromThread(); } @@ -249,27 +252,27 @@ void Open9xSky9xSimulator::setValues(TxInputs &inputs) void Open9xSky9xSimulator::setTrim(unsigned int idx, int value) { idx = Open9xSky9x::modn12x3[4*getStickMode() + idx]; - uint8_t phase = getTrimFlightPhase(getFlightMode(), idx); + ::uint8_t phase = getTrimFlightPhase(getFlightMode(), idx); setTrimValue(phase, idx, value); } void Open9xSky9xSimulator::getTrims(Trims & trims) { - uint8_t phase = getFlightMode(); + ::uint8_t phase = getFlightMode(); trims.extended = hasExtendedTrims(); - for (uint8_t idx=0; idx<4; idx++) { + for (::uint8_t idx=0; idx<4; idx++) { trims.values[idx] = getTrimValue(getTrimFlightPhase(phase, idx), idx); } for (int i=0; i<2; i++) { - uint8_t idx = Open9xSky9x::modn12x3[4*getStickMode() + i]; - int16_t tmp = trims.values[i]; + ::uint8_t idx = Open9xSky9x::modn12x3[4*getStickMode() + i]; + ::int16_t tmp = trims.values[i]; trims.values[i] = trims.values[idx]; trims.values[idx] = tmp; } } -void Open9xSky9xSimulator::wheelEvent(uint8_t steps) +void Open9xSky9xSimulator::wheelEvent(::uint8_t steps) { g_rotenc[0] += steps*4; } @@ -292,7 +295,7 @@ const char * Open9xSky9xSimulator::getError() #include "simulatorimport.h" } -void Open9xSky9xSimulator::setTrainerInput(unsigned int inputNumber, int16_t value) +void Open9xSky9xSimulator::setTrainerInput(unsigned int inputNumber, ::int16_t value) { #define SETTRAINER_IMPORT #include "simulatorimport.h" diff --git a/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp b/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp index 9f7065c19..3fd6fb343 100644 --- a/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp +++ b/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp @@ -145,10 +145,9 @@ inline int geteepromsize() { #include "radio/src/haptic.cpp" #include "radio/src/sbus.cpp" #include "radio/src/targets/taranis/haptic_driver.cpp" -// TODO Because FatFS in not C++ there cannot be namespaces there and the functions are defined several times! -#undef SDCARD +// Because FatFS in not C++ there cannot be namespaces there and the functions are defined several times! +#define SKIP_FATFS_DECLARATION #include "radio/src/targets/simu/simpgmspace.cpp" -#define SDCARD #include "radio/src/translations.cpp" #include "radio/src/gui/Taranis/fonts.cpp" #include "radio/src/telemetry/telemetry.cpp" @@ -245,7 +244,7 @@ bool OpentxTaranisSimulator::timer10ms() #include "simulatorimport.h" } -uint8_t * OpentxTaranisSimulator::getLcd() +::uint8_t * OpentxTaranisSimulator::getLcd() { #define GETLCD_IMPORT #include "simulatorimport.h" @@ -261,18 +260,21 @@ void OpentxTaranisSimulator::start(QByteArray & eeprom, bool tests) { memcpy(Open9xX9D::eeprom, eeprom.data(), std::min(sizeof(Open9xX9D::eeprom), eeprom.size())); StartEepromThread(NULL); + StartAudioThread(); StartMainThread(tests); } void OpentxTaranisSimulator::start(const char * filename, bool tests) { StartEepromThread(filename); + StartAudioThread(); StartMainThread(tests); } void OpentxTaranisSimulator::stop() { StopMainThread(); + StopAudioThread(); StopEepromThread(); } @@ -292,27 +294,27 @@ void OpentxTaranisSimulator::setValues(TxInputs &inputs) void OpentxTaranisSimulator::setTrim(unsigned int idx, int value) { idx = Open9xX9D::modn12x3[4*getStickMode() + idx]; - uint8_t phase = getTrimFlightPhase(getFlightMode(), idx); + ::uint8_t phase = getTrimFlightPhase(getFlightMode(), idx); setTrimValue(phase, idx, value); } void OpentxTaranisSimulator::getTrims(Trims & trims) { - uint8_t phase = getFlightMode(); + ::uint8_t phase = getFlightMode(); trims.extended = hasExtendedTrims(); - for (uint8_t idx=0; idx<4; idx++) { + for (::uint8_t idx=0; idx<4; idx++) { trims.values[idx] = getTrimValue(getTrimFlightPhase(phase, idx), idx); } for (int i=0; i<2; i++) { - uint8_t idx = Open9xX9D::modn12x3[4*getStickMode() + i]; - int16_t tmp = trims.values[i]; + ::uint8_t idx = Open9xX9D::modn12x3[4*getStickMode() + i]; + ::int16_t tmp = trims.values[i]; trims.values[i] = trims.values[idx]; trims.values[idx] = tmp; } } -void OpentxTaranisSimulator::wheelEvent(uint8_t steps) +void OpentxTaranisSimulator::wheelEvent(::uint8_t steps) { // g_rotenc[0] += steps*4; } @@ -335,12 +337,12 @@ const char * OpentxTaranisSimulator::getError() #include "simulatorimport.h" } -void OpentxTaranisSimulator::sendTelemetry(uint8_t * data, unsigned int len) +void OpentxTaranisSimulator::sendTelemetry(::uint8_t * data, unsigned int len) { processSportPacket(data); } -void OpentxTaranisSimulator::setTrainerInput(unsigned int inputNumber, int16_t value) +void OpentxTaranisSimulator::setTrainerInput(unsigned int inputNumber, ::int16_t value) { #define SETTRAINER_IMPORT #include "simulatorimport.h" diff --git a/companion/src/simulation/simulatorimport.h b/companion/src/simulation/simulatorimport.h index 48d3b5e0a..2791ad7c0 100644 --- a/companion/src/simulation/simulatorimport.h +++ b/companion/src/simulation/simulatorimport.h @@ -106,6 +106,6 @@ return main_thread_error; #ifdef SETTRAINER_IMPORT #undef SETTRAINER_IMPORT ppmInValid = 100; - g_ppmIns[inputNumber] = LIMIT(-512, value, 512); + g_ppmIns[inputNumber] = LIMIT< ::int16_t>(-512, value, 512); #endif diff --git a/radio/src/Makefile b/radio/src/Makefile index a11ce208a..41b158a65 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -348,6 +348,10 @@ TARANIS_INTERNAL_PPM = NO # Values = NO, YES SIMU_DISKIO = NO +# Enable audio in simulator +# Values = NO, YES +SIMU_AUDIO = NO + #------- END BUILD OPTIONS --------------------------- # Define programs and commands. @@ -1567,13 +1571,20 @@ FOXLIB=-L/usr/local/lib \ -lFOX-1.6 \ -Wl,-rpath,$(FOXPATH)/src/.libs +SIMUDEFS = -DSIMU -DLUA_USE_APICHECK +ifeq ($(SIMU_AUDIO), YES) + AUDIOLIB = -L/usr/lib/x86_64-linux-gnu/ -lSDLmain -lSDL + AUDIOINC = -I/usr/include/SDL + SIMUDEFS += -DSIMU_AUDIO +endif + ifeq ($(SIMU_DISKIO), YES) - CPPDEFS += -DSIMU_DISKIO CPPSRC += FatFs/ff.c FatFs/option/ccsbcs.c + SIMUDEFS += -DSIMU_DISKIO endif simu: $(LUADEP) stamp_header allsimusrc.cpp Makefile simu.cpp targets/simu/simpgmspace.cpp *.h tra lbm eeprom.bin - g++ $(CPPFLAGS) $(INCFLAGS) simu.cpp allsimusrc.cpp $(LUASRC) targets/simu/simpgmspace.cpp -MD -DSIMU -DLUA_USE_APICHECK -O0 -o simu $(FOXINC) $(FOXLIB) -pthread -fexceptions + g++ $(CPPFLAGS) $(INCFLAGS) simu.cpp allsimusrc.cpp $(LUASRC) targets/simu/simpgmspace.cpp -MD $(SIMUDEFS) -O0 -o simu $(FOXINC) $(FOXLIB) $(AUDIOINC) $(AUDIOLIB) -pthread -fexceptions eeprom.bin: dd if=/dev/zero of=$@ bs=1 count=2048 diff --git a/radio/src/audio_arm.cpp b/radio/src/audio_arm.cpp index 22789a2f5..52e97764b 100644 --- a/radio/src/audio_arm.cpp +++ b/radio/src/audio_arm.cpp @@ -362,14 +362,17 @@ void referenceModelAudioFiles() // Eliminates directories / non wav files if (len < 5 || strcasecmp(fn+len-4, SOUNDS_EXT) || (fno.fattrib & AM_DIR)) continue; + TRACE("referenceModelAudioFiles(): using file: %s", fn); // Phases Audio Files -[on|off].wav for (int i=0; i-[up|mid|down].wav for (int i=0; i> fade) ), 0xFFFF); +#else *result = limit(0, *result + ((sample >> fade) >> 4), 4095); +#endif } -#if defined(SDCARD) && !defined(SIMU) +#if defined(SDCARD) #define RIFF_CHUNK_SIZE 12 uint8_t wavBuffer[AUDIO_BUFFER_SIZE*2]; @@ -695,7 +706,11 @@ void AudioQueue::wakeup() // write silence in the buffer for (uint32_t i=0; idata[i] = 0x8000; /* silence */ +#else buffer->data[i] = 0x8000 >> 4; /* silence */ +#endif } // mix the priority context (only tones) @@ -751,6 +766,7 @@ void AudioQueue::wakeup() // push the buffer if needed if (size > 0) { __disable_irq(); + // TRACE("pushing buffer %d\n", bufferWIdx); bufferWIdx = nextBufferIdx(bufferWIdx); buffer->size = size; buffer->state = dacQueue(buffer) ? AUDIO_BUFFER_PLAYING : AUDIO_BUFFER_FILLED; @@ -793,6 +809,10 @@ bool AudioQueue::isPlaying(uint8_t id) void AudioQueue::playTone(uint16_t freq, uint16_t len, uint16_t pause, uint8_t flags, int8_t freqIncr) { +#if defined(SIMU) && !defined(SIMU_AUDIO) + return; +#endif + CoEnterMutexSection(audioMutex); if (freq && freq < BEEP_MIN_FREQ) { @@ -849,9 +869,13 @@ void AudioQueue::playFile(const char *filename, uint8_t flags, uint8_t id) TRACE("playFile(\"%s\", flags=%x, id=%d)", filename, flags, id); if (strlen(filename) > AUDIO_FILENAME_MAXLEN) { TRACE("file name too long! maximum length is %d characters", AUDIO_FILENAME_MAXLEN); + return; } - fflush(stdout); -#else + #if !defined(SIMU_AUDIO) + return; + #endif +#endif + if (!sdMounted()) return; @@ -887,7 +911,6 @@ void AudioQueue::playFile(const char *filename, uint8_t flags, uint8_t id) } CoLeaveMutexSection(audioMutex); -#endif } void AudioQueue::stopPlay(uint8_t id) @@ -896,6 +919,10 @@ void AudioQueue::stopPlay(uint8_t id) TRACE("stopPlay(id=%d)", id); #endif +#if defined(SIMU) && !defined(SIMU_AUDIO) + return; +#endif + // For the moment it's only needed to stop the background music if (backgroundContext.fragment.id == id) { backgroundContext.fragment.type = FRAGMENT_EMPTY; diff --git a/radio/src/audio_arm.h b/radio/src/audio_arm.h index ddacdde09..b3a5fb5ba 100644 --- a/radio/src/audio_arm.h +++ b/radio/src/audio_arm.h @@ -46,7 +46,11 @@ #define AUDIO_SAMPLE_RATE (32000) #define AUDIO_BUFFER_DURATION (10) #define AUDIO_BUFFER_SIZE (AUDIO_SAMPLE_RATE*AUDIO_BUFFER_DURATION/1000) -#define AUDIO_BUFFER_COUNT (3) +#if defined(SIMU_AUDIO) + #define AUDIO_BUFFER_COUNT (10) // simulator needs more buffers for smooth audio +#else + #define AUDIO_BUFFER_COUNT (3) +#endif #define BEEP_MIN_FREQ (150) #define BEEP_DEFAULT_FREQ (2250) @@ -155,6 +159,9 @@ bool dacQueue(AudioBuffer *buffer); class AudioQueue { friend void audioTask(void* pdata); +#if defined(SIMU_AUDIO) + friend void *audio_thread(void *); +#endif public: @@ -196,7 +203,7 @@ class AudioQueue { } uint8_t idx = bufferRIdx; - while (idx != bufferWIdx) { + do { AudioBuffer * buffer = &buffers[idx]; if (buffer->state == AUDIO_BUFFER_FILLED) { buffer->state = AUDIO_BUFFER_PLAYING; @@ -204,11 +211,23 @@ class AudioQueue { return buffer; } idx = nextBufferIdx(idx); - } + } while (idx != bufferWIdx); //this fixes a bug if all buffers are filled return NULL; } + bool filledAtleast(int noBuffers) { + int count = 0; + for(int n= 0; n= noBuffers) { + return true; + } + } + } + return false; + } + protected: void wakeup(); diff --git a/radio/src/simu.cpp b/radio/src/simu.cpp index aba58a0d6..94679fbe3 100644 --- a/radio/src/simu.cpp +++ b/radio/src/simu.cpp @@ -134,6 +134,7 @@ Open9xSim::Open9xSim(FXApp* a): Open9xSim::~Open9xSim() { StopMainThread(); + StopAudioThread(); StopEepromThread(); delete bmp; @@ -430,6 +431,7 @@ int main(int argc,char **argv) printf("Model size = %d\n", (int)sizeof(g_model)); StartEepromThread(argc >= 2 ? argv[1] : "eeprom.bin"); + StartAudioThread(); StartMainThread(); #if defined(PCBTARANIS) diff --git a/radio/src/targets/simu/simpgmspace.cpp b/radio/src/targets/simu/simpgmspace.cpp index 2150bfc93..cfa5fbf74 100644 --- a/radio/src/targets/simu/simpgmspace.cpp +++ b/radio/src/targets/simu/simpgmspace.cpp @@ -51,6 +51,10 @@ FILE * diskImage = 0; #endif +#if defined(SIMU_AUDIO) && defined(CPUARM) + #include +#endif + volatile uint8_t pina=0xff, pinb=0xff, pinc=0xff, pind, pine=0xff, pinf=0xff, ping=0xff, pinh=0xff, pinj=0xff, pinl=0; uint8_t portb, portc, porth=0, dummyport; uint16_t dummyport16; @@ -89,7 +93,7 @@ Adc Adc0; #define EESIZE_SIMU EESIZE #endif -#if defined(SDCARD) +#if defined(SDCARD) && !defined(SKIP_FATFS_DECLARATION) char simuSdDirectory[1024] = ""; #endif @@ -402,7 +406,7 @@ void StartMainThread(bool tests) pthread_mutex_init(&audioMutex, NULL); #endif - g_tmr10ms = 0; + g_tmr10ms = 1; // must be non-zero otherwise some SF functions (that use this timer as a marker when it was last executed) will be executed twice on startup #if defined(RTCLOCK) g_rtcTime = time(0); #endif @@ -417,7 +421,130 @@ void StopMainThread() pthread_join(main_thread_pid, NULL); } +#if defined(CPUARM) +int Volume = volumeScale[VOLUME_LEVEL_DEF]; +bool dacQueue(AudioBuffer *buffer) +{ + return false; +} + +void setVolume(uint8_t volume) +{ + Volume = volumeScale[min(volume, VOLUME_LEVEL_MAX)]; +} +#endif + +#if defined(SIMU_AUDIO) && defined(CPUARM) + +int leftover_len = 0; +uint16_t leftover_data[AUDIO_BUFFER_SIZE]; + +void copyBuffer(uint8_t * dest, uint16_t * buff, unsigned int samples) +{ + for(unsigned int i=0; i= nextBuffer->size*2) { + copyBuffer(stream, nextBuffer->data, nextBuffer->size); + stream += nextBuffer->size*2; + len -= nextBuffer->size*2; + // putchar('+'); + } + else { + //partial + copyBuffer(stream, nextBuffer->data, len/2); + leftover_len = (nextBuffer->size-len/2); + memcpy(leftover_data, &nextBuffer->data[len/2], leftover_len*2); + len = 0; + // putchar('p'); + break; + } + } + else { + break; + } + } + } + + //fill the rest of buffer with silence + if (len > 0) { + SDL_memset(stream, 0x8000, len); // make sure this is silence. + // putchar('.'); + } +} + +bool audio_thread_running = false; + +void *audio_thread(void *) +{ + SDL_AudioSpec wanted, have; + + /* Set the audio format */ + wanted.freq = AUDIO_SAMPLE_RATE; + wanted.format = AUDIO_S16SYS; + wanted.channels = 1; /* 1 = mono, 2 = stereo */ + wanted.samples = AUDIO_BUFFER_SIZE*2; /* Good low-latency value for callback */ + wanted.callback = fill_audio; + wanted.userdata = NULL; + + /* Open the audio device, forcing the desired format */ + if ( SDL_OpenAudio(&wanted, &have) < 0 ) { + fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); + return 0; + } + SDL_PauseAudio(0); + + while (audio_thread_running) { + audioQueue.wakeup(); + sleep(1); + } + SDL_CloseAudio(); + return 0; +} + +pthread_t audio_thread_pid; + +void StartAudioThread() +{ + pthread_attr_t attr; + pthread_attr_init(&attr); + struct sched_param sp; + sp.sched_priority = SCHED_RR; + pthread_attr_setschedparam(&attr, &sp); + pthread_create(&audio_thread_pid, &attr, &audio_thread, NULL); + audio_thread_running = true; + return; +} + +void StopAudioThread() +{ + audio_thread_running = false; + pthread_join(audio_thread_pid, NULL); +} +#endif // #if defined(CPUARM) + pthread_t eeprom_thread_pid; + void StartEepromThread(const char *filename) { eepromFile = filename; @@ -510,16 +637,23 @@ static void EeFsDump(){ } #endif -#if defined(SDCARD) && !defined(SIMU_DISKIO) +#if defined(SDCARD) && !defined(SKIP_FATFS_DECLARATION) && !defined(SIMU_DISKIO) namespace simu { #include +#if !defined WIN32 + #include +#endif } #include "FatFs/ff.h" #if defined WIN32 || !defined __GNUC__ #include +#include #endif +#include +#include + #if defined(CPUARM) FATFS g_FATFS_Obj; #endif @@ -535,11 +669,89 @@ char *convertSimuPath(const char *path) return result; } +typedef std::map filemap_t; + +filemap_t fileMap; + +char *findTrueFileName(const char *path) +{ + TRACE("findTrueFileName(%s)", path); + static char result[1024]; + filemap_t::iterator i = fileMap.find(path); + if (i != fileMap.end()) { + strcpy(result, i->second.c_str()); + TRACE("\tfound in map: %s", result); + return result; + } + else { + //find file + //add to map +#if defined WIN32 || !defined __GNUC__ + char drive[_MAX_DRIVE]; + char dir[_MAX_DIR]; + char fname[_MAX_FNAME]; + char ext[_MAX_EXT]; + _splitpath(path, drive, dir, fname, ext); + std::string fileName = std::string(fname) + "." + std::string(ext); + std::string dirName = std::string(drive) + std::string(dir); + if (dir) { + // TRACE("\tsearching for: %s", fileName.c_str()); + WIN32_FIND_DATA ffd; + HANDLE hFind = FindFirstFile(dirName.c_str(), &ffd); + if (INVALID_HANDLE_VALUE != hFind) { + do { + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == 0) { + // TRACE("comparing with: %s", ffd.cFileName); + if (!strcasecmp(fileName.c_str(), ffd.cFileName)) { + strcpy(result, dirName.c_str()); + strcat(result, "/"); + strcat(result, ffd.cFileName); + TRACE("\tfound: %s", ffd.cFileName); + fileMap.insert(filemap_t:: value_type(path, result)); + return result; + } + } + } + while (FindNextFile(hFind, &ffd) != 0); + } + } +#else + strcpy(result, path); + std::string fileName = simu::basename(result); + strcpy(result, path); + std::string dirName = simu::dirname(result); + simu::DIR * dir = simu::opendir(dirName.c_str()); + if (dir) { + // TRACE("\tsearching for: %s", fileName.c_str()); + for (;;) { + struct simu::dirent * res = simu::readdir(dir); + if (res == 0) break; + if ((res->d_type == simu::DT_REG) || (res->d_type == simu::DT_LNK)) { + // TRACE("comparing with: %s", res->d_name); + if (!strcasecmp(fileName.c_str(), res->d_name)) { + strcpy(result, dirName.c_str()); + strcat(result, "/"); + strcat(result, res->d_name); + TRACE("\tfound: %s", res->d_name); + fileMap.insert(filemap_t:: value_type(path, result)); + return result; + } + } + } + } +#endif + } + TRACE("\tnot found"); + strcpy(result, path); + return result; +} + FRESULT f_stat (const TCHAR * name, FILINFO *) { char *path = convertSimuPath(name); + char * realPath = findTrueFileName(path); struct stat tmp; - if (stat(path, &tmp)) { + if (stat(realPath, &tmp)) { TRACE("f_stat(%s) = error %d (%s)", path, errno, strerror(errno)); return FR_INVALID_NAME; } @@ -557,17 +769,19 @@ FRESULT f_mount (FATFS* ,const TCHAR*, BYTE opt) FRESULT f_open (FIL * fil, const TCHAR *name, BYTE flag) { char *path = convertSimuPath(name); + char * realPath = findTrueFileName(path); if (!(flag & FA_WRITE)) { struct stat tmp; - if (stat(path, &tmp)) { + if (stat(realPath, &tmp)) { TRACE("f_open(%s) = INVALID_NAME", path); return FR_INVALID_NAME; } fil->fsize = tmp.st_size; } - fil->fs = (FATFS*)fopen(path, (flag & FA_WRITE) ? "wb+" : "rb+"); - if ( fil->fs ) { - TRACE("f_open(%s) = OK", path); + fil->fs = (FATFS*)fopen(realPath, (flag & FA_WRITE) ? "wb+" : "rb+"); + fil->fptr = 0; + if (fil->fs) { + TRACE("f_open(%s) = %p", path, (FILE*)fil->fs); return FR_OK; } TRACE("f_open(%s) = error %d (%s)", path, errno, strerror(errno)); @@ -578,6 +792,7 @@ FRESULT f_read (FIL* fil, void* data, UINT size, UINT* read) { if (fil && fil->fs) { *read = fread(data, 1, size, (FILE*)fil->fs); + fil->fptr += *read; // TRACE("fread(%p) %u, %u", fil->fs, size, *read); } return FR_OK; @@ -587,6 +802,7 @@ FRESULT f_write (FIL* fil, const void* data, UINT size, UINT* written) { if (fil && fil->fs) { *written = fwrite(data, 1, size, (FILE*)fil->fs); + fil->fptr += size; // TRACE("fwrite(%p) %u, %u", fil->fs, size, *written); } return FR_OK; @@ -595,12 +811,14 @@ FRESULT f_write (FIL* fil, const void* data, UINT size, UINT* written) FRESULT f_lseek (FIL* fil, DWORD offset) { if (fil && fil->fs) fseek((FILE*)fil->fs, offset, SEEK_SET); + fil->fptr = offset; return FR_OK; } FRESULT f_close (FIL * fil) { if (fil && fil->fs) { + TRACE("f_close(%p)", (FILE*)fil->fs); fclose((FILE*)fil->fs); fil->fs = NULL; } @@ -724,7 +942,7 @@ int32_t Card_state = SD_ST_MOUNTED; uint32_t Card_CSD[4]; // TODO elsewhere #endif -#endif // #if defined(SDCARD) && !defined(SIMU_DISKIO) +#endif // #if defined(SDCARD) && !defined(SKIP_FATFS_DECLARATION) && !defined(SIMU_DISKIO) #if defined(SIMU_DISKIO) diff --git a/radio/src/targets/simu/simpgmspace.h b/radio/src/targets/simu/simpgmspace.h index 84398bf21..3a984072c 100644 --- a/radio/src/targets/simu/simpgmspace.h +++ b/radio/src/targets/simu/simpgmspace.h @@ -363,6 +363,13 @@ void StartMainThread(bool tests=true); void StopMainThread(); void StartEepromThread(const char *filename="eeprom.bin"); void StopEepromThread(); +#if defined(SIMU_AUDIO) && defined(CPUARM) + void StartAudioThread(void); + void StopAudioThread(void); +#else + #define StartAudioThread() + #define StopAudioThread() +#endif extern const char *eepromFile; #if defined(PCBTARANIS) || defined(PCBACT) diff --git a/radio/src/targets/sky9x/audio_driver.cpp b/radio/src/targets/sky9x/audio_driver.cpp index 4cfe0b25b..0a9c096a6 100644 --- a/radio/src/targets/sky9x/audio_driver.cpp +++ b/radio/src/targets/sky9x/audio_driver.cpp @@ -36,6 +36,14 @@ #include "../../opentx.h" +const int8_t volumeScale[VOLUME_LEVEL_MAX+1] = +{ + 0, 2, 4, 6, 8, 10, 13, 17, 22, 27, 33, 40, + 64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127 +} ; + +#if !defined(SIMU) + void setSampleRate(uint32_t frequency) { register Tc *ptc ; @@ -154,12 +162,6 @@ void audioEnd() PMC->PMC_PCER0 &= ~0x40000000L ; // Disable peripheral clock to DAC } -static const int8_t volumeScale[VOLUME_LEVEL_MAX+1] = -{ - 0, 2, 4, 6, 8, 10, 13, 17, 22, 27, 33, 40, - 64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127 -} ; - void setVolume(uint8_t volume) { volumeRequired = volumeScale[min(volume, VOLUME_LEVEL_MAX)]; @@ -169,4 +171,5 @@ void setVolume(uint8_t volume) } +#endif // #if !defined(SIMU) diff --git a/radio/src/targets/sky9x/audio_driver.h b/radio/src/targets/sky9x/audio_driver.h index 72e67fa21..f37f6eb58 100644 --- a/radio/src/targets/sky9x/audio_driver.h +++ b/radio/src/targets/sky9x/audio_driver.h @@ -55,6 +55,8 @@ inline void dacStop() #define VOLUME_LEVEL_MAX 23 #define VOLUME_LEVEL_DEF 12 +extern const int8_t volumeScale[]; + void setVolume(uint8_t volume); #endif diff --git a/radio/src/targets/taranis/audio_driver.cpp b/radio/src/targets/taranis/audio_driver.cpp index e34f20c09..01e7f38a0 100644 --- a/radio/src/targets/taranis/audio_driver.cpp +++ b/radio/src/targets/taranis/audio_driver.cpp @@ -36,6 +36,13 @@ #include "../../opentx.h" +const int8_t volumeScale[VOLUME_LEVEL_MAX+1] = +{ + 0, 1, 2, 3, 5, 9, 13, 17, 22, 27, 33, 40, + 64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127 +}; + +#if !defined(SIMU) bool dacIdle = true; void setSampleRate(uint32_t frequency) @@ -139,7 +146,6 @@ void audioEnd() NVIC_DisableIRQ(DMA1_Stream5_IRQn) ; } -#if !defined(SIMU) extern "C" void TIM6_DAC_IRQHandler() { DAC->CR &= ~DAC_CR_DMAEN1 ; // Stop DMA requests @@ -167,7 +173,7 @@ extern "C" void DMA1_Stream5_IRQHandler() dacIdle = true; } } -#endif +#endif // #if !defined(SIMU) #if 0 static void Audio_GPIO_Init() diff --git a/radio/src/targets/taranis/audio_driver.h b/radio/src/targets/taranis/audio_driver.h index ea277a8ed..7d52c5203 100644 --- a/radio/src/targets/taranis/audio_driver.h +++ b/radio/src/targets/taranis/audio_driver.h @@ -46,16 +46,12 @@ extern void setSampleRate(uint32_t frequency); #define VOLUME_LEVEL_MAX 23 #define VOLUME_LEVEL_DEF 12 -static const int8_t volumeScale[VOLUME_LEVEL_MAX+1] = -{ - 0, 1, 2, 3, 5, 9, 13, 17, 22, 27, 33, 40, - 64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127 -} ; +extern const int8_t volumeScale[]; #if !defined(SIMU) #define setVolume(v) I2C_set_volume(volumeScale[min(v, VOLUME_LEVEL_MAX)]) #else -#define setVolume(v) +void setVolume(uint8_t volume); #endif #endif