diff --git a/Makefile b/Makefile index 1af62c2..ecaa259 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ ENABLE_AM_FIX := 1 ENABLE_AM_FIX_SHOW_DATA := 1 ENABLE_SQUELCH_MORE_SENSITIVE := 1 ENABLE_FASTER_CHANNEL_SCAN := 1 -ENABLE_RSSI_BAR := 0 +ENABLE_RSSI_BAR := 1 ENABLE_SHOW_TX_TIMEOUT := 0 ENABLE_AUDIO_BAR := 1 ENABLE_COPY_CHAN_TO_VFO := 1 diff --git a/app/aircopy.c b/app/aircopy.c index dd6301b..b67a02d 100644 --- a/app/aircopy.c +++ b/app/aircopy.c @@ -18,10 +18,14 @@ #include "app/aircopy.h" #include "audio.h" +#include "bsp/dp32g030/gpio.h" +#include "driver/backlight.h" #include "driver/bk4819.h" #include "driver/crc.h" #include "driver/eeprom.h" +#include "driver/gpio.h" #include "driver/system.h" +#include "driver/uart.h" #include "frequencies.h" #include "misc.h" #include "radio.h" @@ -30,274 +34,528 @@ #include "ui/inputbox.h" #include "ui/ui.h" -#define AIRCOPY_MAGIC_START 0xABCD -#define AIRCOPY_MAGIC_END 0xDCBA +// ********************** -#define AIRCOPY_LAST_EEPROM_ADDR 0x1E00 +#define AIRCOPY_MAGIC_START_REQ 0xBCDA // used to request a block resend +#define AIRCOPY_MAGIC_END_REQ 0xCDBA // used to request a block resend -const uint8_t g_aircopy_block_max = 120; -uint8_t g_aircopy_block_number; -uint8_t g_aircopy_rx_errors; -aircopy_state_t g_aircopy_state; +#define AIRCOPY_MAGIC_START 0xABCD // normal start value +#define AIRCOPY_MAGIC_END 0xDCBA // normal end value -uint8_t aircopy_send_count_down_10ms; +#define AIRCOPY_LAST_EEPROM_ADDR 0x1E00 // size of eeprom transferred -uint16_t g_fsk_buffer[36]; -unsigned int g_fsk_write_index; -uint16_t g_fsk_tx_timeout_10ms; +// FSK Data Length .. 0xABCD + 2 byte eeprom address + 64 byte payload + 2 byte CRC + 0xDCBA +#define AIRCOPY_DATA_PACKET_SIZE (2 + 2 + 64 + 2 + 2) -void AIRCOPY_start_FSK_tx(const uint8_t request_packet) +// FSK Data Length .. 0xBCDA + 2 byte eeprom address + 2 byte CRC + 0xCDBA +#define AIRCOPY_REQ_PACKET_SIZE (2 + 2 + 64 + 2 + 2) + +// ********************** + +const unsigned int g_aircopy_block_max = 120; +unsigned int g_aircopy_block_number; +uint8_t g_aircopy_rx_errors_fsk_crc; +uint8_t g_aircopy_rx_errors_magic; +uint8_t g_aircopy_rx_errors_crc; +aircopy_state_t g_aircopy_state; + +uint16_t g_fsk_buffer[AIRCOPY_DATA_PACKET_SIZE / 2]; +unsigned int g_fsk_write_index; +uint16_t g_fsk_tx_timeout_10ms; + +uint8_t aircopy_send_count_down_10ms; + +void AIRCOPY_init(void) { - unsigned int i; - const uint16_t eeprom_addr = (uint16_t)g_aircopy_block_number * 64; + // turn the backlight ON + GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); + + RADIO_SetupRegisters(true); + + BK4819_SetupAircopy(AIRCOPY_DATA_PACKET_SIZE); + + BK4819_reset_fsk(); + + g_aircopy_state = AIRCOPY_READY; + + g_fsk_write_index = 0; + BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); // LED off + BK4819_start_fsk_rx(AIRCOPY_DATA_PACKET_SIZE); + + GUI_SelectNextDisplay(DISPLAY_AIRCOPY); +} + +void AIRCOPY_start_fsk_tx(const int request_block_num) +{ + const unsigned int eeprom_addr = (request_block_num < 0) ? g_aircopy_block_number * 64 : (unsigned int)request_block_num * 64; + uint16_t fsk_reg59; + unsigned int k; + unsigned int tx_size = 0; - // will be used to ask the TX/ing radio to resend a missing/corrupted packet - (void)request_packet; - // ********* // packet start - g_fsk_buffer[0] = AIRCOPY_MAGIC_START; + g_fsk_buffer[tx_size++] = (request_block_num < 0) ? AIRCOPY_MAGIC_START : AIRCOPY_MAGIC_START_REQ; // eeprom address - g_fsk_buffer[1] = eeprom_addr; + g_fsk_buffer[tx_size++] = eeprom_addr; // data - EEPROM_ReadBuffer(eeprom_addr, &g_fsk_buffer[2], 64); + if (request_block_num < 0) + { + EEPROM_ReadBuffer(eeprom_addr, &g_fsk_buffer[tx_size], 64); + tx_size += 64 / 2; + } // data CRC - g_fsk_buffer[34] = CRC_Calculate(&g_fsk_buffer[1], 2 + 64); + g_fsk_buffer[tx_size++] = CRC_Calculate(&g_fsk_buffer[1], (request_block_num < 0) ? 2 + 64 : 2); // packet end - g_fsk_buffer[35] = AIRCOPY_MAGIC_END; + g_fsk_buffer[tx_size++] = (request_block_num < 0) ? AIRCOPY_MAGIC_END : AIRCOPY_MAGIC_END_REQ; // ********* - + { // scramble the packet - //for (i = 0; i < 34; i++) - //g_fsk_buffer[1 + i] ^= Obfuscation[i % ARRAY_SIZE(Obfuscation)]; - uint8_t *p = (uint8_t *)&g_fsk_buffer[1]; - for (i = 0; i < (34 * 2); i++) - *p++ ^= obfuscate_array[i % ARRAY_SIZE(obfuscate_array)]; + for (k = 0; k < ((tx_size - 2) * 2); k++) + *p++ ^= obfuscate_array[k % ARRAY_SIZE(obfuscate_array)]; } - - // TX the packet - RADIO_SetTxParameters(); - BK4819_SetupPowerAmplifier(0, g_current_vfo->p_tx->frequency); // VERY low TX power - // turn the RED LED on - BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, true); + g_fsk_tx_timeout_10ms = 1000 / 10; // 1 second timeout - // start sending the packet + // turn the TX on + RADIO_enableTX(true); - // let the TX stabilize - SYSTEM_DelayMs(10); - + // REG_59 + // + // <15> 0 TX FIFO + // 1 = clear + // + // <14> 0 RX FIFO + // 1 = clear + // + // <13> 0 FSK Scramble + // 1 = Enable + // + // <12> 0 FSK RX + // 1 = Enable + // + // <11> 0 FSK TX + // 1 = Enable + // + // <10> 0 FSK data when RX + // 1 = Invert + // + // <9> 0 FSK data when TX + // 1 = Invert + // + // <8> 0 ??? + // + // <7:4> 0 FSK preamble length selection + // 0 = 1 byte + // 1 = 2 bytes + // 2 = 3 bytes + // 15 = 16 bytes + // + // <3> 0 FSK sync length selection + // 0 = 2 bytes (FSK Sync Byte 0, 1) + // 1 = 4 bytes (FSK Sync Byte 0, 1, 2, 3) + // + // <2:0> 0 ??? + // + // 0x0068 0000 0000 0110 1000 + // + fsk_reg59 = (0u << 15) | // 0 or 1 1 = clear TX FIFO + (0u << 14) | // 0 or 1 1 = clear RX FIFO + (0u << 13) | // 0 or 1 1 = scramble + (0u << 12) | // 0 or 1 1 = enable RX + (0u << 11) | // 0 or 1 1 = enable TX + (0u << 10) | // 0 or 1 1 = invert data when RX + (0u << 9) | // 0 or 1 1 = invert data when TX + (0u << 8) | // 0 or 1 ??? + (6u << 4) | // 0 ~ 15 preamble Length Selection + (1u << 3) | // 0 or 1 sync length selection + (0u << 0); // 0 ~ 7 ??? + + // set the packet size + BK4819_WriteRegister(BK4819_REG_5D, (((tx_size * 2) - 1) << 8)); + + // clear TX fifo + BK4819_WriteRegister(BK4819_REG_59, (1u << 15) | fsk_reg59); + BK4819_WriteRegister(BK4819_REG_59, fsk_reg59); + + // load the packet + for (k = 0; k < tx_size; k++) + BK4819_WriteRegister(BK4819_REG_5F, g_fsk_buffer[k]); + + // enable tx interrupt(s) BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_TX_FINISHED); - BK4819_WriteRegister(BK4819_REG_59, 0x8068); - BK4819_WriteRegister(BK4819_REG_59, 0x0068); - - // load the packet - for (i = 0; i < 36; i++) - BK4819_WriteRegister(BK4819_REG_5F, g_fsk_buffer[i]); - -// SYSTEM_DelayMs(20); - - BK4819_WriteRegister(BK4819_REG_59, 0x2868); - - g_fsk_tx_timeout_10ms = 1000 / 10; // 1 second timeout + // enable scramble, enable TX + BK4819_WriteRegister(BK4819_REG_59, (1u << 13) | (1u << 11) | fsk_reg59); } -void AIRCOPY_stop_FSK_tx(void) -{ +void AIRCOPY_stop_fsk_tx(const bool inc_block) +{ if (g_aircopy_state != AIRCOPY_TX && g_fsk_tx_timeout_10ms == 0) return; - - g_fsk_tx_timeout_10ms = 0; - - BK4819_WriteRegister(BK4819_REG_02, 0); // disable all interrupts - -// SYSTEM_DelayMs(20); - BK4819_ResetFSK(); + g_fsk_tx_timeout_10ms = 0; // disable the TX - BK4819_SetupPowerAmplifier(0, 0); - BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, false); + BK4819_SetupPowerAmplifier(0, 0); // + BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, false); // ??? + BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, false); // LED off - // turn the RED LED off - BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, false); - - if (++g_aircopy_block_number >= g_aircopy_block_max) - { // transfer is complete - g_aircopy_state = AIRCOPY_TX_COMPLETE; + BK4819_reset_fsk(); + + if (inc_block) + { + if (++g_aircopy_block_number >= g_aircopy_block_max) + { // transfer is complete + g_aircopy_state = AIRCOPY_TX_COMPLETE; + } + else + { // TX pause/gap time till we start the next packet + aircopy_send_count_down_10ms = 220 / 10; // 220ms + } + + // RX mode + BK4819_start_fsk_rx(AIRCOPY_REQ_PACKET_SIZE); + + g_update_display = true; + GUI_DisplayScreen(); } else - { - // TX pause/gap time till we start the next packet - #if 0 - aircopy_send_count_down_10ms = 300 / 10; // 300ms - #else - aircopy_send_count_down_10ms = 10 / 10; // 10ms - #endif + { // RX mode + BK4819_start_fsk_rx(AIRCOPY_DATA_PACKET_SIZE); } - - g_update_display = true; - GUI_DisplayScreen(); } -void AIRCOPY_process_FSK_tx_10ms(void) +void AIRCOPY_process_fsk_tx_10ms(void) { - if (g_aircopy_state != AIRCOPY_TX) + uint16_t interrupt_bits = 0; + + if (g_aircopy_state != AIRCOPY_TX && g_aircopy_state != AIRCOPY_RX) return; if (g_fsk_tx_timeout_10ms == 0) { // not currently TX'ing - if (g_aircopy_block_number < g_aircopy_block_max) - { // not yet finished the complete transfer - if (aircopy_send_count_down_10ms > 0) - { // waiting till it's time to TX next packet - if (--aircopy_send_count_down_10ms == 0) - { // start next packet - AIRCOPY_start_FSK_tx(0xff); - g_update_display = true; - GUI_DisplayScreen(); - } - } + if (g_aircopy_state == AIRCOPY_TX && g_aircopy_block_number < g_aircopy_block_max) + { // not yet finished the complete transfer + + if (aircopy_send_count_down_10ms > 0) + if (--aircopy_send_count_down_10ms > 0) + return; // not yet time to TX next packet + + if (g_fsk_write_index > 0) + return; // currently RX'ing a packet + + // start next TX packet + AIRCOPY_start_fsk_tx(-1); + + g_update_display = true; + GUI_DisplayScreen(); } + return; } if (--g_fsk_tx_timeout_10ms > 0) { // still TX'ing if ((BK4819_ReadRegister(BK4819_REG_0C) & (1u << 0)) == 0) - return; /// TX not yet finished + return; + BK4819_WriteRegister(BK4819_REG_02, 0); + interrupt_bits = BK4819_ReadRegister(BK4819_REG_02); + if ((interrupt_bits & BK4819_REG_02_FSK_TX_FINISHED) == 0) + return; // TX not yet finished } - AIRCOPY_stop_FSK_tx(); + AIRCOPY_stop_fsk_tx(true); } -void AIRCOPY_process_FSK_rx_10ms(const uint16_t interrupt_status_bits) +void AIRCOPY_process_fsk_rx_10ms(void) { - unsigned int i; - uint16_t Status; + const unsigned int block_size = 64; + const unsigned int write_size = 8; + const unsigned int req_ack_size = 4; + uint16_t interrupt_bits; + uint16_t status; + uint16_t crc1; + uint16_t crc2; + uint16_t eeprom_addr; + uint16_t *data; + unsigned int block_num; + bool req_ack_packet = false; + unsigned int i; - if (g_aircopy_state != AIRCOPY_RX) + // REG_59 + // + // <15> 0 TX FIFO + // 1 = clear + // + // <14> 0 RX FIFO + // 1 = clear + // + // <13> 0 FSK Scramble + // 1 = Enable + // + // <12> 0 FSK RX + // 1 = Enable + // + // <11> 0 FSK TX + // 1 = Enable + // + // <10> 0 FSK data when RX + // 1 = Invert + // + // <9> 0 FSK data when TX + // 1 = Invert + // + // <8> 0 ??? + // + // <7:4> 0 FSK preamble length selection + // 0 = 1 byte + // 1 = 2 bytes + // 2 = 3 bytes + // 15 = 16 bytes + // + // <3> 0 FSK sync length selection + // 0 = 2 bytes (FSK Sync Byte 0, 1) + // 1 = 4 bytes (FSK Sync Byte 0, 1, 2, 3) + // + // <2:0> 0 ??? + // + status = BK4819_ReadRegister(BK4819_REG_59); + + if (status & (1u << 11) || g_fsk_tx_timeout_10ms > 0) + return; // FSK TX is busy + + if ((status & (1u << 12)) == 0) + { // FSK RX is disabled, enable it + g_fsk_write_index = 0; + BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); // LED off + BK4819_start_fsk_rx((g_aircopy_state == AIRCOPY_TX) ? AIRCOPY_REQ_PACKET_SIZE : AIRCOPY_DATA_PACKET_SIZE); + } + + status = BK4819_ReadRegister(BK4819_REG_0C); + if ((status & (1u << 0)) == 0) + return; // no flagged interrupts + + // read the interrupt flags + BK4819_WriteRegister(BK4819_REG_02, 0); // clear them + interrupt_bits = BK4819_ReadRegister(BK4819_REG_02); + + if (interrupt_bits & BK4819_REG_02_FSK_RX_SYNC) + BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, true); // LED on + + if (interrupt_bits & BK4819_REG_02_FSK_RX_FINISHED) + BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); // LED off + + if ((interrupt_bits & BK4819_REG_02_FSK_FIFO_ALMOST_FULL) == 0) return; - if (interrupt_status_bits & BK4819_REG_02_FSK_RX_SYNC) - { - // turn the green LED on -// BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, true); - } + BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, true); // LED on - if (interrupt_status_bits & BK4819_REG_02_FSK_RX_FINISHED) + // fetch RX'ed data + for (i = 0; i < 4; i++) { - // turn the green LED off -// BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); + const uint16_t word = BK4819_ReadRegister(BK4819_REG_5F); + if (g_fsk_write_index < ARRAY_SIZE(g_fsk_buffer)) + g_fsk_buffer[g_fsk_write_index++] = word; } - if (interrupt_status_bits & BK4819_REG_02_FSK_FIFO_ALMOST_FULL) + // REG_0B read only + // + // <15:12> ??? + // + // <11:8> DTMF/5-tone code received + // + // <7> FSK RX sync negative has been found + // + // <6> FSK RX sync positive has been found + // + // <5> ??? + // + // <4> FSK RX CRC indicator + // 1 = CRC pass + // 0 = CRC fail + // + // <3:0> ??? + // + status = BK4819_ReadRegister(BK4819_REG_0B); + + // check to see if it's a REQ/ACK packet + if (g_fsk_write_index == req_ack_size) + req_ack_packet = (g_fsk_buffer[0] == AIRCOPY_MAGIC_START_REQ && g_fsk_buffer[g_fsk_write_index - 1] == AIRCOPY_MAGIC_END_REQ); + + #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) +// UART_printf("aircopy rx %04X %u\r\n", interrupt_bits, g_fsk_write_index); + #endif + + if (g_fsk_write_index < ARRAY_SIZE(g_fsk_buffer) && !req_ack_packet) + return; // not yet a complete packet + + // restart the RX + BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); // LED off + BK4819_start_fsk_rx((g_aircopy_state == AIRCOPY_TX) ? AIRCOPY_REQ_PACKET_SIZE : AIRCOPY_DATA_PACKET_SIZE); + + g_update_display = true; + + // doc says bit 4 should be 1 = CRC OK, 0 = CRC FAIL, but original firmware checks for FAIL + if ((status & (1u << 4)) != 0) { - for (i = 0; i < 4; i++) - g_fsk_buffer[g_fsk_write_index++] = BK4819_ReadRegister(BK4819_REG_5F); + g_aircopy_rx_errors_fsk_crc++; + #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) + UART_printf("aircopy status %04X\r\n", status); + #endif + g_fsk_write_index = 0; + return; + } - if (g_fsk_write_index < ARRAY_SIZE(g_fsk_buffer)) - { - // turn the green LED on - BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, true); - return; + { // unscramble the packet + uint8_t *p = (uint8_t *)&g_fsk_buffer[1]; + for (i = 0; i < ((g_fsk_write_index - 2) * 2); i++) + *p++ ^= obfuscate_array[i % ARRAY_SIZE(obfuscate_array)]; + } + + // compute the CRC + crc1 = CRC_Calculate(&g_fsk_buffer[1], (g_fsk_write_index - 3) * 2); + // fetch the CRC + crc2 = g_fsk_buffer[g_fsk_write_index - 2]; + + #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) + // show the entire packet + UART_SendText("aircopy"); + for (i = 0; i < g_fsk_write_index; i++) + UART_printf(" %04X", g_fsk_buffer[i]); + UART_printf(" - %04X\r\n", status); + #endif + + // check the CRC + if (crc2 != crc1) + { // invalid CRC + g_aircopy_rx_errors_crc++; + #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) + UART_printf("aircopy invalid CRC %04X %04X\r\n", crc2, crc1); + #endif + g_fsk_write_index = 0; + return; + } + + eeprom_addr = g_fsk_buffer[1]; + data = &g_fsk_buffer[2]; + + block_num = eeprom_addr / block_size; + + if (req_ack_packet) + { // it's a req/ack packet + + #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) + UART_printf("aircopy RX req %04X %04X\r\n", block_num * 64, g_aircopy_block_number * 64); + #endif + + if (g_aircopy_state == AIRCOPY_TX) + { // send them the block they want + g_aircopy_block_number = block_num; // go to the block number they want + aircopy_send_count_down_10ms = 0; // TX asap } + + g_fsk_write_index = 0; + return; + } - // turn the green LED off - BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); + if (g_aircopy_state != AIRCOPY_RX) + { // not in RX mode .. ignore it + g_fsk_write_index = 0; + return; + } + + if (g_fsk_buffer[0] != AIRCOPY_MAGIC_START || g_fsk_buffer[g_fsk_write_index - 1] != AIRCOPY_MAGIC_END) + { // invalid magics .. ignore it + g_aircopy_rx_errors_magic++; + g_fsk_write_index = 0; + return; + } + + if (eeprom_addr != (block_num * block_size)) + { // eeprom address not block aligned .. ignore it + g_fsk_write_index = 0; + return; + } + + if (block_num != g_aircopy_block_number) + { // not the block number we're expecting .. request the correct block g_fsk_write_index = 0; - g_update_display = true; - - Status = BK4819_ReadRegister(BK4819_REG_0B); - - BK4819_PrepareFSKReceive(); - - // Doc says bit 4 should be 1 = CRC OK, 0 = CRC FAIL, but original firmware checks for FAIL - - if ((Status & (1u << 4)) == 0 && - g_fsk_buffer[0] == AIRCOPY_MAGIC_START && - g_fsk_buffer[35] == AIRCOPY_MAGIC_END) + + #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) + UART_printf("aircopy TX req %04X %04X\r\n", g_aircopy_block_number * 64, block_num * 64); + #endif + + // this packet takes 150ms start to finish + AIRCOPY_start_fsk_tx(g_aircopy_block_number); + g_fsk_tx_timeout_10ms = 200 / 5; // allow up to 200ms for the TX to complete + while (g_fsk_tx_timeout_10ms-- > 0) { - unsigned int i; - uint16_t CRC; - - { // unscramble the packet - uint8_t *p = (uint8_t *)&g_fsk_buffer[1]; - for (i = 0; i < (34 * 2); i++) - *p++ ^= obfuscate_array[i % ARRAY_SIZE(obfuscate_array)]; - } - - CRC = CRC_Calculate(&g_fsk_buffer[1], 2 + 64); - - if (g_fsk_buffer[34] == CRC) - { // CRC is valid - uint16_t eeprom_addr = g_fsk_buffer[1]; - - if (eeprom_addr == 0) - { // start again - g_aircopy_block_number = 0; - g_aircopy_rx_errors = 0; - } - - if ((eeprom_addr + 64) <= AIRCOPY_LAST_EEPROM_ADDR) - { // eeprom block is valid .. write it directly to eeprom - - uint16_t *pData = &g_fsk_buffer[2]; - for (i = 0; i < 8; i++) - { - if (eeprom_addr == 0x0E98) - { // power-on password .. wipe it - #ifndef ENABLE_PWRON_PASSWORD - pData[0] = 0xffff; - pData[1] = 0xffff; - #endif - } - else - if (eeprom_addr == 0x0F30) - { // AES key .. wipe it - #ifdef ENABLE_RESET_AES_KEY - pData[0] = 0xffff; - pData[1] = 0xffff; - pData[2] = 0xffff; - pData[3] = 0xffff; - #endif - } - - EEPROM_WriteBuffer(eeprom_addr, pData); // 8 bytes at a time - pData += 4; - eeprom_addr += 8; - } - - g_aircopy_block_number = eeprom_addr / 64; - - if (eeprom_addr >= AIRCOPY_LAST_EEPROM_ADDR) - { // reached end of eeprom config area - g_aircopy_state = AIRCOPY_RX_COMPLETE; - - // turn the green LED off - BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); - - g_update_display = true; - } - - memset(g_fsk_buffer, 0, sizeof(g_fsk_buffer)); - return; - } + SYSTEM_DelayMs(5); + if (BK4819_ReadRegister(BK4819_REG_0C) & (1u << 0)) + { // we have interrupt flags + BK4819_WriteRegister(BK4819_REG_02, 0); + const uint16_t interrupt_bits = BK4819_ReadRegister(BK4819_REG_02); + if (interrupt_bits & BK4819_REG_02_FSK_TX_FINISHED) + g_fsk_tx_timeout_10ms = 0; // TX is complete } } - - g_aircopy_rx_errors++; + AIRCOPY_stop_fsk_tx(false); + + return; } + + if ((eeprom_addr + block_size) > AIRCOPY_LAST_EEPROM_ADDR) + { + g_fsk_write_index = 0; + return; + } + + // clear the error counts + g_aircopy_rx_errors_fsk_crc = 0; + g_aircopy_rx_errors_magic = 0; + g_aircopy_rx_errors_crc = 0; + + // eeprom block appears valid .. write it directly to eeprom + + for (i = 0; i < (block_size / write_size); i++) + { + if (eeprom_addr == 0x0E98) + { // power-on password .. wipe it + //#ifndef ENABLE_PWRON_PASSWORD + data[0] = 0xffff; + data[1] = 0xffff; + //#endif + } + else + if (eeprom_addr == 0x0F30) + { // AES key .. wipe it + //#ifdef ENABLE_RESET_AES_KEY + data[0] = 0xffff; + data[1] = 0xffff; + data[2] = 0xffff; + data[3] = 0xffff; + //#endif + } + + EEPROM_WriteBuffer(eeprom_addr, data); // 8 bytes at a time + data += write_size / sizeof(data[0]); + eeprom_addr += write_size; + } + + g_aircopy_block_number = block_num + 1; + g_fsk_write_index = 0; + + if (eeprom_addr >= AIRCOPY_LAST_EEPROM_ADDR) + g_aircopy_state = AIRCOPY_RX_COMPLETE; // reached end of eeprom config area } static void AIRCOPY_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held) @@ -307,8 +565,8 @@ static void AIRCOPY_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held) if (g_aircopy_state != AIRCOPY_READY) { - AIRCOPY_stop_FSK_tx(); - + AIRCOPY_stop_fsk_tx(false); + g_aircopy_state = AIRCOPY_READY; g_update_display = true; GUI_DisplayScreen(); @@ -320,9 +578,9 @@ static void AIRCOPY_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held) unsigned int i; INPUTBOX_Append(Key); - + g_request_display_screen = DISPLAY_AIRCOPY; - + if (g_input_box_index < 6) { #ifdef ENABLE_VOICE @@ -330,11 +588,11 @@ static void AIRCOPY_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held) #endif return; } - + g_input_box_index = 0; - + NUMBER_Get(g_input_box, &Frequency); - + for (i = 0; i < ARRAY_SIZE(FREQ_BAND_TABLE); i++) { if (Frequency >= FREQ_BAND_TABLE[i].lower && Frequency < FREQ_BAND_TABLE[i].upper) @@ -342,31 +600,28 @@ static void AIRCOPY_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held) #ifdef ENABLE_VOICE g_another_voice_id = (voice_id_t)Key; #endif - + g_rx_vfo->band = i; - + // round the frequency to nearest step size Frequency = ((Frequency + (g_rx_vfo->step_freq / 2)) / g_rx_vfo->step_freq) * g_rx_vfo->step_freq; - + g_aircopy_freq = Frequency; #ifdef ENABLE_AIRCOPY_FREQ SETTINGS_SaveSettings(); // remeber the frequency for the next time #endif - + g_rx_vfo->freq_config_rx.frequency = Frequency; g_rx_vfo->freq_config_tx.frequency = Frequency; RADIO_ConfigureSquelchAndOutputPower(g_rx_vfo); - + g_current_vfo = g_rx_vfo; - - RADIO_SetupRegisters(true); - BK4819_SetupAircopy(); - BK4819_ResetFSK(); - + + AIRCOPY_init(); return; } } - + g_request_display_screen = DISPLAY_AIRCOPY; } } @@ -383,7 +638,8 @@ static void AIRCOPY_Key_EXIT(bool key_pressed, bool key_held) // turn the green LED off BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); - AIRCOPY_stop_FSK_tx(); + AIRCOPY_stop_fsk_tx(false); + g_input_box_index = 0; g_aircopy_state = AIRCOPY_READY; g_update_display = true; @@ -418,12 +674,13 @@ static void AIRCOPY_Key_EXIT(bool key_pressed, bool key_held) g_update_display = true; GUI_DisplayScreen(); - g_fsk_write_index = 0; - g_aircopy_block_number = 0; - g_aircopy_rx_errors = 0; - memset(g_fsk_buffer, 0, sizeof(g_fsk_buffer)); - - BK4819_PrepareFSKReceive(); + g_fsk_write_index = 0; + g_aircopy_block_number = 0; + g_aircopy_rx_errors_fsk_crc = 0; + g_aircopy_rx_errors_magic = 0; + g_aircopy_rx_errors_crc = 0; + + BK4819_start_fsk_rx(AIRCOPY_DATA_PACKET_SIZE); } } @@ -439,19 +696,21 @@ static void AIRCOPY_Key_MENU(bool key_pressed, bool key_held) // enter TX mode g_input_box_index = 0; - + g_aircopy_state = AIRCOPY_TX; g_update_display = true; GUI_DisplayScreen(); g_input_box_index = 0; - g_fsk_write_index = 0; - g_aircopy_block_number = 0; - g_aircopy_rx_errors = 0; + g_fsk_write_index = 0; + g_aircopy_block_number = 0; + g_aircopy_rx_errors_fsk_crc = 0; + g_aircopy_rx_errors_magic = 0; + g_aircopy_rx_errors_crc = 0; g_fsk_tx_timeout_10ms = 0; - aircopy_send_count_down_10ms = 30 / 10; // 30ms + aircopy_send_count_down_10ms = 0; } } diff --git a/app/aircopy.h b/app/aircopy.h index 3b3ad1e..26e1d70 100644 --- a/app/aircopy.h +++ b/app/aircopy.h @@ -29,17 +29,19 @@ enum aircopy_state_e }; typedef enum aircopy_state_e aircopy_state_t; -extern const uint8_t g_aircopy_block_max; -extern uint8_t g_aircopy_block_number; -extern uint8_t g_aircopy_rx_errors; -extern aircopy_state_t g_aircopy_state; -extern uint16_t g_fsk_buffer[36]; -extern unsigned int g_fsk_write_index; -extern uint16_t g_fsk_tx_timeout_10ms; +extern const unsigned int g_aircopy_block_max; +extern unsigned int g_aircopy_block_number; +extern uint8_t g_aircopy_rx_errors_fsk_crc; +extern uint8_t g_aircopy_rx_errors_magic; +extern uint8_t g_aircopy_rx_errors_crc; +extern aircopy_state_t g_aircopy_state; +extern uint16_t g_fsk_buffer[36]; +extern unsigned int g_fsk_write_index; +extern uint16_t g_fsk_tx_timeout_10ms; -void AIRCOPY_process_FSK_tx_10ms(void); -void AIRCOPY_process_FSK_rx_10ms(const uint16_t interrupt_status_bits); -void AIRCOPY_stop_FSK_tx(void); +void AIRCOPY_init(void); +void AIRCOPY_process_fsk_tx_10ms(void); +void AIRCOPY_process_fsk_rx_10ms(void); void AIRCOPY_ProcessKey(key_code_t key, bool key_pressed, bool key_held); #endif diff --git a/app/app.c b/app/app.c index fe7da2d..88df3d3 100644 --- a/app/app.c +++ b/app/app.c @@ -848,26 +848,13 @@ void APP_CheckRadioInterrupts(void) if (g_screen_to_display == DISPLAY_SEARCH) return; - while (BK4819_ReadRegister(BK4819_REG_0C) & 1u) + while (BK4819_ReadRegister(BK4819_REG_0C) & (1u << 0)) { // BK chip interrupt request - uint16_t interrupt_status_bits; - - // reset the interrupt ? BK4819_WriteRegister(BK4819_REG_02, 0); + const uint16_t interrupt_bits = BK4819_ReadRegister(BK4819_REG_02); - // fetch the interrupt status bits - interrupt_status_bits = BK4819_ReadRegister(BK4819_REG_02); - - // 0 = no phase shift - // 1 = 120deg phase shift - // 2 = 180deg phase shift - // 3 = 240deg phase shift -// const uint8_t ctcss_shift = BK4819_GetCTCShift(); -// if (ctcss_shift > 0) -// g_ctcss_lost = true; - - if (interrupt_status_bits & BK4819_REG_02_DTMF_5TONE_FOUND) + if (interrupt_bits & BK4819_REG_02_DTMF_5TONE_FOUND) { // save the RX'ed DTMF character const char c = DTMF_GetCharacter(BK4819_GetDTMF_5TONE_Code()); if (c != 0xff) @@ -906,26 +893,26 @@ void APP_CheckRadioInterrupts(void) } } - if (interrupt_status_bits & BK4819_REG_02_CxCSS_TAIL) + if (interrupt_bits & BK4819_REG_02_CxCSS_TAIL) g_cxcss_tail_found = true; - if (interrupt_status_bits & BK4819_REG_02_CDCSS_LOST) + if (interrupt_bits & BK4819_REG_02_CDCSS_LOST) { g_cdcss_lost = true; g_cdcss_code_type = BK4819_get_CDCSS_code_type(); } - if (interrupt_status_bits & BK4819_REG_02_CDCSS_FOUND) + if (interrupt_bits & BK4819_REG_02_CDCSS_FOUND) g_cdcss_lost = false; - if (interrupt_status_bits & BK4819_REG_02_CTCSS_LOST) + if (interrupt_bits & BK4819_REG_02_CTCSS_LOST) g_ctcss_lost = true; - if (interrupt_status_bits & BK4819_REG_02_CTCSS_FOUND) + if (interrupt_bits & BK4819_REG_02_CTCSS_FOUND) g_ctcss_lost = false; #ifdef ENABLE_VOX - if (interrupt_status_bits & BK4819_REG_02_VOX_LOST) + if (interrupt_bits & BK4819_REG_02_VOX_LOST) { g_vox_lost = true; g_vox_pause_count_down = 10; @@ -951,34 +938,24 @@ void APP_CheckRadioInterrupts(void) } } - if (interrupt_status_bits & BK4819_REG_02_VOX_FOUND) + if (interrupt_bits & BK4819_REG_02_VOX_FOUND) { g_vox_lost = false; g_vox_pause_count_down = 0; } #endif - if (interrupt_status_bits & BK4819_REG_02_SQUELCH_LOST) + if (interrupt_bits & BK4819_REG_02_SQUELCH_LOST) { g_squelch_lost = true; - // turn the LED off - BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, true); + BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, true); // LED on } - if (interrupt_status_bits & BK4819_REG_02_SQUELCH_FOUND) + if (interrupt_bits & BK4819_REG_02_SQUELCH_FOUND) { g_squelch_lost = false; - // turn the LED on - BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); + BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); // LED off } - - #ifdef ENABLE_AIRCOPY - if (g_screen_to_display == DISPLAY_AIRCOPY) - { - AIRCOPY_process_FSK_rx_10ms(interrupt_status_bits); -// AIRCOPY_process_FSK_tx_10ms(interrupt_status_bits); - } - #endif } } @@ -1625,19 +1602,13 @@ void APP_TimeSlice10ms(void) #ifdef ENABLE_AIRCOPY if (g_screen_to_display == DISPLAY_AIRCOPY) - { - APP_CheckRadioInterrupts(); - - if (g_aircopy_state == AIRCOPY_RX) - { // we're RX'ing - //AIRCOPY_process_FSK_rx_10ms(0); - } - else + { // we're in AIRCOPY mode + if (g_aircopy_state == AIRCOPY_TX) - { // we're TX'ing - AIRCOPY_process_FSK_tx_10ms(); - } + AIRCOPY_process_fsk_tx_10ms(); + AIRCOPY_process_fsk_rx_10ms(); + APP_CheckKeys(); if (g_update_display) @@ -1720,9 +1691,9 @@ void APP_TimeSlice10ms(void) RADIO_EnableCxCSS(); BK4819_SetupPowerAmplifier(0, 0); - BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, false); + BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, false); // ??? BK4819_Enable_AfDac_DiscMode_TxDsp(); - BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, false); + BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, false); // LED off GUI_DisplayScreen(); } @@ -1732,13 +1703,12 @@ void APP_TimeSlice10ms(void) GUI_DisplayScreen(); - BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, true); - RADIO_SetTxParameters(); + RADIO_enableTX(false); BK4819_TransmitTone(true, 500); SYSTEM_DelayMs(2); GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); - g_enable_speaker = true; + g_enable_speaker = true; g_alarm_tone_counter = 0; } } @@ -2087,12 +2057,17 @@ void APP_TimeSlice500ms(void) } #endif - if (g_backlight_count_down > 0 && !g_ask_to_save && g_css_scan_mode == CSS_SCAN_MODE_OFF) + if (g_backlight_count_down > 0 && + !g_ask_to_save && + g_css_scan_mode == CSS_SCAN_MODE_OFF && + g_screen_to_display != DISPLAY_AIRCOPY) + { if (g_screen_to_display != DISPLAY_MENU || g_menu_cursor != MENU_ABR) // don't turn off backlight if user is in backlight menu option if (--g_backlight_count_down == 0) if (g_eeprom.backlight < (ARRAY_SIZE(g_sub_menu_backlight) - 1)) GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn backlight off - + } + if (g_reduced_service) { BOARD_ADC_GetBatteryInfo(&g_usb_current_voltage, &g_usb_current); diff --git a/driver/bk4819.c b/driver/bk4819.c index 277ce9e..40e7f93 100644 --- a/driver/bk4819.c +++ b/driver/bk4819.c @@ -27,8 +27,6 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif -static const uint16_t FSK_RogerTable[7] = {0xF1A2, 0x7446, 0x61A4, 0x6544, 0x4E8A, 0xE044, 0xEA84}; - static uint16_t gBK4819_GpioOutState; bool g_rx_idle_mode; @@ -700,8 +698,8 @@ void BK4819_SetupPowerAmplifier(const uint8_t bias, const uint32_t frequency) // 7 = max // 0 = min // - // 280MHz gain 1 = 1 gain 2 = 0 gain 1 = 4 gain 2 = 2 - const uint8_t gain = (frequency < 28000000) ? (1u << 3) | (0u << 0) : (4u << 3) | (2u << 0); + // 280MHz gain 1 = 1 gain 2 = 0 gain 1 = 4 gain 2 = 2 + const uint8_t gain = (frequency == 0) ? 0 : (frequency < 28000000) ? (1u << 3) | (0u << 0) : (4u << 3) | (2u << 0); const uint8_t enable = 1; BK4819_WriteRegister(BK4819_REG_36, ((uint16_t)bias << 8) | ((uint16_t)enable << 7) | ((uint16_t)gain << 0)); } @@ -1040,7 +1038,7 @@ void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay, // BK4819_SetAF(g_rx_vfo->am_mode ? BK4819_AF_AM : BK4819_AF_FM); } - BK4819_WriteRegister(BK4819_REG_70, 0x0000); + BK4819_WriteRegister(BK4819_REG_70, 0); BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); BK4819_ExitTxMute(); } @@ -1078,39 +1076,9 @@ void BK4819_TurnsOffTones_TurnsOnRX(void) BK4819_REG_30_ENABLE_RX_DSP); } -#ifdef ENABLE_AIRCOPY - void BK4819_SetupAircopy(void) - { - BK4819_WriteRegister(BK4819_REG_70, 0x00E0); // Enable Tone2, tuning gain 48 - BK4819_WriteRegister(BK4819_REG_72, 0x3065); // Tone2 baudrate 1200 - - BK4819_WriteRegister(BK4819_REG_58, 0x00C1); // FSK Enable - // FSK 1.2K RX Bandwidth - // Preamble 0xAA or 0x55 - // RX Gain 0 - // RX Mode - // (FSK1.2K, FSK2.4K Rx and NOAA SAME Rx) - // TX Mode FSK 1.2K - // FSK 2.4K Tx - - BK4819_WriteRegister(BK4819_REG_5C, 0x5665); // Enable CRC among other things we don't know yet - BK4819_WriteRegister(BK4819_REG_5D, 0x4700); // FSK Data Length 72 Bytes (0xABCD + 2 byte length + 64 byte payload + 2 byte CRC + 0xDCBA) - } -#endif - -void BK4819_ResetFSK(void) -{ - BK4819_WriteRegister(BK4819_REG_3F, 0x0000); // Disable interrupts - BK4819_WriteRegister(BK4819_REG_59, 0x0068); // Sync length 4 bytes, 7 byte preamble - - SYSTEM_DelayMs(30); - - BK4819_Idle(); -} - void BK4819_Idle(void) { - BK4819_WriteRegister(BK4819_REG_30, 0x0000); + BK4819_WriteRegister(BK4819_REG_30, 0); } void BK4819_ExitBypass(void) @@ -1235,7 +1203,7 @@ void BK4819_ExitDTMF_TX(bool bKeep) { BK4819_EnterTxMute(); BK4819_SetAF(BK4819_AF_MUTE); - BK4819_WriteRegister(BK4819_REG_70, 0x0000); + BK4819_WriteRegister(BK4819_REG_70, 0); BK4819_DisableDTMF(); BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); if (!bKeep) @@ -1262,30 +1230,30 @@ void BK4819_PlayDTMF(char Code) uint16_t tone1 = 0; uint16_t tone2 = 0; - switch (Code) // Hz Hz - { // - case '0': tone1 = 9715; tone2 = 13793; break; // 941 1336 - case '1': tone1 = 7196; tone2 = 12482; break; // 679 1209 - case '2': tone1 = 7196; tone2 = 13793; break; // 697 1336 - case '3': tone1 = 7196; tone2 = 15249; break; // 679 1477 - case '4': tone1 = 7950; tone2 = 12482; break; // 770 1209 - case '5': tone1 = 7950; tone2 = 13793; break; // 770 1336 - case '6': tone1 = 7950; tone2 = 15249; break; // 770 1477 - case '7': tone1 = 8796; tone2 = 12482; break; // 852 1209 - case '8': tone1 = 8796; tone2 = 13793; break; // 852 1336 - case '9': tone1 = 8796; tone2 = 15249; break; // 852 1477 - case 'A': tone1 = 7196; tone2 = 16860; break; // 679 1633 - case 'B': tone1 = 7950; tone2 = 16860; break; // 770 1633 - case 'C': tone1 = 8796; tone2 = 16860; break; // 852 1633 - case 'D': tone1 = 9715; tone2 = 16860; break; // 941 1633 - case '*': tone1 = 9715; tone2 = 12482; break; // 941 1209 - case '#': tone1 = 9715; tone2 = 15249; break; // 941 1477 + switch (Code) + { + case '0': tone1 = 941; tone2 = 1336; break; + case '1': tone1 = 679; tone2 = 1209; break; + case '2': tone1 = 697; tone2 = 1336; break; + case '3': tone1 = 679; tone2 = 1477; break; + case '4': tone1 = 770; tone2 = 1209; break; + case '5': tone1 = 770; tone2 = 1336; break; + case '6': tone1 = 770; tone2 = 1477; break; + case '7': tone1 = 852; tone2 = 1209; break; + case '8': tone1 = 852; tone2 = 1336; break; + case '9': tone1 = 852; tone2 = 1477; break; + case 'A': tone1 = 679; tone2 = 1633; break; + case 'B': tone1 = 770; tone2 = 1633; break; + case 'C': tone1 = 852; tone2 = 1633; break; + case 'D': tone1 = 941; tone2 = 1633; break; + case '*': tone1 = 941; tone2 = 1209; break; + case '#': tone1 = 941; tone2 = 1477; break; } if (tone1 > 0) - BK4819_WriteRegister(BK4819_REG_71, tone1); + BK4819_WriteRegister(BK4819_REG_71, (((uint32_t)tone1 * 103244) + 5000) / 10000); // with rounding if (tone2 > 0) - BK4819_WriteRegister(BK4819_REG_72, tone2); + BK4819_WriteRegister(BK4819_REG_72, (((uint32_t)tone2 * 103244) + 5000) / 10000); // with rounding } void BK4819_PlayDTMFString(const char *pString, bool bDelayFirst, uint16_t FirstCodePersistTime, uint16_t HashCodePersistTime, uint16_t CodePersistTime, uint16_t CodeInternalTime) @@ -1697,60 +1665,210 @@ uint8_t BK4819_GetCTCType(void) { return (BK4819_ReadRegister(BK4819_REG_0C) >> 10) & 3u; } -/* -void BK4819_SendFSKData(uint16_t *pData) + +#ifdef ENABLE_AIRCOPY + void BK4819_SetupAircopy(const unsigned int packet_size) + { + if (packet_size == 0) + return; + + // REG_70 + // + // <15> 0 TONE-1 + // 1 = enable + // 0 = disable + // + // <14:8> 0 TONE-1 gain + // + // <7> 0 TONE-2 + // 1 = enable + // 0 = disable + // + // <6:0> 0 TONE-2 / FSK gain + // 0 ~ 127 + // + // enable tone-2, set gain + // + BK4819_WriteRegister(BK4819_REG_70, // 0 0000000 1 1100000 + ( 0u << 15) | + ( 0u << 8) | + ( 1u << 7) | + (96u << 0)); + + // REG_72 + // + // <15:0> 0x2854 TONE2/FSK frequency control word + // = freq(Hz) * 10.32444 for XTAL 13M / 26M or + // = freq(Hz) * 10.48576 for XTAL 12.8M / 19.2M / 25.6M / 38.4M + // + // tone-2 = 1200Hz + // + BK4819_WriteRegister(BK4819_REG_72, ((1200u * 103244) + 5000) / 10000); // with rounding + + // these settings don't match the documentation at all ??? + // + BK4819_WriteRegister(BK4819_REG_58, // 0x00C1); // 000 000 00 11 00 000 1 + (0u << 13) | // 1 FSK TX mode selection + // 0 = FSK 1.2K and FSK 2.4K TX .. no tones, pure data + // 1 = FFSK 1200 / 1800 TX + // 2 = ??? + // 3 = FFSK 1200 / 2400 TX + // 4 = ??? + // 5 = NOAA SAME TX + // 6 = ??? + // 7 = ??? + // + (0u << 10) | // 0 FSK RX mode selection + // 0 = FSK 1.2K, FSK 2.4K RX and NOAA same RX + // 1 = ??? + // 2 = ??? + // 3 = ??? + // 4 = FFSK 1200 / 2400 RX + // 5 = ??? + // 6 = ??? + // 7 = FFSK 1200 / 1800 RX + // + (0u << 8) | // 0 FSK RX gain + // 0 ~ 3 + // + (3u << 6) | // 0 ??? + // 0 ~ 3 + // + (0u << 4) | // 0 FSK preamble type selection + // 0 = 0xAA or 0x55 due to the MSB of FSK sync byte 0 + // 1 = ??? + // 2 = 0x55 + // 3 = 0xAA + // + (0u << 1) | // 1 FSK RX bandwidth setting + // 0 = FSK 1.2K + // 1 = FFSK 1200 / 1800 + // 2 = NOAA same RX + // 3 = ??? + // 4 = FSK 2.4K and FFSK 1200 / 2400 + // 5 = ??? + // 6 = ??? + // 7 = ??? + // + (1u << 0)); // 1 FSK enable + // 0 = disable + // 1 = enable + + // REG_5C + // + // <15:7> ??? + // + // <6> 1 CRC option enable + // 0 = disable + // 1 = enable + // + // <5:0> ??? + // + // Enable CRC among other things we don't know yet + // + BK4819_WriteRegister(BK4819_REG_5C, 0x5665); // 010101100 1 100101 + + // REG_5D + // + // <15:8> 15 FSK data length (byte) Low 8 bits (total 11 bits for BK4819v3) + // 15 means 16 bytes in length + // + // <7:5> 0 FSK data + // + // <4:0> 0 ??? + // + BK4819_WriteRegister(BK4819_REG_5D, ((packet_size - 1) << 8)); + } +#endif + +void BK4819_reset_fsk(void) { - unsigned int i; - uint8_t Timeout = 1000 / 5; // 1 second + BK4819_WriteRegister(BK4819_REG_3F, 0); // disable interrupts - SYSTEM_DelayMs(20); + BK4819_WriteRegister(BK4819_REG_59, // 0x0068); // 0 0 0 0 0 0 0 0 0110 1 000 + (0u << 15) | // 0 or 1 1 = clear TX FIFO + (0u << 14) | // 0 or 1 1 = clear RX FIFO + (0u << 13) | // 0 or 1 1 = scramble + (0u << 12) | // 0 or 1 1 = enable RX + (0u << 11) | // 0 or 1 1 = enable TX + (0u << 10) | // 0 or 1 1 = invert data when RX + (0u << 9) | // 0 or 1 1 = invert data when TX + (0u << 8) | // 0 or 1 ??? + (6u << 4) | // 0 ~ 15 preamble Length Selection + (1u << 3) | // 0 or 1 sync length selection + (0u << 0)); // 0 ~ 7 ??? - BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_TX_FINISHED); - BK4819_WriteRegister(BK4819_REG_59, 0x8068); - BK4819_WriteRegister(BK4819_REG_59, 0x0068); - - // load the packet - for (i = 0; i < 36; i++) - BK4819_WriteRegister(BK4819_REG_5F, pData[i]); - - SYSTEM_DelayMs(20); - - // start sending - BK4819_WriteRegister(BK4819_REG_59, 0x2868); - - // wait till TX is done ? - while (Timeout-- && (BK4819_ReadRegister(BK4819_REG_0C) & (1u << 0)) == 0) - SYSTEM_DelayMs(5); - - BK4819_WriteRegister(BK4819_REG_02, 0); // disable all interrupts - - SYSTEM_DelayMs(20); - - BK4819_ResetFSK(); + BK4819_Idle(); } -*/ -void BK4819_PrepareFSKReceive(void) -{ - BK4819_ResetFSK(); - BK4819_WriteRegister(BK4819_REG_02, 0); - BK4819_WriteRegister(BK4819_REG_3F, 0); +void BK4819_start_fsk_rx(const unsigned int packet_size) +{ + uint16_t fsk_reg59; + + BK4819_reset_fsk(); + + BK4819_WriteRegister(BK4819_REG_02, 0); // clear interrupt flags + + // set the packet size + BK4819_WriteRegister(BK4819_REG_5D, ((packet_size - 1) << 8)); BK4819_RX_TurnOn(); - + +// BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_RX_FINISHED | BK4819_REG_3F_FSK_FIFO_ALMOST_FULL); BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_RX_SYNC | BK4819_REG_3F_FSK_RX_FINISHED | BK4819_REG_3F_FSK_FIFO_ALMOST_FULL); -// BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_RX_FINISHED | BK4819_REG_3F_FSK_FIFO_ALMOST_FULL); - // Clear RX FIFO - // FSK Preamble Length 7 bytes - // FSK SyncLength Selection - BK4819_WriteRegister(BK4819_REG_59, 0x4068); + // REG_59 + // + // <15> 0 TX FIFO + // 1 = clear + // + // <14> 0 RX FIFO + // 1 = clear + // + // <13> 0 FSK Scramble + // 1 = Enable + // + // <12> 0 FSK RX + // 1 = Enable + // + // <11> 0 FSK TX + // 1 = Enable + // + // <10> 0 FSK data when RX + // 1 = Invert + // + // <9> 0 FSK data when TX + // 1 = Invert + // + // <8> 0 ??? + // + // <7:4> 0 FSK preamble length selection + // 0 = 1 byte + // 1 = 2 bytes + // 2 = 3 bytes + // 15 = 16 bytes + // + // <3> 0 FSK sync length selection + // 0 = 2 bytes (FSK Sync Byte 0, 1) + // 1 = 4 bytes (FSK Sync Byte 0, 1, 2, 3) + // + // <2:0> 0 ??? + // + fsk_reg59 = (0u << 15) | // 0 or 1 1 = clear TX FIFO + (0u << 14) | // 0 or 1 1 = clear RX FIFO + (0u << 13) | // 0 or 1 1 = scramble + (0u << 12) | // 0 or 1 1 = enable RX + (0u << 11) | // 0 or 1 1 = enable TX + (0u << 10) | // 0 or 1 1 = invert data when RX + (0u << 9) | // 0 or 1 1 = invert data when TX + (0u << 8) | // 0 or 1 ??? +// (6u << 4) | // 0 ~ 15 preamble Length Selection + (4u << 4) | // 0 ~ 15 preamble Length Selection .. 1of11 .. a little shorter than the TX length + (1u << 3) | // 0 or 1 sync length selection + (0u << 0); // 0 ~ 7 ??? - // Enable FSK Scramble - // Enable FSK RX - // FSK Preamble Length 7 bytes - // FSK SyncLength Selection - BK4819_WriteRegister(BK4819_REG_59, 0x3068); + BK4819_WriteRegister(BK4819_REG_59, (1u << 14) | fsk_reg59); // clear RX fifo + BK4819_WriteRegister(BK4819_REG_59, (1u << 13) | (1u << 12) | fsk_reg59); // enable scrambler, enable RX } void BK4819_PlayRoger(void) @@ -1785,46 +1903,221 @@ void BK4819_PlayRoger(void) SYSTEM_DelayMs(80); BK4819_EnterTxMute(); - BK4819_WriteRegister(BK4819_REG_70, 0x0000); + BK4819_WriteRegister(BK4819_REG_70, 0); BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); // 1 1 0000 0 1 1111 1 1 1 0 } -void BK4819_PlayRogerMDC(void) +void BK4819_PlayRogerMDC1200(void) { - unsigned int i; + static const uint8_t MDC1200_DATA[] = { + 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, + // this needs properly computing for MDC1200 + 0xA2, 0xF1, 0x46, 0x74, 0xA4, 0x61, 0x44, 0x65, 0x8A, 0x4E, 0x44, 0xE0, 0x84, 0xEA + }; + uint16_t fsk_reg59; + unsigned int timeout; BK4819_SetAF(BK4819_AF_MUTE); - BK4819_WriteRegister(BK4819_REG_58, 0x37C3); // FSK Enable, - // RX Bandwidth FFSK 1200/1800 - // 0xAA or 0x55 Preamble - // 11 RX Gain, - // 101 RX Mode - // TX FFSK 1200/1800 - BK4819_WriteRegister(BK4819_REG_72, 0x3065); // Set Tone-2 to 1200Hz - BK4819_WriteRegister(BK4819_REG_70, 0x00E0); // Enable Tone-2 and Set Tone2 Gain - BK4819_WriteRegister(BK4819_REG_5D, 0x0D00); // Set FSK data length to 13 bytes - BK4819_WriteRegister(BK4819_REG_59, 0x8068); // 4 byte sync length, 6 byte preamble, clear TX FIFO - BK4819_WriteRegister(BK4819_REG_59, 0x0068); // Same, but clear TX FIFO is now unset (clearing done) - BK4819_WriteRegister(BK4819_REG_5A, 0x5555); // First two sync bytes - BK4819_WriteRegister(BK4819_REG_5B, 0x55AA); // End of sync bytes. Total 4 bytes: 555555aa - BK4819_WriteRegister(BK4819_REG_5C, 0xAA30); // Disable CRC + BK4819_WriteRegister(BK4819_REG_58, // 0x37C3); // 001 101 11 11 00 001 1 + (1u << 13) | // 1 FSK TX mode selection + // 0 = FSK 1.2K and FSK 2.4K TX .. no tones, pure data + // 1 = FFSK 1200 / 1800 TX + // 2 = ??? + // 3 = FFSK 1200 / 2400 TX + // 4 = ??? + // 5 = NOAA SAME TX + // 6 = ??? + // 7 = ??? + // + (0u << 10) | // 0 FSK RX mode selection + // 0 = FSK 1.2K, FSK 2.4K RX and NOAA same RX + // 1 = ??? + // 2 = ??? + // 3 = ??? + // 4 = FFSK 1200 / 2400 RX + // 5 = ??? + // 6 = ??? + // 7 = FFSK 1200 / 1800 RX + // + (0u << 8) | // 0 FSK RX gain + // 0 ~ 3 + // + (0u << 6) | // 0 ??? + // 0 ~ 3 + // + (0u << 4) | // 0 FSK preamble type selection + // 0 = 0xAA or 0x55 due to the MSB of FSK sync byte 0 + // 1 = ??? + // 2 = 0x55 + // 3 = 0xAA + // + (1u << 1) | // 1 FSK RX bandwidth setting + // 0 = FSK 1.2K + // 1 = FFSK 1200 / 1800 + // 2 = NOAA same RX + // 3 = ??? + // 4 = FSK 2.4K and FFSK 1200 / 2400 + // 5 = ??? + // 6 = ??? + // 7 = ??? + // + (1u << 0)); // 1 FSK enable + // 0 = disable + // 1 = enable - // Send the data from the roger table - for (i = 0; i < 7; i++) - BK4819_WriteRegister(BK4819_REG_5F, FSK_RogerTable[i]); + // REG_72 + // + // <15:0> 0x2854 TONE-2 / FSK frequency control word + // = freq(Hz) * 10.32444 for XTAL 13M / 26M or + // = freq(Hz) * 10.48576 for XTAL 12.8M / 19.2M / 25.6M / 38.4M + // + // tone-2 = 1200Hz + // + BK4819_WriteRegister(BK4819_REG_72, ((1200u * 103244) + 5000) / 10000); // with rounding - SYSTEM_DelayMs(20); + // REG_70 + // + // <15> 0 TONE-1 + // 1 = enable + // 0 = disable + // + // <14:8> 0 TONE-1 gain + // + // <7> 0 TONE-2 + // 1 = enable + // 0 = disable + // + // <6:0> 0 TONE-2 / FSK gain + // 0 ~ 127 + // + // enable tone-2, set gain + // + BK4819_WriteRegister(BK4819_REG_70, // 0 0000000 1 1100000 + ( 0u << 15) | + ( 0u << 8) | + ( 1u << 7) | + (96u << 0)); - // 4 sync bytes, 6 byte preamble, Enable FSK TX - BK4819_WriteRegister(BK4819_REG_59, 0x0868); + // Set FSK data length + BK4819_WriteRegister(BK4819_REG_5D, ((sizeof(MDC1200_DATA) - 1) << 8)); - SYSTEM_DelayMs(180); + // REG_59 + // + // <15> 0 TX FIFO + // 1 = clear + // + // <14> 0 RX FIFO + // 1 = clear + // + // <13> 0 FSK Scramble + // 1 = Enable + // + // <12> 0 FSK RX + // 1 = Enable + // + // <11> 0 FSK TX + // 1 = Enable + // + // <10> 0 FSK data when RX + // 1 = Invert + // + // <9> 0 FSK data when TX + // 1 = Invert + // + // <8> 0 ??? + // + // <7:4> 0 FSK preamble length selection + // 0 = 1 byte + // 1 = 2 bytes + // 2 = 3 bytes + // 15 = 16 bytes + // + // <3> 0 FSK sync length selection + // 0 = 2 bytes (FSK Sync Byte 0, 1) + // 1 = 4 bytes (FSK Sync Byte 0, 1, 2, 3) + // + // <2:0> 0 ??? + // + fsk_reg59 = (0u << 15) | // 0 or 1 1 = clear TX FIFO + (0u << 14) | // 0 or 1 1 = clear RX FIFO + (0u << 13) | // 0 or 1 1 = scramble + (0u << 12) | // 0 or 1 1 = enable RX + (0u << 11) | // 0 or 1 1 = enable TX + (0u << 10) | // 0 or 1 1 = invert data when RX + (0u << 9) | // 0 or 1 1 = invert data when TX + (0u << 8) | // 0 or 1 ??? + (0u << 4) | // 0 ~ 15 preamble length selection + (0u << 3) | // 0 or 1 sync length selection + (0u << 0); // 0 ~ 7 ??? - // Stop FSK TX, reset Tone-2, disable FSK - BK4819_WriteRegister(BK4819_REG_59, 0x0068); - BK4819_WriteRegister(BK4819_REG_70, 0x0000); - BK4819_WriteRegister(BK4819_REG_58, 0x0000); + BK4819_WriteRegister(BK4819_REG_59, (1u << 15) | fsk_reg59); // clear TX fifo + BK4819_WriteRegister(BK4819_REG_59, fsk_reg59); + + // REG_5A + // <15:8> 0x55 FSK Sync Byte 0 (Sync Byte 0 first, then 1,2,3) + // <7:0> 0x55 FSK Sync Byte 1 + // +// BK4819_WriteRegister(BK4819_REG_5A, 0x5555); + BK4819_WriteRegister(BK4819_REG_5A, 0xAAAA); + + // REG_5B + // <15:8> 0x55 FSK Sync Byte 2 (Sync Byte 0 first, then 1,2,3) + // <7:0> 0xAA FSK Sync Byte 3 + // +// BK4819_WriteRegister(BK4819_REG_5B, 0x55AA); + + // Enable CRC among other things we don't know yet + // + // REG_5C + // + // <15:7> ??? + // + // <6> 1 CRC option enable + // 0 = disable + // 1 = enable + // + // <5:0> ??? + // + // disable CRC + // + BK4819_WriteRegister(BK4819_REG_5C, 0xAA30); // 101010100 0 110000 + + { // load the packet data + unsigned int i; + const uint16_t *p = (const uint16_t *)MDC1200_DATA; + for (i = 0; i < (sizeof(MDC1200_DATA) / 2); i++) + BK4819_WriteRegister(BK4819_REG_5F, p[i]); + } + + // enable tx interrupt + BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_TX_FINISHED); + + // enable TX + BK4819_WriteRegister(BK4819_REG_59, (1u << 11) | fsk_reg59); + + // packet is 175ms long + timeout = 250 / 5; // allow up to 250ms for the TX to complete + while (timeout-- > 0) + { + SYSTEM_DelayMs(5); + if (BK4819_ReadRegister(BK4819_REG_0C) & (1u << 0)) + { // we have interrupt flags + uint16_t interrupt_bits; + BK4819_WriteRegister(BK4819_REG_02, 0); + interrupt_bits = BK4819_ReadRegister(BK4819_REG_02); + if (interrupt_bits & BK4819_REG_02_FSK_TX_FINISHED) + timeout = 0; // TX is complete + } + } + + // disable TX + BK4819_WriteRegister(BK4819_REG_59, fsk_reg59); + + BK4819_WriteRegister(BK4819_REG_3F, 0); // disable interrupts + BK4819_WriteRegister(BK4819_REG_70, 0); + BK4819_WriteRegister(BK4819_REG_58, 0); } void BK4819_Enable_AfDac_DiscMode_TxDsp(void) diff --git a/driver/bk4819.h b/driver/bk4819.h index 1962313..b894f46 100644 --- a/driver/bk4819.h +++ b/driver/bk4819.h @@ -105,9 +105,9 @@ void BK4819_ExitTxMute(void); void BK4819_Sleep(void); void BK4819_TurnsOffTones_TurnsOnRX(void); #ifdef ENABLE_AIRCOPY - void BK4819_SetupAircopy(void); + void BK4819_SetupAircopy(const unsigned int packet_size); #endif -void BK4819_ResetFSK(void); +void BK4819_reset_fsk(void); void BK4819_Idle(void); void BK4819_ExitBypass(void); void BK4819_PrepareTransmit(void); @@ -151,11 +151,10 @@ uint8_t BK4819_get_CDCSS_code_type(void); uint8_t BK4819_GetCTCShift(void); uint8_t BK4819_GetCTCType(void); -//void BK4819_SendFSKData(uint16_t *pData); -void BK4819_PrepareFSKReceive(void); +void BK4819_start_fsk_rx(const unsigned int packet_size); void BK4819_PlayRoger(void); -void BK4819_PlayRogerMDC(void); +void BK4819_PlayRogerMDC1200(void); void BK4819_Enable_AfDac_DiscMode_TxDsp(void); diff --git a/driver/crc.c b/driver/crc.c index 7a1840d..800d7d2 100644 --- a/driver/crc.c +++ b/driver/crc.c @@ -19,32 +19,30 @@ void CRC_Init(void) { - CRC_CR = 0 - | CRC_CR_CRC_EN_BITS_DISABLE + CRC_CR = + CRC_CR_CRC_EN_BITS_DISABLE | CRC_CR_INPUT_REV_BITS_NORMAL | CRC_CR_INPUT_INV_BITS_NORMAL | CRC_CR_OUTPUT_REV_BITS_NORMAL | CRC_CR_OUTPUT_INV_BITS_NORMAL | CRC_CR_DATA_WIDTH_BITS_8 - | CRC_CR_CRC_SEL_BITS_CRC_16_CCITT - ; + | CRC_CR_CRC_SEL_BITS_CRC_16_CCITT; CRC_IV = 0; } uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size) { - const uint8_t *pData = (const uint8_t *)pBuffer; - uint16_t i, Crc; + const uint8_t *data = (const uint8_t *)pBuffer; + uint16_t i; + uint16_t crc; CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_ENABLE; - for (i = 0; i < Size; i++) { - CRC_DATAIN = pData[i]; - } - Crc = (uint16_t)CRC_DATAOUT; + for (i = 0; i < Size; i++) + CRC_DATAIN = data[i]; + crc = (uint16_t)CRC_DATAOUT; CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_DISABLE; - return Crc; + return crc; } - diff --git a/firmware.bin b/firmware.bin index 7296aa0..2a3b7ad 100644 Binary files a/firmware.bin and b/firmware.bin differ diff --git a/firmware.packed.bin b/firmware.packed.bin index bb5ffee..1044fdf 100644 Binary files a/firmware.packed.bin and b/firmware.packed.bin differ diff --git a/frequencies.c b/frequencies.c index 204b9f7..0939484 100644 --- a/frequencies.c +++ b/frequencies.c @@ -30,24 +30,24 @@ const freq_band_table_t BX4819_BAND2 = {84000000, 130000000}; const freq_band_table_t FREQ_BAND_TABLE[7] = { - #ifndef ENABLE_WIDE_RX - // QS original - { 5000000, 7600000}, - {10800000, 13600000}, - {13600000, 17400000}, - {17400000, 35000000}, - {35000000, 40000000}, - {40000000, 47000000}, - {47000000, 60000000} - #else + #ifdef ENABLE_WIDE_RX // extended range - { 1800000, 10800000}, - {10800000, 13600000}, - {13600000, 17400000}, - {17400000, 35000000}, - {35000000, 40000000}, - {40000000, 47000000}, - {47000000, 130000000} + { 1800000, 10800000}, // band 1 + {10800000, 13600000}, // band 2 + {13600000, 17400000}, // band 3 + {17400000, 35000000}, // band 4 + {35000000, 40000000}, // band 5 + {40000000, 47000000}, // band 6 + {47000000, 130000000} // band 7 + #else + // QS original + { 5000000, 7600000}, // band 1 + {10800000, 13600000}, // band 2 + {13600000, 17400000}, // band 3 + {17400000, 35000000}, // band 4 + {35000000, 40000000}, // band 5 + {40000000, 47000000}, // band 6 + {47000000, 60000000} // band 7 #endif }; diff --git a/functions.c b/functions.c index 3274ce8..1327c07 100644 --- a/functions.c +++ b/functions.c @@ -226,10 +226,7 @@ void FUNCTION_Select(function_type_t Function) GUI_DisplayScreen(); - RADIO_SetTxParameters(); - - // turn the RED LED on - BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, true); + RADIO_enableTX(false); DTMF_Reply(); diff --git a/helper/boot.c b/helper/boot.c index 1b10282..ea5d7b1 100644 --- a/helper/boot.c +++ b/helper/boot.c @@ -89,13 +89,7 @@ void BOOT_ProcessMode(boot_mode_t Mode) g_current_vfo = g_rx_vfo; - RADIO_SetupRegisters(true); - BK4819_SetupAircopy(); - BK4819_ResetFSK(); - - g_aircopy_state = AIRCOPY_READY; - - GUI_SelectNextDisplay(DISPLAY_AIRCOPY); + AIRCOPY_init(); } #endif else diff --git a/radio.c b/radio.c index 4cbac03..409a353 100644 --- a/radio.c +++ b/radio.c @@ -34,6 +34,7 @@ #include "radio.h" #include "settings.h" #include "ui/menu.h" +#include "ui/ui.h" vfo_info_t *g_tx_vfo; vfo_info_t *g_rx_vfo; @@ -613,21 +614,19 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0) #pragma GCC diagnostic pop - BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, false); - + BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, false); // LED off BK4819_SetupPowerAmplifier(0, 0); - - BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, false); + BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, false); // ??? while (1) - { - const uint16_t Status = BK4819_ReadRegister(BK4819_REG_0C); - if ((Status & 1u) == 0) // INTERRUPT REQUEST + { // wait for the interrupt to clear ??? + const uint16_t status_bits = BK4819_ReadRegister(BK4819_REG_0C); + if ((status_bits & (1u << 0)) == 0) break; - - BK4819_WriteRegister(BK4819_REG_02, 0); + BK4819_WriteRegister(BK4819_REG_02, 0); // clear the interrupt bits SYSTEM_DelayMs(1); } + BK4819_WriteRegister(BK4819_REG_3F, 0); // mic gain 0.5dB/step 0 to 31 @@ -837,7 +836,7 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0) } #endif -void RADIO_SetTxParameters(void) +void RADIO_enableTX(const bool fsk_tx) { BK4819_filter_bandwidth_t Bandwidth = g_current_vfo->channel_bandwidth; @@ -845,7 +844,7 @@ void RADIO_SetTxParameters(void) g_enable_speaker = false; - BK4819_set_GPIO_pin(BK4819_GPIO6_PIN2, false); + BK4819_set_GPIO_pin(BK4819_GPIO6_PIN2, false); // ??? #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wimplicit-fallthrough=" @@ -868,39 +867,38 @@ void RADIO_SetTxParameters(void) #pragma GCC diagnostic pop BK4819_SetFrequency(g_current_vfo->p_tx->frequency); - - // TX compressor - BK4819_SetCompander((g_rx_vfo->am_mode == 0 && (g_rx_vfo->compander == 1 || g_rx_vfo->compander >= 3)) ? g_rx_vfo->compander : 0); - + BK4819_SetCompander((!fsk_tx && g_rx_vfo->am_mode == 0 && (g_rx_vfo->compander == 1 || g_rx_vfo->compander >= 3)) ? g_rx_vfo->compander : 0); BK4819_PrepareTransmit(); - - SYSTEM_DelayMs(10); - BK4819_PickRXFilterPathBasedOnFrequency(g_current_vfo->p_tx->frequency); + BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, true); // ??? + if (g_screen_to_display != DISPLAY_AIRCOPY) + BK4819_SetupPowerAmplifier(g_current_vfo->txp_calculated_setting, g_current_vfo->p_tx->frequency); + else + BK4819_SetupPowerAmplifier(0, g_current_vfo->p_tx->frequency); // very low power when in AIRCOPY mode + BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, true); // turn the RED LED on - BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, true); - - SYSTEM_DelayMs(5); - - BK4819_SetupPowerAmplifier(g_current_vfo->txp_calculated_setting, g_current_vfo->p_tx->frequency); - - SYSTEM_DelayMs(10); - - switch (g_current_vfo->p_tx->code_type) + if (fsk_tx) { - default: - case CODE_TYPE_NONE: - BK4819_ExitSubAu(); - break; - - case CODE_TYPE_CONTINUOUS_TONE: - BK4819_SetCTCSSFrequency(CTCSS_OPTIONS[g_current_vfo->p_tx->code]); - break; - - case CODE_TYPE_DIGITAL: - case CODE_TYPE_REVERSE_DIGITAL: - BK4819_SetCDCSSCodeWord(DCS_GetGolayCodeWord(g_current_vfo->p_tx->code_type, g_current_vfo->p_tx->code)); - break; + BK4819_ExitSubAu(); + } + else + { + switch (g_current_vfo->p_tx->code_type) + { + default: + case CODE_TYPE_NONE: + BK4819_ExitSubAu(); + break; + + case CODE_TYPE_CONTINUOUS_TONE: + BK4819_SetCTCSSFrequency(CTCSS_OPTIONS[g_current_vfo->p_tx->code]); + break; + + case CODE_TYPE_DIGITAL: + case CODE_TYPE_REVERSE_DIGITAL: + BK4819_SetCDCSSCodeWord(DCS_GetGolayCodeWord(g_current_vfo->p_tx->code_type, g_current_vfo->p_tx->code)); + break; + } } } @@ -1089,7 +1087,7 @@ void RADIO_SendEndOfTransmission(void) BK4819_PlayRoger(); else if (g_eeprom.roger_mode == ROGER_MODE_MDC) - BK4819_PlayRogerMDC(); + BK4819_PlayRogerMDC1200(); if (g_current_vfo->dtmf_ptt_id_tx_mode == PTT_ID_APOLLO) BK4819_PlaySingleTone(APOLLO_TONE2_HZ, APOLLO_TONE_MS, 28, g_eeprom.dtmf_side_tone); diff --git a/radio.h b/radio.h index b5d5cd6..a66dd42 100644 --- a/radio.h +++ b/radio.h @@ -137,7 +137,7 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0); #ifdef ENABLE_NOAA void RADIO_ConfigureNOAA(void); #endif -void RADIO_SetTxParameters(void); +void RADIO_enableTX(const bool fsk_tx); void RADIO_Setg_vfo_state(vfo_state_t State); void RADIO_PrepareTX(void); diff --git a/ui/aircopy.c b/ui/aircopy.c index 1d966c7..1c4d52c 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -24,11 +24,16 @@ #include "ui/aircopy.h" #include "ui/helper.h" #include "ui/inputbox.h" +#include "ui/ui.h" void UI_DisplayAircopy(void) { + const uint8_t errors = g_aircopy_rx_errors_fsk_crc + g_aircopy_rx_errors_magic + g_aircopy_rx_errors_crc; char str[17]; + if (g_screen_to_display != DISPLAY_AIRCOPY) + return; + // clear screen/display buffer memset(g_frame_buffer, 0, sizeof(g_frame_buffer)); @@ -78,7 +83,7 @@ void UI_DisplayAircopy(void) break; case AIRCOPY_RX_COMPLETE: - if (g_aircopy_rx_errors == 0) + if (errors == 0) { UI_PrintString("RX COMPLETE", 0, LCD_WIDTH - 1, 5, 8); break; @@ -86,8 +91,17 @@ void UI_DisplayAircopy(void) case AIRCOPY_RX: sprintf(str, "RX %u.%u", g_aircopy_block_number, g_aircopy_block_max); - if (g_aircopy_rx_errors > 0) - sprintf(str + strlen(str), " E %u", g_aircopy_rx_errors); + if (errors > 0) + { + #if 1 + sprintf(str + strlen(str), " E %u", errors); + #else + sprintf(str + strlen(str), " E %u %u %u", + g_aircopy_rx_errors_fsk_crc, + g_aircopy_rx_errors_magic, + g_aircopy_rx_errors_crc); + #endif + } UI_PrintString(str, 0, LCD_WIDTH - 1, 5, 7); break;