diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index a60d997ae..cba0c915d 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -474,6 +474,7 @@ set(SRC timers.cpp trainer.cpp model_init.cpp + serial.cpp ) if(GUI) diff --git a/radio/src/cli.cpp b/radio/src/cli.cpp index b08cc51ef..3be2d23c4 100644 --- a/radio/src/cli.cpp +++ b/radio/src/cli.cpp @@ -37,6 +37,8 @@ // CLI receive buffer size #define CLI_RX_BUFFER_SIZE 256 +#define CLI_PRINT_BUFFER_SIZE 128 + RTOS_TASK_HANDLE cliTaskId; RTOS_DEFINE_STACK(cliStack, CLI_STACK_SIZE); @@ -49,6 +51,50 @@ static StreamBufferHandle_t cliRxBuffer; // CLI receive call back void (*cliReceiveCallBack)(uint8_t* buf, uint32_t len) = nullptr; +// CLI send call back +static void (*cliSendCb)(void*, uint8_t) = nullptr; +static void* cliSendCtx = nullptr; + +void cliSetSendCb(void* ctx, void (*cb)(void*, uint8_t)) +{ + cliSendCb = nullptr; + cliSendCtx = ctx; + cliSendCb = cb; +} + +static void cliSerialPrintf(const char * format, ...) +{ + va_list arglist; + char tmp[CLI_PRINT_BUFFER_SIZE]; + + // no need to do anything if we don't have an output + if (!cliSendCb) return; + + va_start(arglist, format); + vsnprintf(tmp, CLI_PRINT_BUFFER_SIZE-1, format, arglist); + tmp[CLI_PRINT_BUFFER_SIZE-1] = '\0'; + va_end(arglist); + + const char *t = tmp; + while (*t && cliSendCb) { + cliSendCb(cliSendCtx, *t++); + } +} + +#define cliSerialPrint(...) \ + do { cliSerialPrintf(__VA_ARGS__); cliSerialCrlf(); } while(0) + +static void cliSerialPutc(uint8_t c) +{ + if (cliSendCb) cliSendCb(cliSendCtx, c); +} + +static void cliSerialCrlf() +{ + cliSerialPutc('\r'); + cliSerialPutc('\n'); +} + uint8_t cliTracesEnabled = true; char cliLastLine[CLI_COMMAND_MAX_LEN+1]; @@ -73,8 +119,8 @@ struct MemArea void cliPrompt() { - serialPutc('>'); - serialPutc(' '); + cliSerialPutc('>'); + cliSerialPutc(' '); } int toLongLongInt(const char ** argv, int index, long long int * val) @@ -94,7 +140,7 @@ int toLongLongInt(const char ** argv, int index, long long int * val) if (*endptr == '\0') return 1; else { - serialPrint("%s: Invalid argument \"%s\"", argv[0], argv[index]); + cliSerialPrint("%s: Invalid argument \"%s\"", argv[0], argv[index]); return -1; } } @@ -134,12 +180,12 @@ int cliLs(const char ** argv) for (;;) { res = f_readdir(&dir, &fno); /* Read a directory item */ if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ - serialPrint(fno.fname); + cliSerialPrint(fno.fname); } f_closedir(&dir); } else { - serialPrint("%s: Invalid directory \"%s\"", argv[0], argv[1]); + cliSerialPrint("%s: Invalid directory \"%s\"", argv[0], argv[1]); } return 0; } @@ -150,20 +196,20 @@ int cliRead(const char ** argv) uint32_t bytesRead = 0; int bufferSize; if (toInt(argv, 2, &bufferSize) == 0 || bufferSize < 0 ) { - serialPrint("%s: Invalid buffer size \"%s\"", argv[0], argv[2]); + cliSerialPrint("%s: Invalid buffer size \"%s\"", argv[0], argv[2]); return 0; } uint8_t * buffer = (uint8_t*) malloc(bufferSize); if (!buffer) { - serialPrint("Not enough memory"); + cliSerialPrint("Not enough memory"); return 0; } FRESULT result = f_open(&file, argv[1], FA_OPEN_EXISTING | FA_READ); if (result != FR_OK) { free(buffer); - serialPrint("%s: File not found \"%s\"", argv[0], argv[1]); + cliSerialPrint("%s: File not found \"%s\"", argv[0], argv[1]); return 0; } @@ -184,7 +230,7 @@ int cliRead(const char ** argv) uint32_t elapsedTime = (get_tmr10ms() - start) * 10; if (elapsedTime == 0) elapsedTime = 1; uint32_t speed = bytesRead / elapsedTime; - serialPrint("Read %d bytes in %d ms, speed %d kB/s", bytesRead, elapsedTime, speed); + cliSerialPrint("Read %d bytes in %d ms, speed %d kB/s", bytesRead, elapsedTime, speed); free(buffer); return 0; } @@ -195,22 +241,22 @@ int cliReadSD(const char ** argv) int numberOfSectors; int bufferSectors; if (toInt(argv, 1, &startSector) == 0 || startSector < 0 ) { - serialPrint("%s: Invalid start sector \"%s\"", argv[0], argv[1]); + cliSerialPrint("%s: Invalid start sector \"%s\"", argv[0], argv[1]); return 0; } if (toInt(argv, 2, &numberOfSectors) == 0 || numberOfSectors < 0 ) { - serialPrint("%s: Invalid number of sectors \"%s\"", argv[0], argv[2]); + cliSerialPrint("%s: Invalid number of sectors \"%s\"", argv[0], argv[2]); return 0; } if (toInt(argv, 3, &bufferSectors) == 0 || bufferSectors < 0 ) { - serialPrint("%s: Invalid number of buffer sectors \"%s\"", argv[0], argv[3]); + cliSerialPrint("%s: Invalid number of buffer sectors \"%s\"", argv[0], argv[3]); return 0; } uint8_t * buffer = (uint8_t*) malloc(512*bufferSectors); if (!buffer) { - serialPrint("Not enough memory"); + cliSerialPrint("Not enough memory"); return 0; } @@ -220,7 +266,7 @@ int cliReadSD(const char ** argv) while (numberOfSectors > 0) { DRESULT res = __disk_read(0, buffer, startSector, bufferSectors); if (res != RES_OK) { - serialPrint("disk_read error: %d, sector: %d(%d)", res, startSector, numberOfSectors); + cliSerialPrint("disk_read error: %d, sector: %d(%d)", res, startSector, numberOfSectors); } #if 0 for(uint32_t n=0; n= bufferSectors) { numberOfSectors -= bufferSectors; @@ -247,7 +293,7 @@ int cliReadSD(const char ** argv) uint32_t elapsedTime = (get_tmr10ms() - start) * 10; if (elapsedTime == 0) elapsedTime = 1; uint32_t speed = bytesRead / elapsedTime; - serialPrint("Read %d bytes in %d ms, speed %d kB/s", bytesRead, elapsedTime, speed); + cliSerialPrint("Read %d bytes in %d ms, speed %d kB/s", bytesRead, elapsedTime, speed); free(buffer); return 0; } @@ -259,67 +305,67 @@ int cliTestSD(const char ** argv) // get sector count uint32_t sectorCount; if (disk_ioctl(0, GET_SECTOR_COUNT, §orCount) != RES_OK) { - serialPrint("Error: can't read sector count"); + cliSerialPrint("Error: can't read sector count"); return 0; } - serialPrint("SD card has %u sectors", sectorCount); + cliSerialPrint("SD card has %u sectors", sectorCount); // read last 16 sectors one sector at the time - serialPrint("Starting single sector read test, reading 16 sectors one by one"); + cliSerialPrint("Starting single sector read test, reading 16 sectors one by one"); uint8_t * buffer = (uint8_t*) malloc(512); if (!buffer) { - serialPrint("Not enough memory"); + cliSerialPrint("Not enough memory"); return 0; } for (uint32_t s = sectorCount - 16; s &cats = modList.getCategories(); @@ -656,7 +702,7 @@ int cliTestModelsList() for (ModelsCategory::iterator mod_it = (*cat_it)->begin(); mod_it != (*cat_it)->end(); mod_it++) { if (!(*mod_it)->fetchRfData()) { - serialPrint("Error while fetching RF data..."); + cliSerialPrint("Error while fetching RF data..."); return 0; } @@ -666,7 +712,7 @@ int cliTestModelsList() } done: - serialPrint("Done fetching %ix RF data: %lu ms", count, + cliSerialPrint("Done fetching %ix RF data: %lu ms", count, (RTOS_GET_MS() - start)); return 0; @@ -699,7 +745,7 @@ int cliTest(const char ** argv) #endif #endif else { - serialPrint("%s: Invalid argument \"%s\"", argv[0], argv[1]); + cliSerialPrint("%s: Invalid argument \"%s\"", argv[0], argv[1]); } return 0; } @@ -713,18 +759,18 @@ int cliTrace(const char ** argv) cliTracesEnabled = false; } else { - serialPrint("%s: Invalid argument \"%s\"", argv[0], argv[1]); + cliSerialPrint("%s: Invalid argument \"%s\"", argv[0], argv[1]); } return 0; } int cliStackInfo(const char ** argv) { - serialPrint("[MAIN] %d available / %d bytes", stackAvailable()*4, stackSize()*4); - serialPrint("[MENUS] %d available / %d bytes", menusStack.available()*4, menusStack.size()); - serialPrint("[MIXER] %d available / %d bytes", mixerStack.available()*4, mixerStack.size()); - serialPrint("[AUDIO] %d available / %d bytes", audioStack.available()*4, audioStack.size()); - serialPrint("[CLI] %d available / %d bytes", cliStack.available()*4, cliStack.size()); + cliSerialPrint("[MAIN] %d available / %d bytes", stackAvailable()*4, stackSize()*4); + cliSerialPrint("[MENUS] %d available / %d bytes", menusStack.available()*4, menusStack.size()); + cliSerialPrint("[MIXER] %d available / %d bytes", mixerStack.available()*4, mixerStack.size()); + cliSerialPrint("[AUDIO] %d available / %d bytes", audioStack.available()*4, audioStack.size()); + cliSerialPrint("[CLI] %d available / %d bytes", cliStack.available()*4, cliStack.size()); return 0; } @@ -747,31 +793,31 @@ int cliMemoryInfo(const char ** argv) // int keepcost; /* top-most, releasable (via malloc_trim) space */ // }; struct mallinfo info = mallinfo(); - serialPrint("mallinfo:"); - serialPrint("\tarena %d bytes", info.arena); - serialPrint("\tordblks %d bytes", info.ordblks); - serialPrint("\tuordblks %d bytes", info.uordblks); - serialPrint("\tfordblks %d bytes", info.fordblks); - serialPrint("\tkeepcost %d bytes", info.keepcost); + cliSerialPrint("mallinfo:"); + cliSerialPrint("\tarena %d bytes", info.arena); + cliSerialPrint("\tordblks %d bytes", info.ordblks); + cliSerialPrint("\tuordblks %d bytes", info.uordblks); + cliSerialPrint("\tfordblks %d bytes", info.fordblks); + cliSerialPrint("\tkeepcost %d bytes", info.keepcost); - serialPrint("\nHeap:"); - serialPrint("\tstart %p", (unsigned char *)&_end); - serialPrint("\tend %p", (unsigned char *)&_heap_end); - serialPrint("\tcurr %p", heap); - serialPrint("\tused %d bytes", (int)(heap - (unsigned char *)&_end)); - serialPrint("\tfree %d bytes", (int)((unsigned char *)&_heap_end - heap)); + cliSerialPrint("\nHeap:"); + cliSerialPrint("\tstart %p", (unsigned char *)&_end); + cliSerialPrint("\tend %p", (unsigned char *)&_heap_end); + cliSerialPrint("\tcurr %p", heap); + cliSerialPrint("\tused %d bytes", (int)(heap - (unsigned char *)&_end)); + cliSerialPrint("\tfree %d bytes", (int)((unsigned char *)&_heap_end - heap)); #if defined(LUA) - serialPrint("\nLua:"); + cliSerialPrint("\nLua:"); uint32_t s = luaGetMemUsed(lsScripts); - serialPrint("\tScripts %u", s); + cliSerialPrint("\tScripts %u", s); #if defined(COLORLCD) uint32_t w = luaGetMemUsed(lsWidgets); uint32_t e = luaExtraMemoryUsage; - serialPrint("\tWidgets %u", w); - serialPrint("\tExtra %u", e); - serialPrint("------------"); - serialPrint("\tTotal %u", s + w + e); + cliSerialPrint("\tWidgets %u", w); + cliSerialPrint("\tExtra %u", e); + cliSerialPrint("------------"); + cliSerialPrint("\tTotal %u", s + w + e); #endif #endif return 0; @@ -825,7 +871,7 @@ int cliSet(const char **argv) g_rtcTime = gmktime(&t); rtcSetTime(&t); } else { - serialPrint("%s: Invalid arguments \"%s\" \"%s\"", argv[0], argv[1], + cliSerialPrint("%s: Invalid arguments \"%s\" \"%s\"", argv[0], argv[1], argv[2]); return -1; } @@ -836,7 +882,7 @@ int cliSet(const char **argv) if (toInt(argv, 2, &level) > 0) { setVolume(level); } else { - serialPrint("%s: Invalid argument \"%s\" \"%s\"", argv[0], argv[1], + cliSerialPrint("%s: Invalid argument \"%s\" \"%s\"", argv[0], argv[1], argv[2]); return -1; } @@ -845,7 +891,7 @@ int cliSet(const char **argv) else if (!strcmp(argv[1], "rfmod")) { int module = 0; if (toInt(argv, 2, &module) < 0) { - serialPrint("%s: invalid module argument '%s'", argv[0], argv[2]); + cliSerialPrint("%s: invalid module argument '%s'", argv[0], argv[2]); return -1; } if (!strcmp(argv[3], "power")) { @@ -862,34 +908,34 @@ int cliSet(const char **argv) EXTERNAL_MODULE_OFF(); } } else { - serialPrint("%s: invalid power argument '%s'", argv[0], argv[4]); + cliSerialPrint("%s: invalid power argument '%s'", argv[0], argv[4]); return -1; } - serialPrint("%s: rfmod %d power %s", argv[0], module, argv[4]); + cliSerialPrint("%s: rfmod %d power %s", argv[0], module, argv[4]); } #if defined(INTMODULE_BOOTCMD_GPIO) else if (!strcmp(argv[3], "bootpin")) { int level = 0; if (toInt(argv, 4, &level) < 0) { - serialPrint("%s: invalid bootpin argument '%s'", argv[0], argv[4]); + cliSerialPrint("%s: invalid bootpin argument '%s'", argv[0], argv[4]); return -1; } if (module == 0) { if (level) { GPIO_SetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN); - serialPrint("%s: bootpin set", argv[0]); + cliSerialPrint("%s: bootpin set", argv[0]); } else { GPIO_ResetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN); - serialPrint("%s: bootpin reset", argv[0]); + cliSerialPrint("%s: bootpin reset", argv[0]); } } } #endif else { if (strlen(argv[2]) == 0) { - serialPrint("%s: missing rfmod arguments", argv[0]); + cliSerialPrint("%s: missing rfmod arguments", argv[0]); } else { - serialPrint("%s: invalid rfmod argument '%s'", argv[0], argv[3]); + cliSerialPrint("%s: invalid rfmod argument '%s'", argv[0], argv[3]); return -1; } } @@ -897,15 +943,15 @@ int cliSet(const char **argv) else if (!strcmp(argv[1], "pulses")) { int level = 0; if (toInt(argv, 2, &level) < 0) { - serialPrint("%s: invalid level argument '%s'", argv[0], argv[2]); + cliSerialPrint("%s: invalid level argument '%s'", argv[0], argv[2]); return -1; } if (level) { - serialPrint("%s: pulses start", argv[0]); + cliSerialPrint("%s: pulses start", argv[0]); startPulses(); } else { - serialPrint("%s: pulses stop", argv[0]); + cliSerialPrint("%s: pulses stop", argv[0]); stopPulses(); } } @@ -917,7 +963,7 @@ int cliSet(const char **argv) static void spInternalModuleTx(uint8_t* buf, uint32_t len) { while (len > 0) { - IntmoduleSerialDriver.sendByte(*(buf++)); + IntmoduleSerialDriver.sendByte(nullptr, *(buf++)); len--; } } @@ -928,8 +974,6 @@ static const etx_serial_init spIntmoduleSerialInitParams = { .stop_bits = ETX_StopBits_One, .word_length = ETX_WordLength_8, .rx_enable = true, - .rx_dma_buf = nullptr, - .rx_dma_buf_len = 0, .on_receive = intmoduleFifoReceive, .on_error = intmoduleFifoError, }; @@ -953,7 +997,7 @@ int cliSerialPassthrough(const char **argv) // 3rd argument (baudrate is optional) if (!port_type || !port_num) { - serialPrint("%s: missing argument", argv[0]); + cliSerialPrint("%s: missing argument", argv[0]); return -1; } @@ -961,7 +1005,7 @@ int cliSerialPassthrough(const char **argv) int err = toInt(argv, 2, &port_n); if (err == -1) return err; if (err == 0) { - serialPrint("%s: missing port #", argv[0]); + cliSerialPrint("%s: missing port #", argv[0]); return -1; } @@ -973,7 +1017,7 @@ int cliSerialPassthrough(const char **argv) if (!baudrate) { // default to 115200 baudrate = 115200; - serialPrint("%s: USB baudrate is 0, default to 115200", argv[0]); + cliSerialPrint("%s: USB baudrate is 0, default to 115200", argv[0]); } } @@ -982,7 +1026,7 @@ int cliSerialPassthrough(const char **argv) if (port_n >= NUM_MODULES // only internal module supported for now && port_n != INTERNAL_MODULE) { - serialPrint("%s: invalid port # '%s'", port_num); + cliSerialPrint("%s: invalid port # '%s'", port_num); return -1; } @@ -1002,7 +1046,7 @@ int cliSerialPassthrough(const char **argv) etx_serial_init params(spIntmoduleSerialInitParams); params.baudrate = baudrate; - IntmoduleSerialDriver.init(¶ms); + void* uart_ctx = IntmoduleSerialDriver.init(¶ms); // backup and swap CLI input auto backupCB = cliReceiveCallBack; @@ -1023,7 +1067,7 @@ int cliSerialPassthrough(const char **argv) timeout--; } - usbSerialPutc(data); + usbSerialPutc(nullptr, data); } // keep us up & running @@ -1035,7 +1079,7 @@ int cliSerialPassthrough(const char **argv) cliReceiveCallBack = backupCB; // and stop module - IntmoduleSerialDriver.deinit(); + IntmoduleSerialDriver.deinit(uart_ctx); // power off the module and wait for a bit INTERNAL_MODULE_OFF(); @@ -1053,7 +1097,7 @@ int cliSerialPassthrough(const char **argv) xTaskResumeAll(); } else { - serialPrint("%s: invalid port type '%s'", port_type); + cliSerialPrint("%s: invalid port type '%s'", port_type); return -1; } @@ -1069,9 +1113,9 @@ void printInterrupts() memset(&interruptCounters, 0, sizeof(interruptCounters)); interruptCounters.resetTime = get_tmr10ms(); __enable_irq(); - serialPrint("Interrupts count in the last %u ms:", (get_tmr10ms() - ic.resetTime) * 10); + cliSerialPrint("Interrupts count in the last %u ms:", (get_tmr10ms() - ic.resetTime) * 10); for(int n = 0; n < INT_LAST; n++) { - serialPrint("%s: %u", interruptNames[n], ic.cnt[n]); + cliSerialPrint("%s: %u", interruptNames[n], ic.cnt[n]); } } #endif //#if defined(DEBUG_INTERRUPTS) @@ -1080,20 +1124,20 @@ void printInterrupts() void printDebugTime(uint32_t time) { if (time >= 30000) { - serialPrintf("%dms", time/1000); + cliSerialPrintf("%dms", time/1000); } else { - serialPrintf("%d.%03dms", time/1000, time%1000); + cliSerialPrintf("%d.%03dms", time/1000, time%1000); } } void printDebugTimer(const char * name, DebugTimer & timer) { - serialPrintf("%s: ", name); + cliSerialPrintf("%s: ", name); printDebugTime( timer.getMin()); - serialPrintf(" - "); + cliSerialPrintf(" - "); printDebugTime(timer.getMax()); - serialCrlf(); + cliSerialCrlf(); timer.reset(); } void printDebugTimers() @@ -1108,28 +1152,28 @@ void printDebugTimers() void printAudioVars() { for (int n = 0; n < AUDIO_BUFFER_COUNT; n++) { - serialPrint("Audio Buffer %d: size: %u, ", n, + cliSerialPrint("Audio Buffer %d: size: %u, ", n, (uint32_t)audioBuffers[n].size); dump((uint8_t *)audioBuffers[n].data, 32); } - serialPrint("fragments:"); + cliSerialPrint("fragments:"); for (int n = 0; n < AUDIO_QUEUE_LENGTH; n++) { - serialPrint("%d: type %u: id: %u, repeat: %u, ", n, + cliSerialPrint("%d: type %u: id: %u, repeat: %u, ", n, (uint32_t)audioQueue.fragmentsFifo.fragments[n].type, (uint32_t)audioQueue.fragmentsFifo.fragments[n].id, (uint32_t)audioQueue.fragmentsFifo.fragments[n].repeat); if (audioQueue.fragmentsFifo.fragments[n].type == FRAGMENT_FILE) { - serialPrint(" file: %s", audioQueue.fragmentsFifo.fragments[n].file); + cliSerialPrint(" file: %s", audioQueue.fragmentsFifo.fragments[n].file); } } - serialPrint("FragmentFifo: ridx: %d, widx: %d", + cliSerialPrint("FragmentFifo: ridx: %d, widx: %d", audioQueue.fragmentsFifo.ridx, audioQueue.fragmentsFifo.widx); - serialPrint("audioQueue: readIdx: %d, writeIdx: %d, full: %d", + cliSerialPrint("audioQueue: readIdx: %d, writeIdx: %d, full: %d", audioQueue.buffersFifo.readIdx, audioQueue.buffersFifo.writeIdx, audioQueue.buffersFifo.bufferFull); - serialPrint("normalContext: %u", + cliSerialPrint("normalContext: %u", (uint32_t)audioQueue.normalContext.fragment.type); } #endif @@ -1152,13 +1196,13 @@ int cliDisplay(const char ** argv) uint8_t len = STR_VKEYS[0]; strncpy(name, STR_VKEYS+1+len*i, len); name[len] = '\0'; - serialPrint("[%s] = %s", name, keys[i].state() ? "on" : "off"); + cliSerialPrint("[%s] = %s", name, keys[i].state() ? "on" : "off"); } #if defined(ROTARY_ENCODER_NAVIGATION) - serialPrint("[Enc.] = %d", rotencValue / ROTARY_ENCODER_GRANULARITY); + cliSerialPrint("[Enc.] = %d", rotencValue / ROTARY_ENCODER_GRANULARITY); #endif for (int i=TRM_BASE; i<=TRM_LAST; i++) { - serialPrint("[Trim%d] = %s", i-TRM_BASE, keys[i].state() ? "on" : "off"); + cliSerialPrint("[Trim%d] = %s", i-TRM_BASE, keys[i].state() ? "on" : "off"); } for (int i=MIXSRC_FIRST_SWITCH; i<=MIXSRC_LAST_SWITCH; i++) { mixsrc_t sw = i - MIXSRC_FIRST_SWITCH; @@ -1166,34 +1210,34 @@ int cliDisplay(const char ** argv) char swName[LEN_SWITCH_NAME + 1]; strAppend(swName, STR_VSWITCHES+1+sw*STR_VSWITCHES[0], STR_VSWITCHES[0]); static const char * const SWITCH_POSITIONS[] = { "down", "mid", "up" }; - serialPrint("[%s] = %s", swName, SWITCH_POSITIONS[1 + getValue(i) / 1024]); + cliSerialPrint("[%s] = %s", swName, SWITCH_POSITIONS[1 + getValue(i) / 1024]); } } } else if (!strcmp(argv[1], "adc")) { for (int i=0; iCR1); - serialPrint(" CR2 0x%x", tim->CR2); - serialPrint(" DIER 0x%x", tim->DIER); - serialPrint(" SR 0x%x", tim->SR); - serialPrint(" EGR 0x%x", tim->EGR); - serialPrint(" CCMR1 0x%x", tim->CCMR1); - serialPrint(" CCMR2 0x%x", tim->CCMR2); + cliSerialPrint("TIM%d", timerNumber); + cliSerialPrint(" CR1 0x%x", tim->CR1); + cliSerialPrint(" CR2 0x%x", tim->CR2); + cliSerialPrint(" DIER 0x%x", tim->DIER); + cliSerialPrint(" SR 0x%x", tim->SR); + cliSerialPrint(" EGR 0x%x", tim->EGR); + cliSerialPrint(" CCMR1 0x%x", tim->CCMR1); + cliSerialPrint(" CCMR2 0x%x", tim->CCMR2); - serialPrint(" CNT 0x%x", tim->CNT); - serialPrint(" ARR 0x%x", tim->ARR); - serialPrint(" PSC 0x%x", tim->PSC); + cliSerialPrint(" CNT 0x%x", tim->CNT); + cliSerialPrint(" ARR 0x%x", tim->ARR); + cliSerialPrint(" PSC 0x%x", tim->PSC); - serialPrint(" CCER 0x%x", tim->CCER); - serialPrint(" CCR1 0x%x", tim->CCR1); - serialPrint(" CCR2 0x%x", tim->CCR2); - serialPrint(" CCR3 0x%x", tim->CCR3); - serialPrint(" CCR4 0x%x", tim->CCR4); + cliSerialPrint(" CCER 0x%x", tim->CCER); + cliSerialPrint(" CCR1 0x%x", tim->CCR1); + cliSerialPrint(" CCR2 0x%x", tim->CCR2); + cliSerialPrint(" CCR3 0x%x", tim->CCR3); + cliSerialPrint(" CCR4 0x%x", tim->CCR4); } } else if (!strcmp(argv[1], "dma")) { - serialPrint("DMA1_Stream7"); - serialPrint(" CR 0x%x", DMA1_Stream7->CR); + cliSerialPrint("DMA1_Stream7"); + cliSerialPrint(" CR 0x%x", DMA1_Stream7->CR); } #if defined(DEBUG_INTERRUPTS) else if (!strcmp(argv[1], "int")) { @@ -1258,7 +1302,7 @@ int cliDisplay(const char ** argv) else if (!strcmp(argv[1], "dc")) { DiskCacheStats stats = diskCache.getStats(); uint32_t hitRate = diskCache.getHitRate(); - serialPrint("Disk Cache stats: w:%u r: %u, h: %u(%0.1f%%), m: %u", stats.noWrites, (stats.noHits + stats.noMisses), stats.noHits, hitRate*0.1f, stats.noMisses); + cliSerialPrint("Disk Cache stats: w:%u r: %u, h: %u(%0.1f%%), m: %u", stats.noWrites, (stats.noHits + stats.noMisses), stats.noHits, hitRate*0.1f, stats.noMisses); } #endif else if (toLongLongInt(argv, 1, &address) > 0) { @@ -1275,15 +1319,15 @@ int cliDebugVars(const char ** argv) #if defined(PCBHORUS) extern uint32_t ioMutexReq, ioMutexRel; extern uint32_t sdReadRetries; - serialPrint("ioMutexReq=%d", ioMutexReq); - serialPrint("ioMutexRel=%d", ioMutexRel); - serialPrint("sdReadRetries=%d", sdReadRetries); + cliSerialPrint("ioMutexReq=%d", ioMutexReq); + cliSerialPrint("ioMutexRel=%d", ioMutexRel); + cliSerialPrint("sdReadRetries=%d", sdReadRetries); #if defined(ACCESS_DENIED) extern volatile int32_t authenticateFrames; - serialPrint("authenticateFrames=%d", authenticateFrames); + cliSerialPrint("authenticateFrames=%d", authenticateFrames); #endif #elif defined(PCBTARANIS) - serialPrint("telemetryErrors=%d", telemetryErrors); + cliSerialPrint("telemetryErrors=%d", telemetryErrors); #endif return 0; @@ -1311,7 +1355,7 @@ int cliRepeat(const char ** argv) } } else { - serialPrint("%s: Invalid arguments", argv[0]); + cliSerialPrint("%s: Invalid arguments", argv[0]); } return 0; } @@ -1320,13 +1364,13 @@ int cliRepeat(const char ** argv) #if defined(JITTER_MEASURE) int cliShowJitter(const char ** argv) { - serialPrint( "# anaIn rawJ avgJ"); + cliSerialPrint( "# anaIn rawJ avgJ"); for (int i=0; icount; j++) { - serialPrint(" s%d %04X", j, calib->steps[j]); + cliSerialPrint(" s%d %04X", j, calib->steps[j]); } } } @@ -1350,10 +1394,10 @@ int cliGps(const char ** argv) #endif else if (toInt(argv, 1, &baudrate) > 0 && baudrate > 0) { gpsInit(baudrate); - serialPrint("GPS baudrate set to %d", baudrate); + cliSerialPrint("GPS baudrate set to %d", baudrate); } else { - serialPrint("%s: Invalid arguments", argv[0]); + cliSerialPrint("%s: Invalid arguments", argv[0]); } return 0; } @@ -1366,21 +1410,21 @@ int cliBlueTooth(const char ** argv) if (!strncmp(argv[1], "AT", 2) || !strncmp(argv[1], "TTM", 3)) { bluetooth.writeString(argv[1]); char * line = bluetooth.readline(); - serialPrint(" 0) { if (baudrate > 0) { bluetoothInit(baudrate, true); char * line = bluetooth.readline(); - serialPrint("name != nullptr; command++) { if (argv[1][0] == '\0' || !strcmp(command->name, argv[0])) { - serialPrint("%s %s", command->name, command->args); + cliSerialPrint("%s %s", command->name, command->args); if (argv[1][0] != '\0') { return 0; } } } if (argv[1][0] != '\0') { - serialPrint("Invalid command \"%s\"", argv[0]); + cliSerialPrint("Invalid command \"%s\"", argv[0]); } return -1; } @@ -1501,7 +1545,7 @@ int cliExecCommand(const char ** argv) return command->func(argv); } } - serialPrint("Invalid command \"%s\"", argv[0]); + cliSerialPrint("Invalid command \"%s\"", argv[0]); return -1; } @@ -1556,14 +1600,14 @@ void cliTask(void * pdata) switch(c) { case CHAR_NEWPAGE: // clear screen - serialPrint("\033[2J\033[1;1H"); + cliSerialPrint("\033[2J\033[1;1H"); cliPrompt(); break; case CHAR_BACKSPACE: if (pos) { line[--pos] = '\0'; - serialPutc(c); + cliSerialPutc(c); } break; @@ -1573,7 +1617,7 @@ void cliTask(void * pdata) case CHAR_LF: // enter - serialCrlf(); + cliSerialCrlf(); line[pos] = '\0'; if (pos == 0 && cliLastLine[0]) { // execute (repeat) last command @@ -1592,7 +1636,7 @@ void cliTask(void * pdata) default: if (isascii(c) && pos < CLI_COMMAND_MAX_LEN) { line[pos++] = c; - serialPutc(c); + cliSerialPutc(c); } break; } diff --git a/radio/src/cli.h b/radio/src/cli.h index 73f71b1e4..9a8803852 100644 --- a/radio/src/cli.h +++ b/radio/src/cli.h @@ -35,4 +35,7 @@ void cliStart(); // Called from receive ISR (either USB or UART) void cliReceiveData(uint8_t* buf, uint32_t len); +// Set callbacks for sending data back to serial port +void cliSetSendCb(void* ctx, void (*cb)(void*, uint8_t)); + #endif // _CLI_H_ diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index 1d5e00e20..ea18eeee5 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -241,9 +241,6 @@ enum TrainerMode { enum UartModes { UART_MODE_NONE, -#if defined(CLI) || defined(DEBUG) - UART_MODE_DEBUG SKIP = UART_MODE_NONE, -#endif UART_MODE_TELEMETRY_MIRROR, UART_MODE_TELEMETRY, UART_MODE_SBUS_TRAINER, @@ -252,9 +249,7 @@ enum UartModes { UART_MODE_MAX SKIP = UART_MODE_COUNT-1 }; -#if defined(CLI) || defined(DEBUG) -#define UART_MODE_NONE UART_MODE_DEBUG -#endif +#define UART_MODE_DEBUG UART_MODE_NONE #define LEN_SWITCH_NAME 3 #define LEN_ANA_NAME 3 diff --git a/radio/src/debug.h b/radio/src/debug.h index c696e3755..3c6b9b1f2 100644 --- a/radio/src/debug.h +++ b/radio/src/debug.h @@ -33,9 +33,6 @@ extern volatile uint32_t g_tmr10ms; -uint8_t auxSerialTracesEnabled(); -uint8_t aux2SerialTracesEnabled(); - #if defined(SIMU) typedef void (*traceCallbackFunc)(const char * text); extern traceCallbackFunc traceCallback; @@ -45,9 +42,9 @@ uint8_t aux2SerialTracesEnabled(); #define debugPrintf(...) printf(__VA_ARGS__) #elif defined(DEBUG) && defined(CLI) #include "cli_traces.h" - #define debugPrintf(...) do { if (cliTracesEnabled) serialPrintf(__VA_ARGS__); } while(0) + #define debugPrintf(...) do { if (cliTracesEnabled) dbgSerialPrintf(__VA_ARGS__); } while(0) #elif defined(DEBUG) - #define debugPrintf(...) do { serialPrintf(__VA_ARGS__); } while(0) + #define debugPrintf(...) do { dbgSerialPrintf(__VA_ARGS__); } while(0) #else #define debugPrintf(...) #endif diff --git a/radio/src/dump.cpp b/radio/src/dump.cpp index 25ef48901..ecb439524 100644 --- a/radio/src/dump.cpp +++ b/radio/src/dump.cpp @@ -24,7 +24,7 @@ #if defined(SIMU) #define dumpPrintf(...) debugPrintf(__VA_ARGS__) #else -#define dumpPrintf(...) serialPrintf(__VA_ARGS__) +#define dumpPrintf(...) dbgSerialPrintf(__VA_ARGS__) #endif #if defined(DEBUG) || defined(CLI) diff --git a/radio/src/gui/212x64/view_statistics.cpp b/radio/src/gui/212x64/view_statistics.cpp index fc1cb4cbc..270c80807 100644 --- a/radio/src/gui/212x64/view_statistics.cpp +++ b/radio/src/gui/212x64/view_statistics.cpp @@ -163,18 +163,6 @@ void menuStatisticsDebug(event_t event) uint8_t y = FH + 1; -#if defined(STM32) && !defined(SIMU) && defined(DEBUG) - lcdDrawTextAlignedLeft(y, "Usb"); - lcdDrawNumber(MENU_DEBUG_COL1_OFS, y, charsWritten, LEFT); - lcdDrawText(lcdLastRightPos, y, " "); - lcdDrawNumber(lcdLastRightPos, y, APP_Rx_ptr_in, LEFT); - lcdDrawText(lcdLastRightPos, y, " "); - lcdDrawNumber(lcdLastRightPos, y, APP_Rx_ptr_out, LEFT); - lcdDrawText(lcdLastRightPos, y, " "); - lcdDrawNumber(lcdLastRightPos, y, usbWraps, LEFT); - y += FH; -#endif - #if defined(STM32) lcdDrawTextAlignedLeft(y, "Free Mem"); lcdDrawNumber(MENU_DEBUG_COL1_OFS, y, availableMemory(), LEFT); diff --git a/radio/src/gui/colorlcd/radio_hardware.cpp b/radio/src/gui/colorlcd/radio_hardware.cpp index d91fa2627..abed9ea46 100644 --- a/radio/src/gui/colorlcd/radio_hardware.cpp +++ b/radio/src/gui/colorlcd/radio_hardware.cpp @@ -380,7 +380,7 @@ void RadioHardwarePage::build(FormWindow * window) UART_MODE_MAX, GET_DEFAULT(g_eeGeneral.auxSerialMode), [](int value) { g_eeGeneral.auxSerialMode = value; - auxSerialInit(g_eeGeneral.auxSerialMode, modelTelemetryProtocol()); + serialInit(0, value); SET_DIRTY(); }); aux->setAvailableHandler(isAuxModeAvailable); @@ -394,7 +394,7 @@ void RadioHardwarePage::build(FormWindow * window) UART_MODE_MAX, GET_DEFAULT(g_eeGeneral.aux2SerialMode), [](int value) { g_eeGeneral.aux2SerialMode = value; - aux2SerialInit(g_eeGeneral.aux2SerialMode, modelTelemetryProtocol()); + serialInit(1, value); SET_DIRTY(); }); aux2->setAvailableHandler(isAux2ModeAvailable); diff --git a/radio/src/gui/common/stdlcd/radio_hardware.cpp b/radio/src/gui/common/stdlcd/radio_hardware.cpp index 6aa47af37..ffa2dadd5 100644 --- a/radio/src/gui/common/stdlcd/radio_hardware.cpp +++ b/radio/src/gui/common/stdlcd/radio_hardware.cpp @@ -600,7 +600,7 @@ void menuRadioHardware(event_t event) case ITEM_RADIO_HARDWARE_AUX_SERIAL_MODE: g_eeGeneral.auxSerialMode = editChoice(HW_SETTINGS_COLUMN2, y, STR_AUX_SERIAL_MODE, STR_AUX_SERIAL_MODES, g_eeGeneral.auxSerialMode, 0, UART_MODE_MAX, attr, event); if (attr && checkIncDec_Ret) { - auxSerialInit(g_eeGeneral.auxSerialMode, modelTelemetryProtocol()); + serialInit(0, g_eeGeneral.auxSerialMode); } break; #endif diff --git a/radio/src/hal/serial_driver.h b/radio/src/hal/serial_driver.h index a1aad2263..947225ba5 100644 --- a/radio/src/hal/serial_driver.h +++ b/radio/src/hal/serial_driver.h @@ -40,44 +40,45 @@ enum SerialWordLength { ETX_WordLength_9, }; -struct etx_serial_init { +typedef struct { uint32_t baudrate; // = 0; uint8_t parity; // = ETX_Parity_None; uint8_t stop_bits; // = ETX_StopBits_One; uint8_t word_length; // = ETX_WordLength_8; bool rx_enable; // = false; - void* rx_dma_buf; - uint32_t rx_dma_buf_len; - void (*on_receive)(uint8_t data); // = nullptr; void (*on_error)(); // = nullptr; -}; +} etx_serial_init; struct etx_serial_callbacks_t { - bool (*on_send)(uint8_t& data); + bool (*on_send)(uint8_t* data); void (*on_receive)(uint8_t data); void (*on_error)(); }; -struct etx_serial_driver_t { +typedef struct { - // Init module communication - void (*init)(const etx_serial_init* params); + // Init serial communication + void* (*init)(const etx_serial_init* params); - // De-Init module communication - void (*deinit)(); + // De-Init serial communication + void (*deinit)(void* ctx); // Send a single byte - void (*sendByte)(uint8_t byte); + void (*sendByte)(void* ctx, uint8_t byte); // Send a buffer - void (*sendBuffer)(const uint8_t* data, uint8_t size); + void (*sendBuffer)(void* ctx, const uint8_t* data, uint8_t size); // Wait for last send operation to complete - void (*waitForTxCompleted)(); + void (*waitForTxCompleted)(void* ctx); + // Fetch byte from internal buffer + int (*getByte)(void* ctx, uint8_t* data); + // Callbacks - void (*setReceiveCb)(void (*on_receive)(uint8_t data)); - void (*setOnErrorCb)(void (*on_error)()); -}; + void (*setReceiveCb)(void* ctx, void (*on_receive)(uint8_t data)); + void (*setOnErrorCb)(void* ctx, void (*on_error)()); + +} etx_serial_driver_t; diff --git a/radio/src/hal/serial_port.h b/radio/src/hal/serial_port.h new file mode 100644 index 000000000..25bea20a5 --- /dev/null +++ b/radio/src/hal/serial_port.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) EdgeTx + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * 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. + */ + +#pragma once + +#include "serial_driver.h" + +typedef void etx_pwr_driver; + +typedef struct { + const etx_serial_driver_t* uart; + void (*set_pwr)(uint8_t on); +} etx_serial_port_t; diff --git a/radio/src/io/frsky_firmware_update.cpp b/radio/src/io/frsky_firmware_update.cpp index 5a94ec8ff..1ad1e9cd2 100644 --- a/radio/src/io/frsky_firmware_update.cpp +++ b/radio/src/io/frsky_firmware_update.cpp @@ -175,7 +175,7 @@ const uint8_t * FrskyDeviceFirmwareUpdate::readHalfDuplexFrame(uint32_t timeout) { for (int i = timeout; i >= 0; i--) { uint8_t byte ; - while (telemetryGetByte(&byte)) { + while (sportGetByte(&byte)) { if (pushFrskyTelemetryData(byte)) { return telemetryRxBuffer; } @@ -251,7 +251,7 @@ void FrskyDeviceFirmwareUpdate::sendFrame() switch (module) { #if defined(INTERNAL_MODULE_PXX2) case INTERNAL_MODULE: - IntmoduleSerialDriver.sendBuffer(outputTelemetryBuffer.data, + IntmoduleSerialDriver.sendBuffer(uart_ctx, outputTelemetryBuffer.data, ptr - outputTelemetryBuffer.data); return; #endif @@ -316,8 +316,6 @@ static const etx_serial_init serialInitParams = { .stop_bits = ETX_StopBits_One, .word_length = ETX_WordLength_8, .rx_enable = true, - .rx_dma_buf = nullptr, - .rx_dma_buf_len = 0, .on_receive = intmoduleFifoReceive, .on_error = intmoduleFifoError, }; @@ -354,7 +352,7 @@ const char * FrskyDeviceFirmwareUpdate::doFlashFirmware(const char * filename, P etx_serial_init params(serialInitParams); params.baudrate = 38400; - IntmoduleSerialDriver.init(¶ms); + uart_ctx = IntmoduleSerialDriver.init(¶ms); GPIO_SetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN); result = uploadFileToHorusXJT(filename, &file, progressHandler); @@ -370,7 +368,7 @@ const char * FrskyDeviceFirmwareUpdate::doFlashFirmware(const char * filename, P case INTERNAL_MODULE: { etx_serial_init params(serialInitParams); params.baudrate = 57600; - IntmoduleSerialDriver.init(¶ms); + uart_ctx = IntmoduleSerialDriver.init(¶ms); } break; #endif @@ -402,14 +400,14 @@ const char * FrskyDeviceFirmwareUpdate::uploadFileToHorusXJT(const char * filena return STR_DEVICE_NO_RESPONSE; } - IntmoduleSerialDriver.sendByte(0x81); + IntmoduleSerialDriver.sendByte(uart_ctx, 0x81); readBuffer(frame, 1, 100); if (!readBuffer(frame, 8, 100) || frame[0] != 0x02) { return STR_DEVICE_NO_RESPONSE; } - IntmoduleSerialDriver.sendByte(0x82); + IntmoduleSerialDriver.sendByte(uart_ctx, 0x82); readBuffer(frame, 1, 100); uint8_t index = 0; @@ -427,7 +425,7 @@ const char * FrskyDeviceFirmwareUpdate::uploadFileToHorusXJT(const char * filena return STR_DEVICE_WRONG_REQUEST; if (count == 0) { - IntmoduleSerialDriver.sendByte(0xA1); + IntmoduleSerialDriver.sendByte(uart_ctx, 0xA1); RTOS_WAIT_MS(50); return nullptr; } @@ -435,15 +433,15 @@ const char * FrskyDeviceFirmwareUpdate::uploadFileToHorusXJT(const char * filena if (count < 1024) memset(((uint8_t *)buffer) + count, 0, 1024 - count); - IntmoduleSerialDriver.sendByte(frame[0] + 0x80); - IntmoduleSerialDriver.sendByte(frame[1]); + IntmoduleSerialDriver.sendByte(uart_ctx, frame[0] + 0x80); + IntmoduleSerialDriver.sendByte(uart_ctx, frame[1]); uint16_t crc_16 = crc16(CRC_1189, (uint8_t *)buffer, 1024, crc16(CRC_1189, &frame[1], 1)); for (size_t i = 0; i < sizeof(buffer); i++) { - IntmoduleSerialDriver.sendByte(((uint8_t *)buffer)[i]); + IntmoduleSerialDriver.sendByte(uart_ctx, ((uint8_t *)buffer)[i]); } - IntmoduleSerialDriver.sendByte(crc_16 >> 8); - IntmoduleSerialDriver.sendByte(crc_16); + IntmoduleSerialDriver.sendByte(uart_ctx, crc_16 >> 8); + IntmoduleSerialDriver.sendByte(uart_ctx, crc_16); index++; } @@ -597,7 +595,7 @@ const char * FrskyChipFirmwareUpdate::waitAnswer(uint8_t & status) for (uint8_t i = 0; i < sizeof(buffer); i++) { uint32_t retry = 0; while (true) { - if (telemetryGetByte(&buffer[i])) { + if (sportGetByte(&buffer[i])) { if ((i == 0 && buffer[0] != 0x7F) || (i == 1 && buffer[1] != 0xFE) || (i == 10 && buffer[10] != 0x0D) || diff --git a/radio/src/io/frsky_firmware_update.h b/radio/src/io/frsky_firmware_update.h index 3763a6a54..5fa129c29 100644 --- a/radio/src/io/frsky_firmware_update.h +++ b/radio/src/io/frsky_firmware_update.h @@ -137,6 +137,7 @@ class FrskyDeviceFirmwareUpdate { uint32_t address = 0; ModuleIndex module; uint8_t frame[12]; + void* uart_ctx = nullptr; void startFrame(uint8_t command); void sendFrame(); diff --git a/radio/src/io/multi_firmware_update.cpp b/radio/src/io/multi_firmware_update.cpp index 90d8dd9c2..5cff0fdd2 100644 --- a/radio/src/io/multi_firmware_update.cpp +++ b/radio/src/io/multi_firmware_update.cpp @@ -28,6 +28,8 @@ #include "debug.h" #include "timers_driver.h" +#include + #if defined(LIBOPENUI) #include "libopenui.h" #else @@ -50,24 +52,26 @@ class MultiFirmwareUpdateDriver { public: MultiFirmwareUpdateDriver() {} - const char * flashFirmware(FIL * file, const char * label, ProgressHandler progressHandler) const; + virtual ~MultiFirmwareUpdateDriver() {} + const char* flashFirmware(FIL* file, const char* label, + ProgressHandler progressHandler); protected: virtual void moduleOn() const = 0; - virtual void init(bool inverted) const = 0; + virtual void init(bool inverted) = 0; virtual bool getByte(uint8_t & byte) const = 0; virtual void sendByte(uint8_t byte) const = 0; virtual void clear() const = 0; - virtual void deinit(bool inverted) const {} + virtual void deinit(bool inverted) {} private: bool getRxByte(uint8_t & byte) const; bool checkRxByte(uint8_t byte) const; - const char * waitForInitialSync(bool& inverted) const; + const char * waitForInitialSync(bool& inverted); const char * getDeviceSignature(uint8_t * signature) const; const char * loadAddress(uint32_t offset) const; const char * progPage(uint8_t * buffer, uint16_t size) const; - void leaveProgMode(bool inverted) const; + void leaveProgMode(bool inverted); }; #if defined(INTERNAL_MODULE_MULTI) @@ -78,8 +82,6 @@ static const etx_serial_init serialInitParams = { .stop_bits = ETX_StopBits_One, .word_length = ETX_WordLength_8, .rx_enable = true, - .rx_dma_buf = nullptr, - .rx_dma_buf_len = 0, .on_receive = intmoduleFifoReceive, .on_error = intmoduleFifoError, }; @@ -90,16 +92,18 @@ class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver MultiInternalUpdateDriver() {} protected: + void* uart_ctx = nullptr; + void moduleOn() const override { INTERNAL_MODULE_ON(); } - void init(bool inverted) const override + void init(bool inverted) override { etx_serial_init params(serialInitParams); params.baudrate = 57600; - IntmoduleSerialDriver.init(¶ms); + uart_ctx = IntmoduleSerialDriver.init(¶ms); } bool getByte(uint8_t & byte) const override @@ -109,7 +113,7 @@ class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver void sendByte(uint8_t byte) const override { - IntmoduleSerialDriver.sendByte(byte); + IntmoduleSerialDriver.sendByte(uart_ctx, byte); } void clear() const override @@ -117,13 +121,13 @@ class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver intmoduleFifo.clear(); } - void deinit(bool inverted) const override + void deinit(bool inverted) override { + IntmoduleSerialDriver.deinit(uart_ctx); + uart_ctx = nullptr; clear(); } }; - -static const MultiInternalUpdateDriver multiInternalUpdateDriver; #endif class MultiExternalUpdateDriver: public MultiFirmwareUpdateDriver @@ -137,7 +141,7 @@ class MultiExternalUpdateDriver: public MultiFirmwareUpdateDriver EXTERNAL_MODULE_ON(); } - void init(bool inverted) const override + void init(bool inverted) override { #if !defined(EXTMODULE_USART) GPIO_InitTypeDef GPIO_InitStructure; @@ -157,7 +161,7 @@ class MultiExternalUpdateDriver: public MultiFirmwareUpdateDriver bool getByte(uint8_t & byte) const override { - return telemetryGetByte(&byte); + return sportGetByte(&byte); } void sendByte(uint8_t byte) const override @@ -172,7 +176,7 @@ class MultiExternalUpdateDriver: public MultiFirmwareUpdateDriver telemetryClearFifo(); } - void deinit(bool inverted) const override + void deinit(bool inverted) override { if (inverted) telemetryPortInvertedInit(0); @@ -183,8 +187,6 @@ class MultiExternalUpdateDriver: public MultiFirmwareUpdateDriver } }; -static const MultiExternalUpdateDriver multiExternalUpdateDriver; - class MultiExtSportUpdateDriver: public MultiFirmwareUpdateDriver { public: @@ -196,14 +198,14 @@ class MultiExtSportUpdateDriver: public MultiFirmwareUpdateDriver EXTERNAL_MODULE_ON(); } - void init(bool inverted) const override + void init(bool inverted) override { telemetryPortInit(57600, TELEMETRY_SERIAL_WITHOUT_DMA); } bool getByte(uint8_t & byte) const override { - return telemetryGetByte(&byte); + return sportGetByte(&byte); } void sendByte(uint8_t byte) const override @@ -217,15 +219,13 @@ class MultiExtSportUpdateDriver: public MultiFirmwareUpdateDriver telemetryClearFifo(); } - void deinit(bool inverted) const override + void deinit(bool inverted) override { telemetryPortInit(0, 0); clear(); } }; -static const MultiExtSportUpdateDriver multiExtSportUpdateDriver; - bool MultiFirmwareUpdateDriver::getRxByte(uint8_t & byte) const { uint16_t time; @@ -251,7 +251,7 @@ bool MultiFirmwareUpdateDriver::checkRxByte(uint8_t byte) const return getRxByte(rxchar) ? rxchar == byte : false; } -const char * MultiFirmwareUpdateDriver::waitForInitialSync(bool & inverted) const +const char * MultiFirmwareUpdateDriver::waitForInitialSync(bool & inverted) { uint8_t byte; int retries = 200; @@ -375,7 +375,7 @@ const char * MultiFirmwareUpdateDriver::progPage(uint8_t * buffer, uint16_t size return nullptr; } -void MultiFirmwareUpdateDriver::leaveProgMode(bool inverted) const +void MultiFirmwareUpdateDriver::leaveProgMode(bool inverted) { sendByte(STK_LEAVE_PROGMODE); sendByte(CRC_EOP); @@ -385,7 +385,8 @@ void MultiFirmwareUpdateDriver::leaveProgMode(bool inverted) const deinit(inverted); } -const char * MultiFirmwareUpdateDriver::flashFirmware(FIL * file, const char * label, ProgressHandler progressHandler) const +const char* MultiFirmwareUpdateDriver::flashFirmware( + FIL* file, const char* label, ProgressHandler progressHandler) { #if defined(SIMU) for (uint16_t i = 0; i < 100; i++) { @@ -616,13 +617,15 @@ bool MultiDeviceFirmwareUpdate::flashFirmware(const char * filename, ProgressHan } } - const MultiFirmwareUpdateDriver * driver = &multiExternalUpdateDriver; + std::unique_ptr driver; + if (module == EXTERNAL_MODULE) + driver.reset(new MultiExternalUpdateDriver()); #if defined(INTERNAL_MODULE_MULTI) - if (module == INTERNAL_MODULE) - driver = &multiInternalUpdateDriver; + else if (module == INTERNAL_MODULE) + driver.reset(new MultiInternalUpdateDriver()); #endif - if (type == MULTI_TYPE_ELRS) - driver = &multiExtSportUpdateDriver; + else if (type == MULTI_TYPE_ELRS) + driver.reset(new MultiExtSportUpdateDriver()); pausePulses(); diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index e25ceee99..5d92ed46e 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -91,9 +91,49 @@ { "EVT_"#xxx"_LONG", EVT_KEY_LONG(yyy) }, \ { "EVT_"#xxx"_REPT", EVT_KEY_REPT(yyy) } -#if defined(LUA) && !defined(CLI) -Fifo * luaRxFifo = nullptr; -#endif +// Note: +// - luaRxFifo & luaReceiveData are used only for USB serial +// - otherwise, the AUX serial buffer is used directly +// +static Fifo* luaRxFifo = nullptr; + +static int luaRxFifoGetByte(void*, uint8_t* data) +{ + if (!luaRxFifo) return -1; + return luaRxFifo->pop(*data); +} + +void luaReceiveData(uint8_t* buf, uint32_t len) +{ + if (!luaRxFifo) { + luaRxFifo = new Fifo(); + luaSetGetSerialByte(nullptr, luaRxFifoGetByte); + } + + if (luaRxFifo) { + while(len--) luaRxFifo->push(*buf++); + } +} + +static void (*luaSendDataCb)(void*, uint8_t) = nullptr; +static void* luaSendDataCtx = nullptr; + +void luaSetSendCb(void* ctx, void (*cb)(void*, uint8_t)) +{ + luaSendDataCb = nullptr; + luaSendDataCtx = ctx; + luaSendDataCb = cb; +} + +static int (*luaGetSerialByte)(void*, uint8_t*) = nullptr; +static void* luaGetSerialByteCtx = nullptr; + +void luaSetGetSerialByte(void* ctx, int (*fct)(void*, uint8_t*)) +{ + luaGetSerialByte = nullptr; + luaGetSerialByteCtx = ctx; + luaGetSerialByte = fct; +} /*luadoc @function getVersion() @@ -1882,22 +1922,23 @@ Set baudrate for serial port(s) affected to LUA */ static int luaSetSerialBaudrate(lua_State * L) { -#if defined(AUX_SERIAL) || defined(AUX2_SERIAL) - unsigned int baudrate = luaL_checkunsigned(L, 1); -#endif +// #if defined(AUX_SERIAL) || defined(AUX2_SERIAL) +// unsigned int baudrate = luaL_checkunsigned(L, 1); +// #endif -#if defined(AUX_SERIAL) - if (auxSerialMode == UART_MODE_LUA) { - auxSerialStop(); - auxSerialSetup(baudrate, false); - } -#endif -#if defined(AUX2_SERIAL) - if (aux2SerialMode == UART_MODE_LUA) { - aux2SerialStop(); - aux2SerialSetup(baudrate, false); - } -#endif +// TODO: add some callbacks for serial settings +// #if defined(AUX_SERIAL) +// if (auxSerialMode == UART_MODE_LUA) { +// auxSerialStop(); +// auxSerialSetup(baudrate, false); +// } +// #endif +// #if defined(AUX2_SERIAL) +// if (aux2SerialMode == UART_MODE_LUA) { +// aux2SerialStop(); +// aux2SerialSetup(baudrate, false); +// } +// #endif return 1; } @@ -1917,30 +1958,15 @@ static int luaSerialWrite(lua_State * L) if (!str || len < 1) return 0; -#if defined(USB_SERIAL) - if (getSelectedUsbMode() == USB_SERIAL_MODE) { + auto _sendCb = luaSendDataCb; + auto _ctx = luaSendDataCtx; + + if (_sendCb) { size_t wr_len = len; const char* p = str; - while(wr_len--) usbSerialPutc(*p++); + while(wr_len--) _sendCb(_ctx, *p++); } -#endif - -#if defined(AUX_SERIAL) - if (auxSerialMode == UART_MODE_LUA) { - size_t wr_len = len; - const char* p = str; - while(wr_len--) auxSerialPutc(*p++); - } -#endif - -#if defined(AUX2_SERIAL) - if (aux2SerialMode == UART_MODE_LUA) { - size_t wr_len = len; - const char* p = str; - while(wr_len--) aux2SerialPutc(*p++); - } -#endif - + return 0; } @@ -1962,34 +1988,29 @@ static int luaSerialRead(lua_State * L) #if defined(LUA) && !defined(CLI) int num = luaL_optunsigned(L, 1, 0); - if (!luaRxFifo) { - // TODO: - // - check which serial port has been assigned this function - // - set the receive callback on that serial port - // - luaRxFifo = new Fifo(); - if (!luaRxFifo) { - lua_pushlstring(L, "", 0); - return 1; - } - } uint8_t str[LUA_FIFO_SIZE]; uint8_t *p = str; - while (luaRxFifo->pop(*p)) { - p++; // increment only when pop was successful - if (p - str >= LUA_FIFO_SIZE) { - // buffer full - break; - } - if (num == 0) { - if (*(p - 1) == '\n' || *(p - 1) == '\r') { - // found newline + + auto _getByte = luaGetSerialByte; + auto _ctx = luaGetSerialByteCtx; + + if (_getByte) { + while (_getByte(_ctx, p) > 0) { + p++; // increment only when pop was successful + if (p - str >= LUA_FIFO_SIZE) { + // buffer full + break; + } + if (num == 0) { + if (*(p - 1) == '\n' || *(p - 1) == '\r') { + // found newline + break; + } + } + else if (p - str >= num) { + // requested number of characters reached break; } - } - else if (p - str >= num) { - // requested number of characters reached - break; } } lua_pushlstring(L, (const char*)str, p - str); diff --git a/radio/src/lua/lua_api.h b/radio/src/lua/lua_api.h index 28a88aa7a..4506c4b2f 100644 --- a/radio/src/lua/lua_api.h +++ b/radio/src/lua/lua_api.h @@ -48,10 +48,11 @@ extern "C" { #endif #endif -#if !defined(CLI) || defined(AUX2_SERIAL) +// LUA serial connection #define LUA_FIFO_SIZE 256 -extern Fifo * luaRxFifo; -#endif +void luaReceiveData(uint8_t* buf, uint32_t len); +void luaSetSendCb(void* ctx, void (*cb)(void*, uint8_t)); +void luaSetGetSerialByte(void* ctx, int (*fct)(void*, uint8_t*)); extern lua_State * lsScripts; diff --git a/radio/src/main.cpp b/radio/src/main.cpp index fda115218..b562d58c7 100644 --- a/radio/src/main.cpp +++ b/radio/src/main.cpp @@ -26,6 +26,10 @@ #include "libopenui.h" #endif +#if defined(CLI) + #include "cli.h" +#endif + uint8_t currentSpeakerVolume = 255; uint8_t requiredSpeakerVolume = 255; uint8_t currentBacklightBright = 0; @@ -153,6 +157,22 @@ void handleUsbConnection() opentxClose(false); usbPluggedIn(); } +#if defined(USB_SERIAL) + else if (getSelectedUsbMode() == USB_SERIAL_MODE) { + // TODO: query USB serial mode + // -> for now, only CLI / DEBUG / LUA +#if defined(CLI) + cliSetSendCb(nullptr, usbSerialPutc); + usbSerialSetReceiveDataCb(cliReceiveData); +#elif defined(DEBUG) + dbgSerialSetSendCb(nullptr, usbSerialPutc); + usbSerialSetReceiveDataCb(nullptr); +#elif defined(LUA) + luaSetSendCb(nullptr, usbSerialPutc); + usbSerialSetReceiveDataCb(luaReceiveData); +#endif + } +#endif usbStart(); TRACE("USB started"); diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index fdf5d543b..987dad94c 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -1869,14 +1869,8 @@ void opentxInit() #endif #endif // #if !defined(EEPROM) -#if defined(AUX_SERIAL) - auxSerialInit(g_eeGeneral.auxSerialMode, modelTelemetryProtocol()); -#endif - -#if defined(AUX2_SERIAL) - aux2SerialInit(g_eeGeneral.aux2SerialMode, modelTelemetryProtocol()); -#endif - + initSerialPorts(); + currentSpeakerVolume = requiredSpeakerVolume = g_eeGeneral.speakerVolume + VOLUME_LEVEL_DEF; currentBacklightBright = requiredBacklightBright = g_eeGeneral.backlightBright; #if !defined(SOFTWARE_VOLUME) diff --git a/radio/src/pulses/afhds2.cpp b/radio/src/pulses/afhds2.cpp index 93b1bebdf..b8be70990 100644 --- a/radio/src/pulses/afhds2.cpp +++ b/radio/src/pulses/afhds2.cpp @@ -45,8 +45,6 @@ const etx_serial_init afhds2SerialInitParams = { .stop_bits = ETX_StopBits_One, .word_length = ETX_WordLength_8, .rx_enable = true, - .rx_dma_buf = nullptr, - .rx_dma_buf_len = 0, .on_receive = intmoduleFifoReceive, .on_error = intmoduleFifoError, }; @@ -69,11 +67,9 @@ static void* afhds2Init(uint8_t module) static void afhds2DeInit(void* context) { - (void)context; - INTERNAL_MODULE_OFF(); intmoduleFifo.clear(); - IntmoduleSerialDriver.deinit(); + IntmoduleSerialDriver.deinit(context); // mixer setup mixerSchedulerSetPeriod(INTERNAL_MODULE, 0); @@ -97,11 +93,9 @@ static void afhds2SetupPulses(void* context, int16_t* channels, uint8_t nChannel static void afhds2SendPulses(void* context) { - (void)context; - uint8_t* data = (uint8_t*)intmodulePulsesData.flysky.pulses; uint16_t size = intmodulePulsesData.flysky.ptr - data; - IntmoduleSerialDriver.sendBuffer(data, size); + IntmoduleSerialDriver.sendBuffer(context, data, size); } const etx_module_driver_t Afhds2InternalDriver = { diff --git a/radio/src/pulses/crossfire.cpp b/radio/src/pulses/crossfire.cpp index a176e8ccd..5d1e9df4d 100644 --- a/radio/src/pulses/crossfire.cpp +++ b/radio/src/pulses/crossfire.cpp @@ -134,8 +134,6 @@ static const etx_serial_init intmoduleCrossfireInitParams = { .stop_bits = ETX_StopBits_One, .word_length = ETX_WordLength_8, .rx_enable = true, - .rx_dma_buf = nullptr, - .rx_dma_buf_len = 0, .on_receive = intmoduleCRSF_rx, .on_error = nullptr, }; @@ -177,9 +175,7 @@ static void crossfireSetupPulsesInternal(void* context, int16_t* channels, uint8 static void crossfireSendPulsesInternal(void* context) { - (void)context; - - IntmoduleSerialDriver.sendBuffer(intmodulePulsesData.crossfire.pulses, + IntmoduleSerialDriver.sendBuffer(context, intmodulePulsesData.crossfire.pulses, intmodulePulsesData.crossfire.length); } diff --git a/radio/src/pulses/multi.cpp b/radio/src/pulses/multi.cpp index d1190be5a..ff75960d4 100644 --- a/radio/src/pulses/multi.cpp +++ b/radio/src/pulses/multi.cpp @@ -60,8 +60,6 @@ etx_serial_init multiSerialInitParams = { .stop_bits = ETX_StopBits_Two, .word_length = ETX_WordLength_9, .rx_enable = true, - .rx_dma_buf = nullptr, - .rx_dma_buf_len = 0, .on_receive = intmoduleFifoReceive, .on_error = intmoduleFifoError, }; @@ -260,7 +258,7 @@ static void* multiInit(uint8_t module) // serial port setup intmodulePulsesData.multi.initFrame(); intmoduleFifo.clear(); - IntmoduleSerialDriver.init(&multiSerialInitParams); + void* uart_ctx = IntmoduleSerialDriver.init(&multiSerialInitParams); // mixer setup mixerSchedulerSetPeriod(INTERNAL_MODULE, MULTIMODULE_PERIOD); @@ -276,16 +274,14 @@ static void* multiInit(uint8_t module) TRACE("counter = %d", moduleState[INTERNAL_MODULE].counter); #endif - return nullptr; + return uart_ctx; } static void multiDeInit(void* context) { - (void)context; - INTERNAL_MODULE_OFF(); mixerSchedulerSetPeriod(INTERNAL_MODULE, 0); - IntmoduleSerialDriver.deinit(); + IntmoduleSerialDriver.deinit(context); } static void multiSetupPulses(void* context, int16_t* channels, uint8_t nChannels) @@ -301,8 +297,7 @@ static void multiSetupPulses(void* context, int16_t* channels, uint8_t nChannels static void multiSendPulses(void* context) { - (void)context; - IntmoduleSerialDriver.sendBuffer(intmodulePulsesData.multi.getData(), + IntmoduleSerialDriver.sendBuffer(context, intmodulePulsesData.multi.getData(), intmodulePulsesData.multi.getSize()); } diff --git a/radio/src/pulses/pulses.cpp b/radio/src/pulses/pulses.cpp index c1732939a..4cd50f240 100755 --- a/radio/src/pulses/pulses.cpp +++ b/radio/src/pulses/pulses.cpp @@ -476,8 +476,8 @@ void enablePulsesExternalModule(uint8_t protocol) #if defined(PXX1) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML) case PROTOCOL_CHANNELS_PXX1_SERIAL: - extmodulePxx1SerialStart(); - mixerSchedulerSetPeriod(EXTERNAL_MODULE, EXTMODULE_PXX1_SERIAL_PERIOD); + externalModuleContext = Pxx1ExternalSerialDriver.init(EXTERNAL_MODULE); + externalModuleDriver = &Pxx1ExternalSerialDriver; break; #endif @@ -522,12 +522,8 @@ void enablePulsesExternalModule(uint8_t protocol) #if defined(MULTIMODULE) case PROTOCOL_CHANNELS_MULTIMODULE: -#if defined(PCBSKY9X) - extmoduleSerialStart(MULTIMODULE_BAUDRATE, MULTIMODULE_PERIOD * 2000, true); -#else extmoduleSerialStart(); mixerSchedulerSetPeriod(EXTERNAL_MODULE, MULTIMODULE_PERIOD); -#endif getMultiModuleStatus(EXTERNAL_MODULE).failsafeChecked = false; getMultiModuleStatus(EXTERNAL_MODULE).flags = 0; #if defined(MULTI_PROTOLIST) @@ -558,6 +554,7 @@ void enablePulsesExternalModule(uint8_t protocol) #if defined(AFHDS3) case PROTOCOL_CHANNELS_AFHDS3: + // convert to serial module interface extmodulePulsesData.afhds3.init(EXTERNAL_MODULE); extmoduleSerialStart(); mixerSchedulerSetPeriod(EXTERNAL_MODULE, AFHDS3_COMMAND_TIMEOUT * 1000 /* us */); @@ -591,12 +588,6 @@ bool setupPulsesExternalModule(uint8_t protocol) return true; #endif -#if defined(PXX1) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML) - case PROTOCOL_CHANNELS_PXX1_SERIAL: - extmodulePulsesData.pxx_uart.setupFrame(EXTERNAL_MODULE); - return true; -#endif - #if defined(SBUS) case PROTOCOL_CHANNELS_SBUS: setupPulsesSbus(); @@ -681,13 +672,6 @@ void extmoduleSendNextFrame() break; #endif -#if defined(PXX1) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML) - case PROTOCOL_CHANNELS_PXX1_SERIAL: - ExtmoduleSerialDriver.sendBuffer(extmodulePulsesData.pxx_uart.getData(), - extmodulePulsesData.pxx_uart.getSize()); - break; -#endif - #if defined(AFHDS3) case PROTOCOL_CHANNELS_AFHDS3: #if defined(EXTMODULE_USART) && defined(EXTMODULE_TX_INVERT_GPIO) diff --git a/radio/src/pulses/pxx1.cpp b/radio/src/pulses/pxx1.cpp index bb592760b..833cb53b2 100644 --- a/radio/src/pulses/pxx1.cpp +++ b/radio/src/pulses/pxx1.cpp @@ -231,17 +231,13 @@ static const etx_serial_init pxx1SerialInit = { .stop_bits = ETX_StopBits_One, .word_length = ETX_WordLength_8, .rx_enable = false, - .rx_dma_buf = nullptr, - .rx_dma_buf_len = 0, .on_receive = intmoduleFifoReceive, .on_error = intmoduleFifoError, }; static void* pxx1InitInternal(uint8_t module) { - (void)module; - - IntmoduleSerialDriver.init(&pxx1SerialInit); + void* uart_ctx = IntmoduleSerialDriver.init(&pxx1SerialInit); #if defined(INTMODULE_HEARTBEAT) init_intmodule_heartbeat(); @@ -249,19 +245,17 @@ static void* pxx1InitInternal(uint8_t module) mixerSchedulerSetPeriod(INTERNAL_MODULE, INTMODULE_PXX1_SERIAL_PERIOD); INTERNAL_MODULE_ON(); - return nullptr; + return uart_ctx; } static void pxx1DeInitInternal(void* context) { - (void)context; - INTERNAL_MODULE_OFF(); mixerSchedulerSetPeriod(INTERNAL_MODULE, 0); #if defined(INTMODULE_HEARTBEAT) stop_intmodule_heartbeat(); #endif - IntmoduleSerialDriver.deinit(); + IntmoduleSerialDriver.deinit(context); } static void pxx1SetupPulsesInternal(void* context, int16_t* channels, uint8_t nChannels) @@ -276,8 +270,7 @@ static void pxx1SetupPulsesInternal(void* context, int16_t* channels, uint8_t nC static void pxx1SendPulsesInternal(void* context) { - (void)context; - IntmoduleSerialDriver.sendBuffer(intmodulePulsesData.pxx_uart.getData(), + IntmoduleSerialDriver.sendBuffer(context, intmodulePulsesData.pxx_uart.getData(), intmodulePulsesData.pxx_uart.getSize()); } @@ -290,3 +283,60 @@ const etx_module_driver_t Pxx1InternalSerialDriver = { }; #endif + +#if defined(EXTMODULE_USART) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML) +#include "extmodule_serial_driver.h" + +static const etx_serial_init pxx1ExtSerialInit = { + .baudrate = EXTMODULE_PXX1_SERIAL_BAUDRATE, + .parity = ETX_Parity_None, + .stop_bits = ETX_StopBits_One, + .word_length = ETX_WordLength_8, + .rx_enable = false, + .on_receive = extmoduleFifoReceive, + .on_error = extmoduleFifoError, +}; + +static void* pxx1InitExternal(uint8_t module) +{ + void* uart_ctx = ExtmoduleSerialDriver.init(&pxx1ExtSerialInit); + + mixerSchedulerSetPeriod(EXTERNAL_MODULE, EXTMODULE_PXX1_SERIAL_PERIOD); + EXTERNAL_MODULE_ON(); + + return uart_ctx; +} + +static void pxx1DeInitExternal(void* context) +{ + EXTERNAL_MODULE_OFF(); + mixerSchedulerSetPeriod(EXTERNAL_MODULE, 0); + ExtmoduleSerialDriver.deinit(context); +} + +static void pxx1SetupPulsesExternal(void* context, int16_t* channels, uint8_t nChannels) +{ + (void)context; + + // TODO: + (void)channels; + (void)nChannels; + + extmodulePulsesData.pxx_uart.setupFrame(EXTERNAL_MODULE); +} + +static void pxx1SendPulsesExternal(void* context) +{ + ExtmoduleSerialDriver.sendBuffer(context, extmodulePulsesData.pxx_uart.getData(), + extmodulePulsesData.pxx_uart.getSize()); +} + +const etx_module_driver_t Pxx1ExternalSerialDriver = { + .protocol = PROTOCOL_CHANNELS_PXX1_SERIAL, + .init = pxx1InitExternal, + .deinit = pxx1DeInitExternal, + .setupPulses = pxx1SetupPulsesExternal, + .sendPulses = pxx1SendPulsesExternal, +}; + +#endif diff --git a/radio/src/pulses/pxx1.h b/radio/src/pulses/pxx1.h index 40d219d55..84b1259c6 100644 --- a/radio/src/pulses/pxx1.h +++ b/radio/src/pulses/pxx1.h @@ -168,6 +168,12 @@ typedef Pxx1Pulses UartPxx1Pulses; typedef Pxx1Pulses> PwmPxx1Pulses; typedef Pxx1Pulses> SerialPxx1Pulses; +#if defined(INTMODULE_USART) extern const etx_module_driver_t Pxx1InternalSerialDriver; +#endif + +#if defined(EXTMODULE_USART) +extern const etx_module_driver_t Pxx1ExternalSerialDriver; +#endif #endif diff --git a/radio/src/pulses/pxx2.cpp b/radio/src/pulses/pxx2.cpp index bab20cb05..6fe768266 100644 --- a/radio/src/pulses/pxx2.cpp +++ b/radio/src/pulses/pxx2.cpp @@ -36,8 +36,6 @@ const etx_serial_init pxx2SerialInitParams = { .stop_bits = ETX_StopBits_One, .word_length = ETX_WordLength_8, .rx_enable = true, - .rx_dma_buf = nullptr, - .rx_dma_buf_len = 0, .on_receive = intmoduleFifoReceive, .on_error = intmoduleFifoError, }; @@ -652,7 +650,7 @@ void Pxx2OtaUpdate::flashFirmware(const char * filename, ProgressHandler progres static void* pxx2InitInternal(uint8_t moduleType) { intmoduleFifo.clear(); - IntmoduleSerialDriver.init(&pxx2SerialInitParams); + void* uart_ctx = IntmoduleSerialDriver.init(&pxx2SerialInitParams); resetAccessAuthenticationCount(); #if defined(INTMODULE_HEARTBEAT) @@ -662,13 +660,13 @@ static void* pxx2InitInternal(uint8_t moduleType) mixerSchedulerSetPeriod(INTERNAL_MODULE, PXX2_PERIOD); INTERNAL_MODULE_ON(); - return nullptr; + return uart_ctx; } static void pxx2DeInitInternal(void* context) { INTERNAL_MODULE_OFF(); - IntmoduleSerialDriver.deinit(); + IntmoduleSerialDriver.deinit(context); #if defined(INTMODULE_HEARTBEAT) stop_intmodule_heartbeat(); #endif @@ -694,10 +692,8 @@ static void pxx2SetupPulsesInternal(void* context, int16_t* channels, uint8_t nC static void pxx2SendPulsesInternal(void* context) { - (void)context; - if (pxx2InternalSendNextFrame) { - IntmoduleSerialDriver.sendBuffer(intmodulePulsesData.pxx2.getData(), + IntmoduleSerialDriver.sendBuffer(context, intmodulePulsesData.pxx2.getData(), intmodulePulsesData.pxx2.getSize()); } } @@ -721,8 +717,6 @@ static const etx_serial_init pxx2ExtSerialInitParams = { .stop_bits = ETX_StopBits_One, .word_length = ETX_WordLength_8, .rx_enable = true, - .rx_dma_buf = nullptr, - .rx_dma_buf_len = 0, .on_receive = extmoduleFifoReceive, .on_error = extmoduleFifoError, }; @@ -743,21 +737,19 @@ static void* pxx2InitExternal(uint8_t module) { etx_serial_init params(pxx2ExtSerialInitParams); params.baudrate = PXX2_HIGHSPEED_BAUDRATE; - ExtmoduleSerialDriver.init(¶ms); + void* uart_ctx = ExtmoduleSerialDriver.init(¶ms); mixerSchedulerSetPeriod(EXTERNAL_MODULE, PXX2_NO_HEARTBEAT_PERIOD); EXTERNAL_MODULE_ON(); - return nullptr; + return uart_ctx; } static void pxx2DeInitExternal(void* context) { - (void)context; - EXTERNAL_MODULE_OFF(); mixerSchedulerSetPeriod(EXTERNAL_MODULE, 0); - ExtmoduleSerialDriver.deinit(); + ExtmoduleSerialDriver.deinit(context); } static void pxx2SetupPulsesExternal(void* context, int16_t* channels, uint8_t nChannels) @@ -768,8 +760,7 @@ static void pxx2SetupPulsesExternal(void* context, int16_t* channels, uint8_t nC static void pxx2SendPulsesExternal(void* context) { - (void)context; - ExtmoduleSerialDriver.sendBuffer(extmodulePulsesData.pxx2.getData(), + ExtmoduleSerialDriver.sendBuffer(context, extmodulePulsesData.pxx2.getData(), extmodulePulsesData.pxx2.getSize()); } diff --git a/radio/src/sbus.cpp b/radio/src/sbus.cpp index 8ed40d1c0..1c61f9b74 100644 --- a/radio/src/sbus.cpp +++ b/radio/src/sbus.cpp @@ -36,14 +36,45 @@ #define SBUS_CH_CENTER 0x3E0 +static int (*_sbusAuxGetByte)(void*, uint8_t*) = nullptr; +static void* _sbusAuxGetByteCtx = nullptr; + +void sbusSetAuxGetByte(void* ctx, int (*fct)(void*, uint8_t*)) +{ + _sbusAuxGetByte = nullptr; + _sbusAuxGetByteCtx = ctx; + _sbusAuxGetByte = fct; +} + +int sbusAuxGetByte(uint8_t* byte) +{ + auto _getByte = _sbusAuxGetByte; + auto _ctx = _sbusAuxGetByteCtx; + + if (_getByte) { + return _getByte(_ctx, byte); + } + + return -1; +} + +static int (*sbusGetByte)(uint8_t*) = nullptr; + +void sbusSetGetByte(int (*fct)(uint8_t*)) +{ + sbusGetByte = fct; +} + // Range for pulses (ppm input) is [-512:+512] void processSbusFrame(uint8_t * sbus, int16_t * pulses, uint32_t size) { - if (size != SBUS_FRAME_SIZE || sbus[0] != SBUS_START_BYTE || sbus[SBUS_FRAME_SIZE-1] != SBUS_END_BYTE) { - return; // not a valid SBUS frame + if (size != SBUS_FRAME_SIZE || sbus[0] != SBUS_START_BYTE || + sbus[SBUS_FRAME_SIZE - 1] != SBUS_END_BYTE) { + return; // not a valid SBUS frame } - if ((sbus[SBUS_FLAGS_IDX] & (1< 0)) { active = 1; - if (SbusIndex > SBUS_FRAME_SIZE-1) { - SbusIndex = SBUS_FRAME_SIZE-1; + if (SbusIndex > SBUS_FRAME_SIZE - 1) { + SbusIndex = SBUS_FRAME_SIZE - 1; } SbusFrame[SbusIndex++] = rxchar; } if (active) { SbusTimer = getTmr2MHz(); return; - } - else { + } else { if (SbusIndex) { - if ((uint16_t) (getTmr2MHz() - SbusTimer) > SBUS_FRAME_GAP_DELAY) { + if ((uint16_t)(getTmr2MHz() - SbusTimer) > SBUS_FRAME_GAP_DELAY) { processSbusFrame(SbusFrame, ppmInput, SbusIndex); SbusIndex = 0; } } } -#endif } diff --git a/radio/src/sbus.h b/radio/src/sbus.h index f6a1b4579..981a7c7ed 100644 --- a/radio/src/sbus.h +++ b/radio/src/sbus.h @@ -25,6 +25,17 @@ #define SBUS_BAUDRATE 100000 #define SBUS_FRAME_SIZE 25 +// Setup SBUS AUX serial input +void sbusSetAuxGetByte(void* ctx, int (*fct)(void*, uint8_t*)); + +// SBUS AUX serial getter: +// if set, it will fetch data from the handler set +// with sbusSetAuxGetByte() +int sbusAuxGetByte(uint8_t* byte); + +// Setup general SBUS input source +void sbusSetGetByte(int (*fct)(uint8_t*)); + void processSbusInput(); #endif // _SBUS_H_ diff --git a/radio/src/serial.cpp b/radio/src/serial.cpp index 0df948283..8c9460f65 100644 --- a/radio/src/serial.cpp +++ b/radio/src/serial.cpp @@ -24,42 +24,279 @@ #include #include #include "aux_serial_driver.h" +#include "hal/serial_port.h" #define PRINTF_BUFFER_SIZE 128 -void serialPutc(char c) { -#if !defined(BOOT) && defined(USB_SERIAL) - if (getSelectedUsbMode() == USB_SERIAL_MODE) - usbSerialPutc(c); -#endif -#if defined(AUX_SERIAL) - if (auxSerialTracesEnabled()) - auxSerialPutc(c); -#endif -#if defined(AUX2_SERIAL) - if (aux2SerialTracesEnabled()) - aux2SerialPutc(c); -#endif +static void (*dbg_serial_putc)(void*, uint8_t) = nullptr; +static void* dbg_serial_ctx = nullptr; + +void dbgSerialSetSendCb(void* ctx, void (*cb)(void*, uint8_t)) +{ + dbg_serial_putc = nullptr; + dbg_serial_ctx = ctx; + dbg_serial_putc = cb; } -void serialPrintf(const char * format, ...) +extern "C" void dbgSerialPutc(char c) +{ + auto _putc = dbg_serial_putc; + auto _ctx = dbg_serial_ctx; + if (_putc) _putc(_ctx, c); +} + +extern "C" void dbgSerialPrintf(const char * format, ...) { va_list arglist; char tmp[PRINTF_BUFFER_SIZE+1]; + // no need to do anything if we don't have an output + if (!dbg_serial_putc) return; + va_start(arglist, format); vsnprintf(tmp, PRINTF_BUFFER_SIZE, format, arglist); tmp[PRINTF_BUFFER_SIZE] = '\0'; va_end(arglist); const char *t = tmp; - while (*t) { - serialPutc(*t++); + while (*t && dbg_serial_putc) { + dbg_serial_putc(dbg_serial_ctx, *t++); } } -void serialCrlf() +extern "C" void dbgSerialCrlf() { - serialPutc('\r'); - serialPutc('\n'); + dbgSerialPutc('\r'); + dbgSerialPutc('\n'); +} + +static int getAuxSerialMode(uint8_t port_nr) +{ +#if !defined(BOOT) + if (port_nr == 0) { + return g_eeGeneral.auxSerialMode; + } + +// TODO: change in datastruct_private.h +#if defined(PCBHORUS) || defined(PCBNV14) + if (port_nr == 1) { + return g_eeGeneral.aux2SerialMode; + } +#endif +#endif + + return UART_MODE_NONE; +} + +struct AuxSerialPortState +{ + uint8_t mode; + const etx_serial_port_t* port; + void* usart_ctx; +}; + +static AuxSerialPortState auxSerialPortStates[MAX_AUX_SERIAL]; + +static AuxSerialPortState* auxGetPortState(int port_nr) +{ + if (port_nr >= MAX_AUX_SERIAL) return nullptr; + return &auxSerialPortStates[port_nr]; +} + +// TODO: replace serialSetupCallBacks & serialSetupPort +// with usage based handlers. +// +static void serialSetCallBacks(int mode, void* ctx, const etx_serial_port_t* port) +{ + void (*sendByte)(void*, uint8_t) = nullptr; + int (*getByte)(void*, uint8_t*) = nullptr; + + if (port) { + sendByte = port->uart->sendByte; + getByte = port->uart->getByte; + } + + switch(mode) { +#if defined(DEBUG) + case UART_MODE_DEBUG: + // TODO: should we handle 2 outputs? + dbgSerialSetSendCb(ctx, sendByte); + (void)getByte; + break; +#endif + +#if !defined(BOOT) +#if defined(LUA) + case UART_MODE_LUA: + luaSetSendCb(ctx, sendByte); + luaSetGetSerialByte(ctx, getByte); + break; +#endif + +#if defined(SBUS_TRAINER) + case UART_MODE_SBUS_TRAINER: + sbusSetAuxGetByte(ctx, getByte); + break; +#endif + + case UART_MODE_TELEMETRY: + telemetrySetGetByte(ctx, getByte); + break; + + case UART_MODE_TELEMETRY_MIRROR: + telemetrySetMirrorCb(ctx, sendByte); + break; +#endif + } +} + +static void serialSetupPort(int mode, etx_serial_init& params, bool& power_required) +{ + switch (mode) { + +#if defined(DEBUG) || defined(CLI) + case UART_MODE_DEBUG: + params.baudrate = DEBUG_BAUDRATE; + break; +#endif + +#if !defined(BOOT) + case UART_MODE_TELEMETRY_MIRROR: + // TODO: query telemetry baudrate / add setting for module + power_required = true; +#if defined(CROSSFIRE) + if (modelTelemetryProtocol() == PROTOCOL_TELEMETRY_CROSSFIRE) { + params.baudrate = CROSSFIRE_TELEM_MIRROR_BAUDRATE; + break; + } +#endif + params.baudrate = FRSKY_TELEM_MIRROR_BAUDRATE; + break; + + case UART_MODE_TELEMETRY: + if (modelTelemetryProtocol() == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY) { + params.baudrate = FRSKY_D_BAUDRATE; + params.rx_enable = true; + power_required = true; + } + break; + + case UART_MODE_SBUS_TRAINER: + params.baudrate = SBUS_BAUDRATE; + params.word_length = ETX_WordLength_9; + params.parity = ETX_Parity_Even; + params.stop_bits = ETX_StopBits_Two; + params.rx_enable = true; + power_required = true; + break; + +#if defined(LUA) + case UART_MODE_LUA: + params.baudrate = LUA_DEFAULT_BAUDRATE; + params.rx_enable = true; + power_required = true; + break; +#endif +#endif + } +} + +void serialInit(int port_nr, int mode) +{ + if (port_nr >= MAX_AUX_SERIAL) return; + + auto state = auxGetPortState(port_nr); + if (!state) return; + + auto port = auxSerialGetPort(port_nr); + if (!port) return; + + if (state->port) { + auto drv = state->port->uart; + if (drv->deinit) { + drv->deinit(state->usart_ctx); + } + if (state->mode != 0) { + // Clear callbacks + serialSetCallBacks(mode, nullptr, nullptr); + } + memset(state, 0, sizeof(AuxSerialPortState)); + } + + etx_serial_init params = { + .baudrate = 0, + .parity = ETX_Parity_None, + .stop_bits = ETX_StopBits_One, + .word_length = ETX_WordLength_8, + .rx_enable = false, + .on_receive = nullptr, + .on_error = nullptr, + }; + + bool power_required = false; + serialSetupPort(mode, params, power_required); + + if (params.baudrate != 0) { + state->mode = mode; + state->port = port; + state->usart_ctx = port->uart->init(¶ms); + + // Set power on/off + if (port->set_pwr) { + port->set_pwr(power_required); + } + + // Update callbacks once the port is setup + serialSetCallBacks(mode, state->usart_ctx, state->port); + } +} + +void initSerialPorts() +{ + memset(auxSerialPortStates, 0, sizeof(auxSerialPortStates)); + + for (int port_nr = 0; port_nr < MAX_AUX_SERIAL; port_nr++) { + auto mode = getAuxSerialMode(port_nr); + serialInit(port_nr, mode); + } +} + +uint8_t serialGetMode(int port_nr) +{ + auto state = auxGetPortState(port_nr); + if (!state) return UART_MODE_NONE; + return state->mode; +} + +uint8_t serialTracesEnabled(int port_nr) +{ +#if defined(DEBUG) + return serialGetMode(port_nr) == UART_MODE_DEBUG; +#else + return false; +#endif +} + +void serialStop(int port_nr) +{ + auto state = auxGetPortState(port_nr); + if (!state) return; + + if (state->port) { + auto drv = state->port->uart; + if (drv && drv->deinit) { + drv->deinit(state->usart_ctx); + } + memset(state, 0, sizeof(AuxSerialPortState)); + } +} + +void serialPutc(int port_nr, uint8_t c) +{ + auto state = auxGetPortState(port_nr); + if (!state) return; + + if (state->port) { + state->port->uart->sendByte(state->usart_ctx, c); + } } diff --git a/radio/src/serial.h b/radio/src/serial.h index 4e596016c..a9e8133bf 100644 --- a/radio/src/serial.h +++ b/radio/src/serial.h @@ -22,19 +22,52 @@ #ifndef _SERIAL_H_ #define _SERIAL_H_ +#include + +#define MAX_AUX_SERIAL 2 + +void initSerialPorts(); +uint8_t serialGetMode(int port_nr); +uint8_t serialTracesEnabled(int port_nr); +void serialInit(int port_nr, int mode); +void serialStop(int port_nr); +void serialPutc(int port_nr, uint8_t c); + +#if defined(AUX_SERIAL) +#define auxSerialSbusInit() serialInit(0, UART_MODE_SBUS_TRAINER) +#define auxSerialGetMode() serialGetMode(0) +#define auxSerialTracesEnabled() serialTracesEnabled(0) +#define auxSerialStop() serialStop(0) +#define auxSerialPutc(c) serialPutc(0, (c)) +#endif + +#if defined(AUX2_SERIAL) +#define aux2SerialSbusInit() serialInit(1, UART_MODE_SBUS_TRAINER) +#define aux2SerialGetMode() serialGetMode(1) +#define aux2SerialTracesEnabled() serialTracesEnabled(1) +#define aux2SerialStop() serialStop(1) +#define aux2SerialPutc(c) serialPutc(1, (c)) +#endif + +// +// Functions used by debug.h +// #ifdef __cplusplus extern "C" { #endif -void serialPutc(char c); -void serialPrintf(const char *format, ...); -void serialCrlf(); +void dbgSerialPutc(char c); +void dbgSerialPrintf(const char *format, ...); +void dbgSerialCrlf(); #ifdef __cplusplus } #endif -#define serialPrint(...) do { serialPrintf(__VA_ARGS__); serialCrlf(); } while(0) +#define dbgSerialPrint(...) do { dbgSerialPrintf(__VA_ARGS__); dbgSerialCrlf(); } while(0) + +// Debug serial callback +void dbgSerialSetSendCb(void* ctx, void (*cb)(void*, uint8_t)); #endif // _SERIAL_H_ diff --git a/radio/src/targets/common/arm/stm32/CMakeLists.txt b/radio/src/targets/common/arm/stm32/CMakeLists.txt index 242b3176c..eae3fdbbd 100644 --- a/radio/src/targets/common/arm/stm32/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/CMakeLists.txt @@ -29,7 +29,6 @@ set(STM32USB_SRC set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} ../common/arm/stm32/rtc_driver.cpp - ${AUX_SERIAL_DRIVER} ../common/arm/stm32/delays_driver.cpp ../common/arm/stm32/usb_bsp.c ../common/arm/stm32/usbd_desc.c @@ -40,6 +39,18 @@ set(FIRMWARE_TARGET_SRC ../common/arm/stm32/usbd_hid_joystick.c ) +if(AUX_SERIAL OR AUX2_SERIAL) + set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} + ../common/arm/stm32/aux_serial_driver.cpp + ) + if(AUX_SERIAL) + add_definitions(-DAUX_SERIAL) + endif() + if(AUX2_SERIAL) + add_definitions(-DAUX2_SERIAL) + endif() +endif() + if(DEBUG OR CLI OR USB_SERIAL) set(STM32USB_SRC ${STM32USB_SRC} @@ -70,7 +81,6 @@ endif() set(FIRMWARE_SRC ${FIRMWARE_SRC} - serial.cpp syscalls.c ) diff --git a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp index 2c5909d5f..141a896fb 100644 --- a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp +++ b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp @@ -26,8 +26,71 @@ #include "targets/horus/board.h" #include "aux_serial_driver.h" +#include "fifo.h" +#include "dmafifo.h" + +typedef DMAFifo<32> AuxSerialRxFifo; + +struct AuxSerialState +{ + Fifo* txFifo; + AuxSerialRxFifo* rxFifo; + + const stm32_usart_t* usart; +}; + +static void* aux_serial_init(struct AuxSerialState* st, const etx_serial_init* params) +{ + stm32_usart_init(st->usart, params); + + if (params->rx_enable && st->usart->rxDMA && !params->on_receive) { + st->rxFifo->clear(); + stm32_usart_init_rx_dma(st->usart, st->rxFifo->buffer(), st->rxFifo->size()); + } + + return st; +} + +static void aux_serial_putc(void* ctx, uint8_t c) +{ + AuxSerialState* st = (AuxSerialState*)ctx; + if (st->txFifo->isFull()) return; + st->txFifo->push(c); + + // Send is based on IRQ, so that this + // only enables the corresponding IRQ + stm32_usart_send_buffer(st->usart, &c, 1); +} + +static void aux_serial_send_buffer(void* ctx, const uint8_t* data, uint8_t size) +{ + while(size > 0) { + aux_serial_putc(ctx, *data++); + size--; + } +} + +static void aux_wait_tx_completed(void* ctx) +{ + // TODO + (void)ctx; +} + +static int aux_get_byte(void* ctx, uint8_t* data) +{ + AuxSerialState* st = (AuxSerialState*)ctx; + if (!st->rxFifo) return -1; + return st->rxFifo->pop(*data); +} + +void aux_serial_deinit(void* ctx) +{ + AuxSerialState* st = (AuxSerialState*)ctx; + stm32_usart_deinit(st->usart); +} + #if defined(AUX_SERIAL) -uint8_t auxSerialMode = UART_MODE_COUNT; // Prevent debug output before port is setup + Fifo auxSerialTxFifo; #if defined(AUX_SERIAL_DMA_Stream_RX) @@ -65,166 +128,53 @@ const stm32_usart_t auxUSART = { #endif }; -static bool auxSerialOnSend(uint8_t& data) +AuxSerialState auxSerialState = { + .txFifo = &auxSerialTxFifo, + .rxFifo = &auxSerialRxFifo, + .usart = &auxUSART, +}; + +// TODO: grab context to get buffer +static bool auxSerialOnSend(uint8_t* data) { - return auxSerialTxFifo.pop(data); + return auxSerialTxFifo.pop(*data); } +// TODO: add to state static etx_serial_callbacks_t auxSerialCb = { .on_send = auxSerialOnSend, .on_receive = nullptr, .on_error = nullptr, }; -void auxSerialSetup(unsigned int baudrate, bool rx_enable, uint8_t word_length, - uint8_t parity, uint8_t stop_bits) +static void* auxSerialInit(const etx_serial_init* params) { -#if defined(AUX_SERIAL_PWR_GPIO) - LL_GPIO_InitTypeDef pinInit; - LL_GPIO_StructInit(&pinInit); - pinInit.Pin = AUX_SERIAL_PWR_GPIO_PIN; - pinInit.Mode = LL_GPIO_MODE_OUTPUT; - pinInit.Pull = LL_GPIO_PULL_UP; - LL_GPIO_Init(AUX_SERIAL_PWR_GPIO, &pinInit); -#endif - -#if defined(AUX_SERIAL_TX_INVERT_GPIO_PIN) // NV14 - // TODO - GPIO_InitStructure.GPIO_Pin = AUX_SERIAL_TX_INVERT_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(AUX_SERIAL_TX_INVERT_GPIO, &GPIO_InitStructure); - GPIO_ResetBits(AUX_SERIAL_TX_INVERT_GPIO, AUX_SERIAL_TX_INVERT_GPIO_PIN); -#endif - -#if defined(AUX_SERIAL_RX_INVERT_GPIO_PIN) // NV14 - // TODO - GPIO_InitStructure.GPIO_Pin = AUX_SERIAL_RX_INVERT_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(AUX_SERIAL_RX_INVERT_GPIO, &GPIO_InitStructure); - GPIO_ResetBits(AUX_SERIAL_RX_INVERT_GPIO, AUX_SERIAL_RX_INVERT_GPIO_PIN); -#endif - - etx_serial_init serialInit = { - .baudrate = baudrate, - .parity = parity, - .stop_bits = stop_bits, - .word_length = word_length, - .rx_enable = rx_enable, - .rx_dma_buf = nullptr, - .rx_dma_buf_len = 0, - .on_receive = nullptr, // TODO - .on_error = nullptr, // TODO - }; - -#if defined(AUX_SERIAL_DMA_Stream_RX) - if (rx_enable) { - auxSerialRxFifo.clear(); - serialInit.rx_dma_buf = auxSerialRxFifo.buffer(); - serialInit.rx_dma_buf_len = auxSerialRxFifo.size(); - } -#endif - - stm32_usart_init(&auxUSART, &serialInit); + return aux_serial_init(&auxSerialState, params); } +const etx_serial_driver_t AuxSerialDriver = { + .init = auxSerialInit, + .deinit = aux_serial_deinit, + .sendByte = aux_serial_putc, + .sendBuffer = aux_serial_send_buffer, + .waitForTxCompleted = aux_wait_tx_completed, + .getByte = aux_get_byte, + .setReceiveCb = nullptr, + .setOnErrorCb = nullptr, +}; + extern "C" void AUX_SERIAL_USART_IRQHandler(void) { DEBUG_INTERRUPT(INT_SER2); stm32_usart_isr(&auxUSART, &auxSerialCb); } -void auxSerialPutc(uint8_t c) -{ - if (auxSerialTxFifo.isFull()) return; - auxSerialTxFifo.push(c); - stm32_usart_send_buffer(&auxUSART, &c, 1); -} - -void auxSerialStop() -{ - stm32_usart_deinit(&auxUSART); -} - -static void serialPushLua(uint8_t data) -{ - // TODO: this should be set by LUA instead of - // including some LUA header here. - // - // if (luaRxFifo) - // luaRxFifo->push(data); -} - -void auxSerialInit(unsigned int mode, unsigned int protocol) -{ - auxSerialStop(); - - auxSerialMode = mode; - auxSerialCb.on_receive = nullptr; - - switch (mode) { - case UART_MODE_TELEMETRY_MIRROR: - // TODO: add a setting for the telemetry protocol ??? - // -> how do we know the baudrate? -#if defined(CROSSFIRE) - if (protocol == PROTOCOL_TELEMETRY_CROSSFIRE) { - auxSerialSetup(CROSSFIRE_TELEM_MIRROR_BAUDRATE, false); - AUX_SERIAL_POWER_ON(); - break; - } -#endif - auxSerialSetup(FRSKY_TELEM_MIRROR_BAUDRATE, false); - AUX_SERIAL_POWER_ON(); - break; - -#if defined(DEBUG) || defined(CLI) - case UART_MODE_DEBUG: - auxSerialSetup(DEBUG_BAUDRATE, false); - AUX_SERIAL_POWER_OFF(); - break; -#endif - - case UART_MODE_TELEMETRY: - if (protocol == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY) { - auxSerialSetup(FRSKY_D_BAUDRATE, true); - AUX_SERIAL_POWER_ON(); - } - break; - - case UART_MODE_SBUS_TRAINER: - auxSerialSetup( - SBUS_BAUDRATE, true, ETX_WordLength_9, ETX_Parity_Even, - ETX_StopBits_Two); // USART_WordLength_9b due to parity bit - AUX_SERIAL_POWER_ON(); - break; - -#if defined(LUA) - case UART_MODE_LUA: - auxSerialSetup(LUA_DEFAULT_BAUDRATE, false); - auxSerialCb.on_receive = serialPushLua; - AUX_SERIAL_POWER_ON(); - break; -#endif - } -} - -void auxSerialSbusInit() -{ - auxSerialInit(UART_MODE_SBUS_TRAINER, 0); -} - -uint8_t auxSerialTracesEnabled() -{ -#if defined(DEBUG) - return (auxSerialMode == UART_MODE_DEBUG); -#else - return false; -#endif -} #endif // AUX_SERIAL #if defined(AUX2_SERIAL) -uint8_t aux2SerialMode = UART_MODE_COUNT; // Prevent debug output before port is setup + Fifo aux2SerialTxFifo; + AuxSerialRxFifo aux2SerialRxFifo __DMA (AUX2_SERIAL_DMA_Stream_RX); const LL_GPIO_InitTypeDef aux2USARTPinInit = { @@ -250,9 +200,15 @@ const stm32_usart_t aux2USART = { .rxDMA_Channel = AUX2_SERIAL_DMA_Channel_RX, }; -static bool aux2SerialOnSend(uint8_t& data) +AuxSerialState aux2SerialState = { + .txFifo = &aux2SerialTxFifo, + .rxFifo = &aux2SerialRxFifo, + .usart = &aux2USART, +}; + +static bool aux2SerialOnSend(uint8_t* data) { - return aux2SerialTxFifo.pop(data); + return aux2SerialTxFifo.pop(*data); } static etx_serial_callbacks_t aux2SerialCb = { @@ -261,35 +217,9 @@ static etx_serial_callbacks_t aux2SerialCb = { .on_error = nullptr, }; -void aux2SerialSetup(unsigned int baudrate, bool rx_enable, uint8_t word_length, - uint8_t parity, uint8_t stop_bits) +void* aux2SerialInit(const etx_serial_init* params) { - etx_serial_init serialInit = { - .baudrate = baudrate, - .parity = parity, - .stop_bits = stop_bits, - .word_length = word_length, - .rx_enable = rx_enable, - .rx_dma_buf = nullptr, - .rx_dma_buf_len = 0, - .on_receive = nullptr, // TODO - .on_error = nullptr, // TODO - }; - - if (rx_enable) { - aux2SerialRxFifo.clear(); - serialInit.rx_dma_buf = aux2SerialRxFifo.buffer(); - serialInit.rx_dma_buf_len = aux2SerialRxFifo.size(); - } - - stm32_usart_init(&aux2USART, &serialInit); - -// #if defined(AUX2_SERIAL_PWR_GPIO) -// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; -// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; -// GPIO_InitStructure.GPIO_Pin = AUX2_SERIAL_PWR_GPIO_PIN; -// GPIO_Init(AUX2_SERIAL_PWR_GPIO, &GPIO_InitStructure); -// #endif + return aux_serial_init(&aux2SerialState, params); } extern "C" void AUX2_SERIAL_USART_IRQHandler(void) @@ -298,81 +228,15 @@ extern "C" void AUX2_SERIAL_USART_IRQHandler(void) stm32_usart_isr(&aux2USART, &aux2SerialCb); } -void aux2SerialPutc(uint8_t c) -{ - if (aux2SerialTxFifo.isFull()) return; - aux2SerialTxFifo.push(c); - stm32_usart_send_buffer(&aux2USART, &c, 1); -} - -void aux2SerialStop() -{ - stm32_usart_deinit(&aux2USART); -} - -void aux2SerialInit(unsigned int mode, unsigned int protocol) -{ - aux2SerialStop(); - - aux2SerialMode = mode; - aux2SerialCb.on_receive = nullptr; - - switch (mode) { - case UART_MODE_TELEMETRY_MIRROR: -#if defined(CROSSFIRE) - if (protocol == PROTOCOL_TELEMETRY_CROSSFIRE) { - aux2SerialSetup(CROSSFIRE_TELEM_MIRROR_BAUDRATE, false); - AUX2_SERIAL_POWER_ON(); - break; - } -#endif - aux2SerialSetup(FRSKY_TELEM_MIRROR_BAUDRATE, false); - AUX2_SERIAL_POWER_ON(); - break; - -#if defined(DEBUG) || defined(CLI) - case UART_MODE_DEBUG: - aux2SerialSetup(DEBUG_BAUDRATE, false); - AUX2_SERIAL_POWER_OFF(); - break; -#endif - - case UART_MODE_TELEMETRY: - if (protocol == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY) { - aux2SerialSetup(FRSKY_D_BAUDRATE, true); - AUX2_SERIAL_POWER_ON(); - } - break; - - case UART_MODE_SBUS_TRAINER: - aux2SerialSetup( - SBUS_BAUDRATE, true, ETX_WordLength_9, ETX_Parity_Even, - ETX_StopBits_Two); // 2 stop bits requires USART_WordLength_9b - AUX2_SERIAL_POWER_ON(); - break; - -#if defined(LUA) - case UART_MODE_LUA: - aux2SerialSetup(LUA_DEFAULT_BAUDRATE, false); - aux2SerialCb.on_receive = serialPushLua; - AUX2_SERIAL_POWER_ON(); - break; -#endif - } -} - -void aux2SerialSbusInit() -{ - aux2SerialInit(UART_MODE_SBUS_TRAINER, 0); -} - -uint8_t aux2SerialTracesEnabled() -{ -#if defined(DEBUG) - return (aux2SerialMode == UART_MODE_DEBUG); -#else - return false; -#endif -} +const etx_serial_driver_t Aux2SerialDriver = { + .init = aux2SerialInit, + .deinit = aux_serial_deinit, + .sendByte = aux_serial_putc, + .sendBuffer = aux_serial_send_buffer, + .waitForTxCompleted = aux_wait_tx_completed, + .getByte = aux_get_byte, + .setReceiveCb = nullptr, + .setOnErrorCb = nullptr, +}; #endif // AUX2_SERIAL diff --git a/radio/src/targets/common/arm/stm32/aux_serial_driver.h b/radio/src/targets/common/arm/stm32/aux_serial_driver.h index 3dd733d0d..6debae13f 100644 --- a/radio/src/targets/common/arm/stm32/aux_serial_driver.h +++ b/radio/src/targets/common/arm/stm32/aux_serial_driver.h @@ -24,28 +24,12 @@ #include "hal/serial_driver.h" #if defined(AUX_SERIAL) -extern uint8_t auxSerialMode; -void auxSerialSetup(unsigned int baudrate, bool rx_enable, - uint8_t word_length = ETX_WordLength_8, - uint8_t parity = ETX_Parity_None, - uint8_t stop_bits = ETX_StopBits_One); -void auxSerialInit(unsigned int mode, unsigned int protocol); -void auxSerialPutc(uint8_t c); -void auxSerialSbusInit(); -void auxSerialStop(); -uint8_t auxSerialTracesEnabled(); + +extern const etx_serial_driver_t AuxSerialDriver; #endif #if defined(AUX2_SERIAL) -extern uint8_t aux2SerialMode; -void aux2SerialSetup(unsigned int baudrate, bool rx_enable, - uint8_t word_length = ETX_WordLength_8, - uint8_t parity = ETX_Parity_None, - uint8_t stop_bits = ETX_StopBits_One); -void aux2SerialInit(unsigned int mode, unsigned int protocol); -void aux2SerialPutc(uint8_t c); -void aux2SerialSbusInit(); -void aux2SerialStop(); -uint8_t aux2SerialTracesEnabled(); + +extern const etx_serial_driver_t Aux2SerialDriver; #endif diff --git a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt index bd8403077..64ba5f989 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt @@ -144,6 +144,7 @@ if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14) ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c ../../../../../serial.cpp ../../../../../targets/common/arm/stm32/aux_serial_driver.cpp + ../../../../../targets/common/arm/stm32/stm32_usart_driver.cpp ) endif() else() diff --git a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp index 6697f8edd..2dbe723bc 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp +++ b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp @@ -244,12 +244,9 @@ int main() #endif delaysInit(); // needed for lcdInit() - -#if defined(DEBUG) && defined(AUX_SERIAL) - auxSerialInit(UART_MODE_DEBUG, 0); // default serial mode (None if DEBUG not defined) -#endif -#if defined(DEBUG) && defined(AUX2_SERIAL) - aux2SerialInit(UART_MODE_DEBUG, 0); // default serial mode (None if DEBUG not defined) + +#if defined(DEBUG) + initSerialPorts(); #endif __enable_irq(); diff --git a/radio/src/targets/common/arm/stm32/extmodule_serial_driver.cpp b/radio/src/targets/common/arm/stm32/extmodule_serial_driver.cpp index edd277928..648b6464b 100644 --- a/radio/src/targets/common/arm/stm32/extmodule_serial_driver.cpp +++ b/radio/src/targets/common/arm/stm32/extmodule_serial_driver.cpp @@ -49,8 +49,6 @@ static const etx_serial_init extmoduleSerialParams = { .stop_bits = ETX_StopBits_One, .word_length = ETX_WordLength_8, .rx_enable = true, - .rx_dma_buf = nullptr, - .rx_dma_buf_len = 0, .on_receive = extmoduleFifoReceive, .on_error = extmoduleFifoError, }; @@ -78,9 +76,9 @@ static const stm32_usart_t extmoduleUSART = { .rxDMA_Channel = 0, }; -static void extmoduleSerialStart(const etx_serial_init* params) +static void* extmoduleSerialStart(const etx_serial_init* params) { - if (!params) return; + if (!params) return nullptr; extmodule_driver.on_receive = params->on_receive; extmodule_driver.on_error = params->on_error; @@ -88,6 +86,8 @@ static void extmoduleSerialStart(const etx_serial_init* params) // UART config stm32_usart_init(&extmoduleUSART, params); extmoduleFifo.clear(); + + return nullptr; } void extmoduleInvertedSerialStart(uint32_t baudrate) @@ -108,7 +108,7 @@ void extmodulePxx1SerialStart() } #endif -void extmoduleSerialStop() +void extmoduleSerialStop(void*) { stm32_usart_deinit(&extmoduleUSART); @@ -117,18 +117,18 @@ void extmoduleSerialStop() extmodule_driver.on_error = nullptr; } -static void extmoduleSendByte(uint8_t byte) +static void extmoduleSendByte(void*, uint8_t byte) { stm32_usart_send_byte(&extmoduleUSART, byte); } -static void extmoduleSendBuffer(const uint8_t * data, uint8_t size) +static void extmoduleSendBuffer(void*, const uint8_t * data, uint8_t size) { if (size == 0) return; stm32_usart_send_buffer(&extmoduleUSART, data, size); } -static void extmoduleWaitForTxCompleted() +static void extmoduleWaitForTxCompleted(void*) { stm32_usart_wait_for_tx_dma(&extmoduleUSART); } diff --git a/radio/src/targets/common/arm/stm32/f4/CMakeLists.txt b/radio/src/targets/common/arm/stm32/f4/CMakeLists.txt index 9b7c61bb0..761c7e671 100644 --- a/radio/src/targets/common/arm/stm32/f4/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/f4/CMakeLists.txt @@ -20,6 +20,7 @@ target_include_directories(stm32cube_ll PRIVATE ${THIRDPARTY_DIR}/CMSIS/Include) set(FIRMWARE_SRC ${FIRMWARE_SRC} $) +set(BOOTLOADER_SRC ${BOOTLOADER_SRC} $) # StdPeriph library set(STM32LIB_DIR ${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries) diff --git a/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp b/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp index 126cb58d4..7e487e2a9 100755 --- a/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp +++ b/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp @@ -28,13 +28,13 @@ ModuleFifo intmoduleFifo; #if !defined(INTMODULE_DMA_STREAM) -uint8_t * intmoduleTxBufferData; -volatile uint8_t intmoduleTxBufferRemaining; +static uint8_t * intmoduleTxBufferData; +static volatile uint8_t intmoduleTxBufferRemaining; -bool intmoduleTxBufferSend(uint8_t& data) +bool intmoduleTxBufferSend(uint8_t* data) { if (intmoduleTxBufferRemaining) { - data = *(intmoduleTxBufferData++); + *data = *(intmoduleTxBufferData++); intmoduleTxBufferRemaining--; return true; } @@ -96,9 +96,15 @@ void intmoduleStop() intmodule_driver.on_error = nullptr; } -void intmoduleSerialStart(const etx_serial_init* params) +static void intmoduleStop(void* ctx) { - if (!params) return; + (void)ctx; + intmoduleStop(); +} + +void* intmoduleSerialStart(const etx_serial_init* params) +{ + if (!params) return nullptr; // TODO: sanity check parameters // - the UART seems to block when initialised with baudrate = 0 @@ -108,6 +114,7 @@ void intmoduleSerialStart(const etx_serial_init* params) intmodule_driver.on_error = params->on_error; stm32_usart_init(&intmoduleUSART, params); + return nullptr; } #define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE) @@ -116,13 +123,15 @@ extern "C" void INTMODULE_USART_IRQHandler(void) stm32_usart_isr(&intmoduleUSART, &intmodule_driver); } -void intmoduleSendByte(uint8_t byte) +void intmoduleSendByte(void* ctx, uint8_t byte) { + (void)ctx; stm32_usart_send_byte(&intmoduleUSART, byte); } -void intmoduleSendBuffer(const uint8_t * data, uint8_t size) +void intmoduleSendBuffer(void* ctx, const uint8_t * data, uint8_t size) { + (void)ctx; if (size == 0) return; @@ -133,8 +142,9 @@ void intmoduleSendBuffer(const uint8_t * data, uint8_t size) stm32_usart_send_buffer(&intmoduleUSART, data, size); } -void intmoduleWaitForTxCompleted() +void intmoduleWaitForTxCompleted(void* ctx) { + (void)ctx; #if defined(INTMODULE_DMA_STREAM) stm32_usart_wait_for_tx_dma(&intmoduleUSART); #else diff --git a/radio/src/targets/common/arm/stm32/stm32_usart_driver.cpp b/radio/src/targets/common/arm/stm32/stm32_usart_driver.cpp index aa29225b9..5ac82b0b8 100644 --- a/radio/src/targets/common/arm/stm32/stm32_usart_driver.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_usart_driver.cpp @@ -22,8 +22,16 @@ #include "stm32_usart_driver.h" #include -static void stm32_usart_init_rx_dma(const stm32_usart_t* usart, void* buffer, uint32_t length) +void stm32_usart_init_rx_dma(const stm32_usart_t* usart, void* buffer, uint32_t length) { + // Disable IRQ based RX + LL_USART_DisableIT_RXNE(usart->USARTx); + + // In case TX DMA is used, disable the ISR completely + if (usart->txDMA) { + NVIC_DisableIRQ(usart->IRQn); + } + LL_DMA_InitTypeDef dmaInit; LL_DMA_StructInit(&dmaInit); dmaInit.Channel = usart->rxDMA_Channel; @@ -47,6 +55,8 @@ void stm32_usart_init(const stm32_usart_t* usart, const etx_serial_init* params) LL_GPIO_Init(usart->GPIOx, (LL_GPIO_InitTypeDef*)usart->pinInit); LL_USART_InitTypeDef usartInit; + LL_USART_StructInit(&usartInit); + usartInit.BaudRate = params->baudrate; uint32_t parity = LL_USART_PARITY_NONE; @@ -96,14 +106,8 @@ void stm32_usart_init(const stm32_usart_t* usart, const etx_serial_init* params) // Enable RX IRQ if (params->rx_enable) { - if (usart->rxDMA) { - // RX DMA - stm32_usart_init_rx_dma(usart, params->rx_dma_buf, - params->rx_dma_buf_len); - } else { - // IRQ based RX - LL_USART_EnableIT_RXNE(usart->USARTx); - } + // IRQ based RX + LL_USART_EnableIT_RXNE(usart->USARTx); } if (!usart->txDMA || (params->rx_enable && !usart->rxDMA)) { @@ -159,7 +163,7 @@ void stm32_usart_send_buffer(const stm32_usart_t* usart, const uint8_t * data, u return; } else { // Please note that we don't use the buffer: - // it should set internally by the driver user + // it should be set internally by the driver user // and each byte is returned individually by on_send() LL_USART_EnableIT_TXE(usart->USARTx); } @@ -204,7 +208,7 @@ void stm32_usart_isr(const stm32_usart_t* usart, etx_serial_callbacks_t* cb) uint32_t status = LL_USART_ReadReg(usart->USARTx, SR); // Receive: do it first as it is more time critical - if (LL_USART_IsEnabledIT_TXE(usart->USARTx)) { + if (LL_USART_IsEnabledIT_RXNE(usart->USARTx)) { // Drain RX while (status & (LL_USART_SR_RXNE | USART_FLAG_ERRORS)) { @@ -229,7 +233,7 @@ void stm32_usart_isr(const stm32_usart_t* usart, etx_serial_callbacks_t* cb) if (LL_USART_IsEnabledIT_TXE(usart->USARTx) && (status & LL_USART_SR_TXE)) { uint8_t data; - if (cb->on_send && cb->on_send(data)) { + if (cb->on_send && cb->on_send(&data)) { LL_USART_TransmitData8(usart->USARTx, data); } else { LL_USART_DisableIT_TXE(usart->USARTx); diff --git a/radio/src/targets/common/arm/stm32/stm32_usart_driver.h b/radio/src/targets/common/arm/stm32/stm32_usart_driver.h index d1a0d7eed..1671d49b4 100644 --- a/radio/src/targets/common/arm/stm32/stm32_usart_driver.h +++ b/radio/src/targets/common/arm/stm32/stm32_usart_driver.h @@ -48,10 +48,10 @@ struct stm32_usart_t { }; void stm32_usart_init(const stm32_usart_t* usart, const etx_serial_init* params); +void stm32_usart_init_rx_dma(const stm32_usart_t* usart, void* buffer, uint32_t length); void stm32_usart_deinit(const stm32_usart_t* usart); void stm32_usart_send_byte(const stm32_usart_t* usart, uint8_t byte); void stm32_usart_send_buffer(const stm32_usart_t* usart, const uint8_t * data, uint32_t size); void stm32_usart_wait_for_tx_dma(const stm32_usart_t* usart); void stm32_usart_isr(const stm32_usart_t* usart, etx_serial_callbacks_t* cb); - diff --git a/radio/src/targets/common/arm/stm32/usb_driver.h b/radio/src/targets/common/arm/stm32/usb_driver.h index cf86cbea1..a12d319c7 100644 --- a/radio/src/targets/common/arm/stm32/usb_driver.h +++ b/radio/src/targets/common/arm/stm32/usb_driver.h @@ -51,7 +51,7 @@ int getSelectedUsbMode(); void setSelectedUsbMode(int mode); uint32_t usbSerialFreeSpace(); -void usbSerialPutc(uint8_t c); +void usbSerialPutc(void*, uint8_t c); uint32_t usbSerialBaudRate(void); diff --git a/radio/src/targets/common/arm/stm32/usbd_cdc.cpp b/radio/src/targets/common/arm/stm32/usbd_cdc.cpp index 3879d74e7..2a005a221 100644 --- a/radio/src/targets/common/arm/stm32/usbd_cdc.cpp +++ b/radio/src/targets/common/arm/stm32/usbd_cdc.cpp @@ -94,6 +94,7 @@ static uint16_t VCP_Init(void) cdcConnected = true; ctrlLineStateCb = NULL; baudRateCb = NULL; + return USBD_OK; } @@ -205,7 +206,7 @@ uint32_t usbSerialFreeSpace() 1; } -void usbSerialPutc(uint8_t c) +void usbSerialPutc(void*, uint8_t c) { /* Apparently there is no reliable way to tell if the @@ -253,21 +254,8 @@ void usbSerialPutc(uint8_t c) */ static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len) { - if (receiveDataCb) - receiveDataCb(Buf, Len); - -// #if defined(CLI) -// // pass data to CLI -// cliReceiveData(Buf, Len); -// #elif defined(LUA) -// // copy data to the LUA FIFO -// if (luaRxFifo) { -// for (uint32_t i = 0; i < Len; i++) { -// luaRxFifo->push(Buf[i]); -// } -// } -// #endif - + auto _rxCb = receiveDataCb; + if (_rxCb) _rxCb(Buf, Len); return USBD_OK; } diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index 870b2f89e..8229e8845 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -245,16 +245,6 @@ if(BLUETOOTH) add_definitions(-DHARDWARE_TRAINER_BLUETOOTH) endif() -if (AUX_SERIAL) - add_definitions(-DAUX_SERIAL) - set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp) -endif() - -if (AUX2_SERIAL) - add_definitions(-DAUX2_SERIAL) - set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp) -endif() - if (SBUS_TRAINER) add_definitions(-DSBUS_TRAINER) set(SRC @@ -266,7 +256,6 @@ endif() set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} ${LCD_DRIVER} - ${AUX_SERIAL_DRIVER} ${FLYSKY_HALL_STICKS_DRIVER} ${IMU_LSM6DS33_DRIVER} ${TOUCH_DRIVER} diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index fccc3036a..8dbc178fb 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -19,13 +19,21 @@ * GNU General Public License for more details. */ +#include "stm32_hal_ll.h" #include "opentx.h" #include "hal/adc_driver.h" -#include "../common/arm/stm32/timers_driver.h" +#include "hal/serial_driver.h" +#include "hal/serial_port.h" + +#include "timers_driver.h" + +#if defined(AUX_SERIAL) || defined(AUX2_SERIAL) +#include "aux_serial_driver.h" +#endif #if !defined(PCBX12S) - #include "../common/arm/stm32/stm32_hal_adc.h" + #include "stm32_hal_adc.h" #define ADC_DRIVER stm32_hal_adc_driver #else #include "x12s_adc_driver.h" @@ -58,30 +66,6 @@ void watchdogInit(unsigned int duration) IWDG->KR = 0xCCCC; // start } -#if defined(AUX_SERIAL_PWR_GPIO) -void auxSerialPowerOn() -{ - GPIO_SetBits(AUX_SERIAL_PWR_GPIO, AUX_SERIAL_PWR_GPIO_PIN); -} - -void auxSerialPowerOff() -{ - GPIO_ResetBits(AUX_SERIAL_PWR_GPIO, AUX_SERIAL_PWR_GPIO_PIN); -} -#endif -#if defined(AUX2_SERIAL_PWR_GPIO) -void aux2SerialPowerOn() -{ - GPIO_SetBits(AUX2_SERIAL_PWR_GPIO, AUX2_SERIAL_PWR_GPIO_PIN); -} - -void aux2SerialPowerOff() -{ - GPIO_ResetBits(AUX2_SERIAL_PWR_GPIO, AUX2_SERIAL_PWR_GPIO_PIN); -} -#endif - - #if HAS_SPORT_UPDATE_CONNECTOR() void sportUpdateInit() { @@ -193,12 +177,7 @@ void boardInit() __enable_irq(); -#if defined(DEBUG) && defined(AUX_SERIAL) - auxSerialInit(UART_MODE_DEBUG, 0); // default serial mode (None if DEBUG not defined) -#endif -#if defined(DEBUG) && defined(AUX2_SERIAL) - aux2SerialInit(UART_MODE_DEBUG, 0); // default serial mode (None if DEBUG not defined) -#endif + initSerialPorts(); TRACE("\nHorus board started :)"); TRACE("RCC->CSR = %08x", RCC->CSR); @@ -359,3 +338,64 @@ bool isBacklightEnabled() return true; return boardBacklightOn; } + +static void _aux_pwr(GPIO_TypeDef *GPIOx, uint32_t pin, uint8_t on) +{ + LL_GPIO_InitTypeDef pinInit; + LL_GPIO_StructInit(&pinInit); + pinInit.Pin = pin; + pinInit.Mode = LL_GPIO_MODE_OUTPUT; + pinInit.Pull = LL_GPIO_PULL_UP; + LL_GPIO_Init(GPIOx, &pinInit); + + if (on) { + LL_GPIO_SetOutputPin(GPIOx, pin); + } else { + LL_GPIO_ResetOutputPin(GPIOx, pin); + } +} + +#if defined(AUX_SERIAL) +void set_aux_pwr(uint8_t on) +{ +#if defined(AUX_SERIAL_PWR_GPIO) + _aux_pwr(AUX_SERIAL_PWR_GPIO, AUX_SERIAL_PWR_GPIO_PIN, on); +#endif +} + +const etx_serial_port_t auxSerialPort = { + &AuxSerialDriver, + set_aux_pwr, +}; +#define AUX_SERIAL_PORT &auxSerialPort +#else +#define AUX_SERIAL_PORT nullptr +#endif + +#if defined(AUX2_SERIAL) +void set_aux2_pwr(uint8_t on) +{ +#if defined(AUX2_SERIAL_PWR_GPIO) + _aux_pwr(AUX2_SERIAL_PWR_GPIO, AUX2_SERIAL_PWR_GPIO_PIN, on); +#endif +} + +const etx_serial_port_t aux2SerialPort = { + &Aux2SerialDriver, + set_aux2_pwr, +}; +#define AUX2_SERIAL_PORT &aux2SerialPort +#else +#define AUX2_SERIAL_PORT nullptr +#endif // AUX2_SERIAL + +static const etx_serial_port_t* serialPorts[MAX_AUX_SERIAL] = { + AUX_SERIAL_PORT, + AUX2_SERIAL_PORT, +}; + +const etx_serial_port_t* auxSerialGetPort(int port_nr) +{ + if (port_nr >= MAX_AUX_SERIAL) return nullptr; + return serialPorts[port_nr]; +} diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index 936da58b6..038d8693f 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -26,6 +26,7 @@ #include "opentx_constants.h" #include "board_common.h" #include "hal.h" +#include "hal/serial_port.h" #include "watchdog_driver.h" @@ -198,9 +199,6 @@ void stop_trainer_ppm(); void init_trainer_capture(); void stop_trainer_capture(); -// SBUS -int sbusGetByte(uint8_t * byte); - // Keys driver enum EnumKeys { @@ -623,7 +621,7 @@ void telemetryPortSetDirectionInput(); void telemetryPortSetDirectionOutput(); void sportSendByte(uint8_t byte); void sportSendBuffer(const uint8_t * buffer, uint32_t count); -bool telemetryGetByte(uint8_t * byte); +bool sportGetByte(uint8_t * byte); void telemetryClearFifo(); extern uint32_t telemetryErrors; @@ -654,32 +652,8 @@ void sportUpdatePowerInit(); #define DEBUG_BAUDRATE 115200 #define LUA_DEFAULT_BAUDRATE 115200 #endif -#if defined(AUX_SERIAL) -#define auxSerialTelemetryInit(protocol) auxSerialInit(UART_MODE_TELEMETRY, protocol) -void auxSerialPowerOn(); -void auxSerialPowerOff(); -#if defined(AUX_SERIAL_PWR_GPIO) -#define AUX_SERIAL_POWER_ON() auxSerialPowerOn() -#define AUX_SERIAL_POWER_OFF() auxSerialPowerOff() -#else -#define AUX_SERIAL_POWER_ON() -#define AUX_SERIAL_POWER_OFF() -#endif -#endif -// Aux2 serial port driver -#if defined(AUX2_SERIAL) -#define aux2SerialTelemetryInit(protocol) aux2SerialInit(UART_MODE_TELEMETRY, protocol) -void aux2SerialPowerOn(); -void aux2SerialPowerOff(); -#if defined(AUX2_SERIAL_PWR_GPIO) -#define AUX2_SERIAL_POWER_ON() aux2SerialPowerOn() -#define AUX2_SERIAL_POWER_OFF() aux2SerialPowerOff() -#else -#define AUX2_SERIAL_POWER_ON() -#define AUX2_SERIAL_POWER_OFF() -#endif -#endif +const etx_serial_port_t* auxSerialGetPort(int port_nr); // Haptic driver void hapticInit(); @@ -711,14 +685,4 @@ void bluetoothWriteWakeup(); uint8_t bluetoothIsWriting(); void bluetoothDisable(); -#if defined(__cplusplus) -#include "fifo.h" -#include "dmafifo.h" -extern DMAFifo<512> telemetryFifo; -typedef DMAFifo<32> AuxSerialRxFifo; -extern AuxSerialRxFifo auxSerialRxFifo; -extern AuxSerialRxFifo aux2SerialRxFifo; -extern volatile uint32_t externalModulePort; -#endif - #endif // _BOARD_H_ diff --git a/radio/src/targets/horus/flyskyHallStick_driver.cpp b/radio/src/targets/horus/flyskyHallStick_driver.cpp index 43ae99448..a2889b2b5 100644 --- a/radio/src/targets/horus/flyskyHallStick_driver.cpp +++ b/radio/src/targets/horus/flyskyHallStick_driver.cpp @@ -22,6 +22,9 @@ #include "opentx.h" #include "flyskyHallStick_driver.h" +#include "fifo.h" +#include "dmafifo.h" + DMAFifo hallDMAFifo __DMA (FLYSKY_HALL_DMA_Stream_RX); Fifo hallStickTxFifo; unsigned char HallCmd[264] __DMA; diff --git a/radio/src/targets/horus/telemetry_driver.cpp b/radio/src/targets/horus/telemetry_driver.cpp index f04de051d..618b07873 100644 --- a/radio/src/targets/horus/telemetry_driver.cpp +++ b/radio/src/targets/horus/telemetry_driver.cpp @@ -21,6 +21,9 @@ #include "opentx.h" +#include "fifo.h" +#include "dmafifo.h" + Fifo telemetryNoDMAFifo; uint32_t telemetryErrors = 0; @@ -415,7 +418,7 @@ extern "C" void TELEMETRY_TIMER_IRQHandler() } // TODO we should have telemetry in an higher layer, functions above should move to a sport_driver.cpp -bool telemetryGetByte(uint8_t * byte) +bool sportGetByte(uint8_t * byte) { #if defined(PCBX12S) if (telemetryFifoMode & TELEMETRY_SERIAL_WITHOUT_DMA) diff --git a/radio/src/targets/horus/trainer_driver.cpp b/radio/src/targets/horus/trainer_driver.cpp index cf3355f2c..6f49e02e7 100644 --- a/radio/src/targets/horus/trainer_driver.cpp +++ b/radio/src/targets/horus/trainer_driver.cpp @@ -142,22 +142,3 @@ extern "C" void TRAINER_TIMER_IRQHandler() } } } - -int sbusGetByte(uint8_t * byte) -{ - switch (currentTrainerMode) { -#if defined(AUX_SERIAL) || defined(AUX2_SERIAL) - case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: -#if defined(AUX_SERIAL) - if (auxSerialMode == UART_MODE_SBUS_TRAINER) - return auxSerialRxFifo.pop(*byte); -#endif -#if defined(AUX2_SERIAL) - if (aux2SerialMode == UART_MODE_SBUS_TRAINER) - return aux2SerialRxFifo.pop(*byte); -#endif -#endif - default: - return false; - } -} diff --git a/radio/src/targets/nv14/board.cpp b/radio/src/targets/nv14/board.cpp index 0eeea7b87..bcede129f 100644 --- a/radio/src/targets/nv14/board.cpp +++ b/radio/src/targets/nv14/board.cpp @@ -23,8 +23,8 @@ #include "touch.h" #include "hal/adc_driver.h" -#include "../common/arm/stm32/stm32_hal_adc.h" -#include "../common/arm/stm32/timers_driver.h" +#include "stm32_hal_adc.h" +#include "timers_driver.h" #if defined(__cplusplus) && !defined(SIMU) extern "C" { @@ -242,3 +242,8 @@ void boardOff() } } + +const etx_serial_port_t* auxSerialGetPort(int port_nr) +{ + return nullptr; +} diff --git a/radio/src/targets/nv14/board.h b/radio/src/targets/nv14/board.h index 41c63a037..a9b730e95 100644 --- a/radio/src/targets/nv14/board.h +++ b/radio/src/targets/nv14/board.h @@ -26,6 +26,7 @@ #include "opentx_constants.h" #include "board_common.h" #include "hal.h" +#include "hal/serial_port.h" #if !defined(LUA_EXPORT_GENERATION) #include "stm32f4xx_sdio.h" @@ -390,9 +391,8 @@ bool pwrPressed(); #endif uint32_t pwrPressedDuration();; -#define AUX_SERIAL_POWER_ON() -#define AUX_SERIAL_POWER_OFF() - +const etx_serial_port_t* auxSerialGetPort(int port_nr); + // LCD driver #define LCD_W 320 #define LCD_H 480 @@ -483,7 +483,7 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode); void telemetryPortSetDirectionOutput(); void telemetryPortSetDirectionInput(); void sportSendBuffer(const uint8_t * buffer, uint32_t count); -bool telemetryGetByte(uint8_t * byte); +bool sportGetByte(uint8_t * byte); void telemetryClearFifo(); void sportSendByte(uint8_t byte); extern uint32_t telemetryErrors; @@ -507,27 +507,10 @@ void hapticOn(uint32_t pwmPercent); //#define AUX_SERIAL #define DEBUG_BAUDRATE 115200 #define LUA_DEFAULT_BAUDRATE 115200 -#define auxSerialTelemetryInit(protocol) auxSerialInit(UART_MODE_TELEMETRY, protocol) - -#if defined(AUX_SERIAL_PWR_GPIO) -#define AUX_SERIAL_POWER_ON() auxSerialPowerOn() -#define AUX_SERIAL__POWER_OFF() auxSerialPowerOff() -#else -#define AUX_SERIAL_POWER_ON() -#define AUX_SERIAL__POWER_OFF() -#endif extern uint8_t currentTrainerMode; void checkTrainerSettings(); -#if defined(__cplusplus) -#include "fifo.h" -#include "dmafifo.h" -extern DMAFifo<512> telemetryFifo; -typedef Fifo AuxSerialRxFifo; -extern AuxSerialRxFifo auxSerialRxFifo; -#endif - // Touch panel driver bool touchPanelEventOccured(); struct TouchState touchPanelRead(); diff --git a/radio/src/targets/nv14/telemetry_driver.cpp b/radio/src/targets/nv14/telemetry_driver.cpp index 53936f914..b94ce7abc 100644 --- a/radio/src/targets/nv14/telemetry_driver.cpp +++ b/radio/src/targets/nv14/telemetry_driver.cpp @@ -215,7 +215,7 @@ extern "C" void TELEMETRY_USART_IRQHandler(void) } // TODO we should have telemetry in an higher layer, functions above should move to a sport_driver.cpp -bool telemetryGetByte(uint8_t * byte) +bool sportGetByte(uint8_t * byte) { #if defined(PCBX12S) if (telemetryFifoMode & TELEMETRY_SERIAL_WITHOUT_DMA) diff --git a/radio/src/targets/simu/module_drivers.cpp b/radio/src/targets/simu/module_drivers.cpp index ec3bf5d96..d369d3324 100644 --- a/radio/src/targets/simu/module_drivers.cpp +++ b/radio/src/targets/simu/module_drivers.cpp @@ -63,11 +63,12 @@ void stop_trainer_module_sbus() {} void init_intmodule_heartbeat() {} void stop_intmodule_heartbeat() {} -static void init(const etx_serial_init*) {} -static void deinit() {} -static void sendByte(uint8_t) {} -static void sendBuffer(const uint8_t*, uint8_t) {} -static void waitForTxCompleted() {} +static void* init(const etx_serial_init*) { return nullptr; } +static void deinit(void*) {} +static void sendByte(void*, uint8_t) {} +static void sendBuffer(void*, const uint8_t*, uint8_t) {} +static void waitForTxCompleted(void*) {} +static int getByte(void*,uint8_t*) { return -1; } const etx_serial_driver_t IntmoduleSerialDriver = { .init = init, @@ -75,6 +76,7 @@ const etx_serial_driver_t IntmoduleSerialDriver = { .sendByte = sendByte, .sendBuffer = sendBuffer, .waitForTxCompleted = waitForTxCompleted, + .getByte = getByte, .setReceiveCb = nullptr, .setOnErrorCb = nullptr, }; @@ -85,6 +87,7 @@ const etx_serial_driver_t ExtmoduleSerialDriver = { .sendByte = sendByte, .sendBuffer = sendBuffer, .waitForTxCompleted = waitForTxCompleted, + .getByte = getByte, .setReceiveCb = nullptr, .setOnErrorCb = nullptr, }; diff --git a/radio/src/targets/simu/simpgmspace.cpp b/radio/src/targets/simu/simpgmspace.cpp index 4b2f60aae..d4a60c29c 100644 --- a/radio/src/targets/simu/simpgmspace.cpp +++ b/radio/src/targets/simu/simpgmspace.cpp @@ -429,7 +429,7 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode) { } -bool telemetryGetByte(uint8_t * byte) +bool sportGetByte(uint8_t * byte) { return false; } @@ -732,6 +732,7 @@ void disableSpeaker() } #endif +int trainerModuleSbusGetByte(unsigned char*) { return 0; } void rtcInit() { @@ -751,60 +752,7 @@ void usbSerialPutc(uint8_t c) } #endif -#if defined(AUX_SERIAL) -#if defined(AUX_SERIAL_DMA_Stream_RX) -AuxSerialRxFifo auxSerialRxFifo(nullptr); -#else -AuxSerialRxFifo auxSerialRxFifo; -#endif -uint8_t auxSerialMode; - -void auxSerialSetup(unsigned int baudrate, bool dma, uint8_t length, uint8_t parity, uint8_t stop) -{ -} - -void auxSerialInit(unsigned int mode, unsigned int protocol) -{ -} - -void auxSerialPutc(uint8_t c) -{ -} - -void auxSerialSbusInit() -{ -} - -void auxSerialStop() -{ -} -#endif - -#if defined(AUX2_SERIAL) -AuxSerialRxFifo aux2SerialRxFifo(nullptr); -uint8_t aux2SerialMode; - -void aux2SerialSetup(unsigned int baudrate, bool dma, uint8_t length, uint8_t parity, uint8_t stop) -{ -} - -void aux2SerialInit(unsigned int mode, unsigned int protocol) -{ -} - -void aux2SerialPutc(uint8_t c) -{ -} - -void aux2SerialSbusInit() -{ -} - -void aux2SerialStop() -{ -} -#endif - +const etx_serial_port_t* auxSerialGetPort(int port_nr) { return nullptr; } #if defined(HARDWARE_TOUCH) struct TouchState simTouchState = {}; diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index f4fca7089..564ba8a9b 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -31,7 +31,7 @@ if(PCB STREQUAL X9E) top_lcd_driver.cpp startup_stm32f40_41xxx.s ) - set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp) + set(AUX_SERIAL ON) if(STICKS STREQUAL HORUS) add_definitions(-DHORUS_STICKS) endif() @@ -90,7 +90,7 @@ elseif(PCB STREQUAL X9D+) set(CPU_TYPE_FULL STM32F205xE) # for size report add_definitions(-DSTM32F205xx) set(LINKER_SCRIPT targets/taranis/stm32f2_flash.ld) - set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp) + set(AUX_SERIAL ON) set(STATUS_LEDS NO) endif() elseif(PCB STREQUAL X9D) @@ -110,7 +110,7 @@ elseif(PCB STREQUAL X9D) set(BITMAPS_TARGET taranis_bitmaps) set(FONTS_TARGET taranis_fonts) set(LCD_DRIVER lcd_driver_aspi.cpp) - set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp) + set(AUX_SERIAL ON) set(GVAR_SCREEN model_gvars.cpp) set(STATUS_LEDS NO) add_definitions(-DMANUFACTURER_FRSKY) @@ -207,7 +207,7 @@ elseif(PCB STREQUAL X7) set(LUA_EXPORT lua_export_zorro) set(BLUETOOTH NO) set(USB_CHARGER YES) - set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp) + set(AUX_SERIAL ON) add_definitions(-DRADIO_ZORRO) add_definitions(-DEEPROM_VARIANT=0x4006) add_definitions(-DMANUFACTURER_RADIOMASTER) diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index 5d4ab4ecc..bcc4a1658 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -26,6 +26,10 @@ #include "../common/arm/stm32/timers_driver.h" +#if defined(AUX_SERIAL) +#include "aux_serial_driver.h" +#endif + #if defined(__cplusplus) extern "C" { #endif @@ -223,10 +227,7 @@ void boardInit() i2cInit(); usbInit(); -#if defined(DEBUG) && defined(AUX_SERIAL_GPIO) - auxSerialInit(0, 0); // default serial mode (None if DEBUG not defined) - TRACE("\nTaranis board started :)"); -#endif + initSerialPorts(); #if defined(HAPTIC) hapticInit(); @@ -415,3 +416,26 @@ void initJackDetect(void) GPIO_Init(JACK_DETECT_GPIO, &GPIO_InitStructure); } #endif + +#if defined(AUX_SERIAL) +const etx_serial_port_t auxSerialPort = { + &AuxSerialDriver, + nullptr +}; +#define AUX_SERIAL_PORT &auxSerialPort +#else +#define AUX_SERIAL_PORT nullptr +#endif + +#define AUX2_SERIAL_PORT nullptr + +static const etx_serial_port_t* serialPorts[MAX_AUX_SERIAL] = { + AUX_SERIAL_PORT, + AUX2_SERIAL_PORT, +}; + +const etx_serial_port_t* auxSerialGetPort(int port_nr) +{ + if (port_nr >= MAX_AUX_SERIAL) return nullptr; + return serialPorts[port_nr]; +} diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index a1d6d1f35..550bb9892 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -27,6 +27,7 @@ #include "opentx_constants.h" #include "board_common.h" #include "hal.h" +#include "hal/serial_port.h" #include "watchdog_driver.h" @@ -164,26 +165,20 @@ uint32_t isBootloaderStart(const uint8_t * buffer); #define init_trainer_capture() #define stop_trainer_capture() #endif + #if defined(TRAINER_MODULE_CPPM) void init_trainer_module_cppm(); void stop_trainer_module_cppm(); -#else - #define init_trainer_module_cppm() - #define stop_trainer_module_cppm() #endif + #if defined(TRAINER_MODULE_SBUS) void init_trainer_module_sbus(); void stop_trainer_module_sbus(); -#else - #define init_trainer_module_sbus() - #define stop_trainer_module_sbus() + int trainerModuleSbusGetByte(uint8_t* byte); #endif void check_telemetry_exti(); -// SBUS -int sbusGetByte(uint8_t * byte); - // Keys driver enum EnumKeys { @@ -775,7 +770,7 @@ void sportSendByte(uint8_t byte); void sportSendByteLoop(uint8_t byte); void sportStopSendByteLoop(); void sportSendBuffer(const uint8_t * buffer, uint32_t count); -bool telemetryGetByte(uint8_t * byte); +bool sportGetByte(uint8_t * byte); void telemetryClearFifo(); extern uint32_t telemetryErrors; @@ -860,15 +855,10 @@ void hapticOff(); void hapticOn(); #endif -// Aux serial port driver -#if defined(AUX_SERIAL_GPIO) #define DEBUG_BAUDRATE 115200 #define LUA_DEFAULT_BAUDRATE 115200 -#define AUX_SERIAL -#define auxSerialTelemetryInit(protocol) auxSerialInit(UART_MODE_TELEMETRY, protocol) -#define AUX_SERIAL_POWER_ON() -#define AUX_SERIAL_POWER_OFF() -#endif + +const etx_serial_port_t* auxSerialGetPort(int port_nr); // BT driver #define BLUETOOTH_BOOTLOADER_BAUDRATE 230400 diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 3a0e81a79..61b3daa1c 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -1929,14 +1929,14 @@ #define TRAINER_MODULE_CPPM_TIMER_IRQn TRAINER_TIMER_IRQn #define TRAINER_MODULE_CPPM_GPIO_AF GPIO_AF_TIM3 // Trainer SBUS input on heartbeat pin - #define TRAINER_MODULE_SBUS - #define TRAINER_MODULE_SBUS_GPIO_AF GPIO_AF_USART6 - #define TRAINER_MODULE_SBUS_USART USART6 - #define TRAINER_MODULE_SBUS_GPIO INTMODULE_HEARTBEAT_GPIO - #define TRAINER_MODULE_SBUS_GPIO_PIN INTMODULE_HEARTBEAT_GPIO_PIN - #define TRAINER_MODULE_SBUS_GPIO_PinSource INTMODULE_HEARTBEAT_EXTI_PinSource - #define TRAINER_MODULE_SBUS_DMA_STREAM DMA2_Stream1 - #define TRAINER_MODULE_SBUS_DMA_CHANNEL DMA_Channel_5 + // #define TRAINER_MODULE_SBUS + // #define TRAINER_MODULE_SBUS_GPIO_AF GPIO_AF_USART6 + // #define TRAINER_MODULE_SBUS_USART USART6 + // #define TRAINER_MODULE_SBUS_GPIO INTMODULE_HEARTBEAT_GPIO + // #define TRAINER_MODULE_SBUS_GPIO_PIN INTMODULE_HEARTBEAT_GPIO_PIN + // #define TRAINER_MODULE_SBUS_GPIO_PinSource INTMODULE_HEARTBEAT_EXTI_PinSource + // #define TRAINER_MODULE_SBUS_DMA_STREAM DMA2_Stream1 + // #define TRAINER_MODULE_SBUS_DMA_CHANNEL DMA_Channel_5 #else // TODO: replace SBUS trainer with S.PORT pin #define TRAINER_MODULE_RCC_AHB1Periph 0 diff --git a/radio/src/targets/taranis/telemetry_driver.cpp b/radio/src/targets/taranis/telemetry_driver.cpp index 8709dfbb6..f634c5b21 100644 --- a/radio/src/targets/taranis/telemetry_driver.cpp +++ b/radio/src/targets/taranis/telemetry_driver.cpp @@ -393,22 +393,12 @@ extern "C" void TELEMETRY_TIMER_IRQHandler() telemetryPortInvertedRxBit(); } -// TODO we should have telemetry in an higher layer, functions above should move to a sport_driver.cpp -bool telemetryGetByte(uint8_t * byte) +// TODO: we should have telemetry in an higher layer, +// functions above should move to a sport_driver.cpp +// +bool sportGetByte(uint8_t * byte) { -#if defined(AUX_SERIAL) - if (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY) { - if (auxSerialMode == UART_MODE_TELEMETRY) - return auxSerialRxFifo.pop(*byte); - else - return false; - } - else { - return telemetryFifo.pop(*byte); - } -#else return telemetryFifo.pop(*byte); -#endif } void telemetryClearFifo() diff --git a/radio/src/targets/taranis/trainer_driver.cpp b/radio/src/targets/taranis/trainer_driver.cpp index a78d9c906..919c38240 100644 --- a/radio/src/targets/taranis/trainer_driver.cpp +++ b/radio/src/targets/taranis/trainer_driver.cpp @@ -21,10 +21,6 @@ #include "opentx.h" -#if defined(TRAINER_MODULE_SBUS_USART) -DMAFifo<32> trainerSbusFifo __DMA (TRAINER_MODULE_SBUS_DMA_STREAM); -#endif - void trainerSendNextFrame(); #if defined(TRAINER_GPIO) @@ -267,7 +263,11 @@ void stop_trainer_module_cppm() } #endif +// TODO: use external module serial driver #if defined(TRAINER_MODULE_SBUS) + +static DMAFifo<32> trainerSbusFifo __DMA (TRAINER_MODULE_SBUS_DMA_STREAM); + void init_trainer_module_sbus() { EXTERNAL_MODULE_ON(); @@ -328,22 +328,9 @@ void stop_trainer_module_sbus() EXTERNAL_MODULE_OFF(); } } -#endif -#if defined(SBUS_TRAINER) -int sbusGetByte(uint8_t * byte) +int trainerModuleSbusGetByte(uint8_t* byte) { - switch (currentTrainerMode) { -#if defined(TRAINER_MODULE_SBUS_USART) - case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE: - return trainerSbusFifo.pop(*byte); -#endif -#if defined(AUX_SERIAL_USART) - case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: - return auxSerialRxFifo.pop(*byte); -#endif - default: - return false; - } + return trainerSbusFifo.pop(*byte); } #endif diff --git a/radio/src/telemetry/crossfire.cpp b/radio/src/telemetry/crossfire.cpp index 257a18faa..ef30d580f 100644 --- a/radio/src/telemetry/crossfire.cpp +++ b/radio/src/telemetry/crossfire.cpp @@ -293,17 +293,7 @@ void processCrossfireTelemetryData(uint8_t data, uint8_t module) uint8_t * rxBuffer = getTelemetryRxBuffer(module); uint8_t &rxBufferCount = getTelemetryRxBufferCount(module); -#if defined(AUX_SERIAL) - if (g_eeGeneral.auxSerialMode == UART_MODE_TELEMETRY_MIRROR) { - auxSerialPutc(data); - } -#endif - -#if defined(AUX2_SERIAL) - if (g_eeGeneral.aux2SerialMode == UART_MODE_TELEMETRY_MIRROR) { - aux2SerialPutc(data); - } -#endif + telemetryMirrorSend(data); if (rxBufferCount == 0 && data != RADIO_ADDRESS && data != UART_SYNC) { TRACE("[XF] address 0x%02X error", data); diff --git a/radio/src/telemetry/crossfire.h b/radio/src/telemetry/crossfire.h index 59d9524a5..044cd3415 100644 --- a/radio/src/telemetry/crossfire.h +++ b/radio/src/telemetry/crossfire.h @@ -116,6 +116,7 @@ const uint8_t CROSSFIRE_FRAME_PERIODS[] = { 4, 4, 4, + 4, }; #if SPORT_MAX_BAUDRATE < 400000 // index 0 (115200) is the default 0 value diff --git a/radio/src/telemetry/frsky.cpp b/radio/src/telemetry/frsky.cpp index 6f0b0e6b1..a2d1e798e 100644 --- a/radio/src/telemetry/frsky.cpp +++ b/radio/src/telemetry/frsky.cpp @@ -24,17 +24,7 @@ void processFrskyTelemetryData(uint8_t data) { - -#if defined(AUX_SERIAL) - if (g_eeGeneral.auxSerialMode == UART_MODE_TELEMETRY_MIRROR) { - auxSerialPutc(data); - } -#endif -#if defined(AUX2_SERIAL) - if (g_eeGeneral.aux2SerialMode == UART_MODE_TELEMETRY_MIRROR) { - aux2SerialPutc(data); - } -#endif + telemetryMirrorSend(data); if (pushFrskyTelemetryData(data)) { if (IS_FRSKY_SPORT_PROTOCOL()) { diff --git a/radio/src/telemetry/ghost.cpp b/radio/src/telemetry/ghost.cpp index 525ea3642..879eeaaf0 100755 --- a/radio/src/telemetry/ghost.cpp +++ b/radio/src/telemetry/ghost.cpp @@ -322,17 +322,7 @@ void processGhostTelemetryFrame() void processGhostTelemetryData(uint8_t data) { -#if defined(AUX_SERIAL) - if (g_eeGeneral.auxSerialMode == UART_MODE_TELEMETRY_MIRROR) { - auxSerialPutc(data); - } -#endif - -#if defined(AUX2_SERIAL) - if (g_eeGeneral.aux2SerialMode == UART_MODE_TELEMETRY_MIRROR) { - aux2SerialPutc(data); - } -#endif + telemetryMirrorSend(data); if (telemetryRxBufferCount == 0 && data != GHST_ADDR_RADIO) { TRACE("[GH] address 0x%02X error", data); diff --git a/radio/src/telemetry/multi.cpp b/radio/src/telemetry/multi.cpp index c43edfd5f..c4f3a1c6f 100644 --- a/radio/src/telemetry/multi.cpp +++ b/radio/src/telemetry/multi.cpp @@ -257,7 +257,7 @@ static void processMultiSyncPacket(const uint8_t * data, uint8_t module) status.update(refreshRate, inputLag); #if defined(DEBUG) - serialPrint("MP ADJ: R %d, L %04d", refreshRate, inputLag); + dbgSerialPrint("MP ADJ: R %d, L %04d", refreshRate, inputLag); #endif } @@ -351,18 +351,8 @@ static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module) uint8_t len = packet[1]; const uint8_t * data = packet + 2; -#if defined(AUX_SERIAL) - if (g_eeGeneral.auxSerialMode == UART_MODE_TELEMETRY_MIRROR) { - for (uint8_t c = 0; c < len + 2; c++) - auxSerialPutc(packet[c]); - } -#endif -#if defined(AUX2_SERIAL) - if (g_eeGeneral.aux2SerialMode == UART_MODE_TELEMETRY_MIRROR) { - for (uint8_t c = 0; c < len + 2; c++) - aux2SerialPutc(packet[c]); - } -#endif + for (uint8_t c = 0; c < len + 2; c++) + telemetryMirrorSend(packet[c]); // Switch type switch (type) { diff --git a/radio/src/telemetry/telemetry.cpp b/radio/src/telemetry/telemetry.cpp index bc65bc6a7..670d94c5d 100644 --- a/radio/src/telemetry/telemetry.cpp +++ b/radio/src/telemetry/telemetry.cpp @@ -42,8 +42,8 @@ TelemetryData telemetryData; uint8_t telemetryProtocol = 255; #if defined(INTERNAL_MODULE_SERIAL_TELEMETRY) -uint8_t intTelemetryRxBuffer[TELEMETRY_RX_PACKET_SIZE]; -uint8_t intTelemetryRxBufferCount; +static uint8_t intTelemetryRxBuffer[TELEMETRY_RX_PACKET_SIZE]; +static uint8_t intTelemetryRxBufferCount; #endif uint8_t * getTelemetryRxBuffer(uint8_t moduleIdx) @@ -64,6 +64,48 @@ uint8_t &getTelemetryRxBufferCount(uint8_t moduleIdx) return telemetryRxBufferCount; } +static int (*_telemetryGetByte)(void*, uint8_t*) = nullptr; +static void* _telemetryGetByteCtx = nullptr; + +void telemetrySetGetByte(void* ctx, int (*fct)(void*, uint8_t*)) +{ + _telemetryGetByte = nullptr; + _telemetryGetByteCtx = ctx; + _telemetryGetByte = fct; +} + +static bool telemetryGetByte(uint8_t* data) +{ + auto _getByte = _telemetryGetByte; + auto _ctx = _telemetryGetByteCtx; + + if (_getByte) { + return _getByte(_ctx, data); + } + + return sportGetByte(data); +} + +static void (*telemetryMirrorSendByte)(void*, uint8_t) = nullptr; +static void* telemetryMirrorSendByteCtx = nullptr; + +void telemetrySetMirrorCb(void* ctx, void (*fct)(void*, uint8_t)) +{ + telemetryMirrorSendByte = nullptr; + telemetryMirrorSendByteCtx = ctx; + telemetryMirrorSendByte = fct; +} + +void telemetryMirrorSend(uint8_t data) +{ + auto _sendByte = telemetryMirrorSendByte; + auto _ctx = telemetryMirrorSendByteCtx; + + if (_sendByte) { + _sendByte(_ctx, data); + } +} + void processTelemetryData(uint8_t data) { #if defined(CROSSFIRE) @@ -427,7 +469,8 @@ void telemetryInit(uint8_t protocol) #if defined(AUX_SERIAL) else if (protocol == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY) { telemetryPortInit(0, TELEMETRY_SERIAL_DEFAULT); - auxSerialTelemetryInit(PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY); + // Note: this is done in initSerialPorts() + //auxSerialTelemetryInit(PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY); } #endif diff --git a/radio/src/telemetry/telemetry.h b/radio/src/telemetry/telemetry.h index d5edb5386..a3c2c84f3 100644 --- a/radio/src/telemetry/telemetry.h +++ b/radio/src/telemetry/telemetry.h @@ -75,10 +75,17 @@ constexpr uint8_t TELEMETRY_TIMEOUT10ms = 100; // 1 second extern uint8_t telemetryRxBuffer[TELEMETRY_RX_PACKET_SIZE]; extern uint8_t telemetryRxBufferCount; -//TODO: use module scoped buffers instead uint8_t* getTelemetryRxBuffer(uint8_t moduleIdx); uint8_t& getTelemetryRxBufferCount(uint8_t moduleIdx); +// Set alternative telemetry input +void telemetrySetGetByte(void* ctx, int (*fct)(void*, uint8_t*)); + +// Set telemetry mirror callback +void telemetrySetMirrorCb(void* ctx, void (*fct)(void*, uint8_t)); + +// Mirror telemetry byte +void telemetryMirrorSend(uint8_t data); #define TELEMETRY_AVERAGE_COUNT 3 diff --git a/radio/src/trainer.cpp b/radio/src/trainer.cpp index 4840ebc9c..73cd2504d 100644 --- a/radio/src/trainer.cpp +++ b/radio/src/trainer.cpp @@ -69,20 +69,14 @@ void stopTrainer() #if defined(TRAINER_MODULE_SBUS) case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE: + sbusSetGetByte(nullptr); stop_trainer_module_sbus(); break; #endif #if defined(TRAINER_BATTERY_COMPARTMENT) case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: -#if defined(AUX_SERIAL) - if (g_eeGeneral.auxSerialMode == UART_MODE_SBUS_TRAINER) - auxSerialStop(); -#endif -#if defined(AUX2_SERIAL) - if (g_eeGeneral.aux2SerialMode == UART_MODE_SBUS_TRAINER) - aux2SerialStop(); -#endif + sbusSetGetByte(nullptr); break; #endif } @@ -115,26 +109,14 @@ void checkTrainerSettings() #if defined(TRAINER_MODULE_SBUS) case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE: init_trainer_module_sbus(); + sbusSetGetByte(trainerModuleSbusGetByte); break; #endif #if defined(TRAINER_BATTERY_COMPARTMENT) case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: -#if defined(AUX_SERIAL) - if (g_eeGeneral.auxSerialMode == UART_MODE_SBUS_TRAINER) { - auxSerialSbusInit(); - break; - } -#endif - -#if defined(AUX2_SERIAL) - if (g_eeGeneral.aux2SerialMode == UART_MODE_SBUS_TRAINER) { - aux2SerialSbusInit(); - break; - } -#endif - - // no break + sbusSetGetByte(sbusAuxGetByte); + break; #endif case TRAINER_MODE_MASTER_TRAINER_JACK: