diff --git a/app/aircopy.c b/app/aircopy.c index db9f076..08bffec 100644 --- a/app/aircopy.c +++ b/app/aircopy.c @@ -48,7 +48,7 @@ #define AIRCOPY_MAGIC_END_REQ 0xCDBA // used to request a block resend #define AIRCOPY_MAGIC_START 0xABCD // normal start value -#define AIRCOPY_MAGIC_END 0xDCBA // normal end value +#define AIRCOPY_MAGIC_END 0xDCBA // normal end value #define AIRCOPY_LAST_EEPROM_ADDR 0x1E00 // size of eeprom transferred diff --git a/driver/bk4819.c b/driver/bk4819.c index a9b6b78..850cc6a 100644 --- a/driver/bk4819.c +++ b/driver/bk4819.c @@ -1747,7 +1747,8 @@ uint8_t BK4819_GetCTCType(void) ( 0u << 15) | ( 0u << 8) | ( 1u << 7) | - (96u << 0)); +// (96u << 0)); + (127u << 0)); // best waveform // REG_72 // @@ -1759,11 +1760,11 @@ uint8_t BK4819_GetCTCType(void) // BK4819_WriteRegister(BK4819_REG_72, ((1200u * 103244) + 5000) / 10000); // with rounding - // these settings don't match the documentation at all ??? + // aircopy is done in direct FM mode // 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 + // 0 = FSK 1.2K and FSK 2.4K TX .. no tones, direct FM // 1 = FFSK 1200 / 1800 TX // 2 = ??? // 3 = FFSK 1200 / 2400 TX @@ -1773,7 +1774,7 @@ uint8_t BK4819_GetCTCType(void) // 7 = ??? // (0u << 10) | // 0 FSK RX mode selection - // 0 = FSK 1.2K, FSK 2.4K RX and NOAA same RX + // 0 = FSK 1.2K, FSK 2.4K RX and NOAA SAME RX .. no tones, direct FM // 1 = ??? // 2 = ??? // 3 = ??? @@ -1795,9 +1796,9 @@ uint8_t BK4819_GetCTCType(void) // 3 = 0xAA // (0u << 1) | // 1 FSK RX bandwidth setting - // 0 = FSK 1.2K + // 0 = FSK 1.2K .. no tones, direct FM // 1 = FFSK 1200 / 1800 - // 2 = NOAA same RX + // 2 = NOAA SAME RX // 3 = ??? // 4 = FSK 2.4K and FFSK 1200 / 2400 // 5 = ??? @@ -1925,34 +1926,19 @@ void BK4819_start_fsk_rx(const unsigned int packet_size) BK4819_WriteRegister(BK4819_REG_59, (1u << 13) | (1u << 12) | fsk_reg59); // enable scrambler, enable RX } +#ifdef ENABLE_MDC1200 + void BK4819_PlayRogerMDC1200(void) { uint16_t fsk_reg59; + uint8_t packet[40]; - #ifdef ENABLE_MDC1200 + const uint8_t op = MDC1200_OP_CODE_POST_ID; + const uint8_t arg = 0x80; + const uint16_t id = 0xB183; - const uint8_t op = MDC1200_OP_CODE_POST_ID; - const uint8_t arg = 0x00; - const uint16_t id = 0xB183; - - uint8_t packet[8 + 40]; - memset(packet + 0, 0x00, 4); - memset(packet + 4, 0xff, 4); - const unsigned int size = 8 + MDC1200_encode_single_packet(packet + 8, op, arg, id); - - #else - - static const uint8_t packet[] = { - 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 - }; - - const unsigned int size = sizeof(packet); - - }; - #endif + // create the MDC1200 packet + const unsigned int size = MDC1200_encode_single_packet(packet, op, arg, id); BK4819_SetAF(BK4819_AF_MUTE); // BK4819_SetAF(BK4819_AF_BEEP); @@ -1960,26 +1946,28 @@ void BK4819_PlayRogerMDC1200(void) BK4819_EnableTXLink(); SYSTEM_DelayMs(10); + // MDC1200 uses 1200/1800 Hz FSK tone frequencies 1200 bits/s + // 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 + // 0 = FSK 1.2K and FSK 2.4K TX .. no tones, direct FM + // 1 = FFSK 1200/1800 TX // 2 = ??? - // 3 = FFSK 1200 / 2400 TX + // 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 + (7u << 10) | // 0 FSK RX mode selection + // 0 = FSK 1.2K, FSK 2.4K RX and NOAA SAME RX .. no tones, direct FM // 1 = ??? // 2 = ??? // 3 = ??? - // 4 = FFSK 1200 / 2400 RX + // 4 = FFSK 1200/2400 RX // 5 = ??? // 6 = ??? - // 7 = FFSK 1200 / 1800 RX + // 7 = FFSK 1200/1800 RX // (0u << 8) | // 0 FSK RX gain // 0 ~ 3 @@ -1994,11 +1982,11 @@ void BK4819_PlayRogerMDC1200(void) // 3 = 0xAA // (1u << 1) | // 1 FSK RX bandwidth setting - // 0 = FSK 1.2K - // 1 = FFSK 1200 / 1800 - // 2 = NOAA same RX + // 0 = FSK 1.2K .. no tones, direct FM + // 1 = FFSK 1200/1800 + // 2 = NOAA SAME RX // 3 = ??? - // 4 = FSK 2.4K and FFSK 1200 / 2400 + // 4 = FSK 2.4K and FFSK 1200/2400 // 5 = ??? // 6 = ??? // 7 = ??? @@ -2035,14 +2023,11 @@ void BK4819_PlayRogerMDC1200(void) // enable tone-2, set gain // BK4819_WriteRegister(BK4819_REG_70, // 0 0000000 1 1100000 - ( 0u << 15) | - ( 0u << 8) | - ( 1u << 7) | -// ( 0u << 7) | - (96u << 0)); - - // Set FSK data length - BK4819_WriteRegister(BK4819_REG_5D, ((size - 1) << 8)); + ( 0u << 15) | // 0 + ( 0u << 8) | // 0 + ( 1u << 7) | // 1 +// (96u << 0)); // 96 + (127u << 0)); // produces the best undistorted waveform, this is not gain but affects filtering // REG_59 // @@ -2081,36 +2066,39 @@ void BK4819_PlayRogerMDC1200(void) // // <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 ??? + fsk_reg59 = (0u << 15) | // 0 ~ 1 1 = clear TX FIFO + (0u << 14) | // 0 ~ 1 1 = clear RX FIFO + (0u << 13) | // 0 ~ 1 1 = scramble + (0u << 12) | // 0 ~ 1 1 = enable RX + (0u << 11) | // 0 ~ 1 1 = enable TX + (0u << 10) | // 0 ~ 1 1 = invert data when RX + (0u << 9) | // 0 ~ 1 1 = invert data when TX + (0u << 8) | // 0 ~ 1 ??? + (0u << 4) | // 0 ~ 15 preamble length + (0u << 3) | // 0 ~ 1 sync length + (0u << 0); // 0 ~ 7 ??? - BK4819_WriteRegister(BK4819_REG_59, (1u << 15) | fsk_reg59); // clear TX fifo - BK4819_WriteRegister(BK4819_REG_59, fsk_reg59); + // Set entire packet length (not including the pre-amble and sync bytes we can't seem to disable) + BK4819_WriteRegister(BK4819_REG_5D, ((size - 1) << 8)); + + BK4819_WriteRegister(BK4819_REG_59, (1u << 15) | fsk_reg59); // clear TX fifo by setting the FIFO reset bit + BK4819_WriteRegister(BK4819_REG_59, (0u << 15) | fsk_reg59); // release the reset bit // 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); - BK4819_WriteRegister(BK4819_REG_5A, 0); + BK4819_WriteRegister(BK4819_REG_5A, 0); // can be any bit pattern you like // 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); + BK4819_WriteRegister(BK4819_REG_5B, 0); // bytes 2 & 3 not sent/used - // Enable CRC among other things we don't know yet + // CRC setting (plus other stuff we don't know what) // // REG_5C // @@ -2124,13 +2112,14 @@ void BK4819_PlayRogerMDC1200(void) // // disable CRC // - BK4819_WriteRegister(BK4819_REG_5C, 0xAA30); // 101010100 0 110000 +// BK4819_WriteRegister(BK4819_REG_5C, 0xAA30); // 101010100 0 110000 + BK4819_WriteRegister(BK4819_REG_5C, 0); // setting to '0' doesn't make any difference ! - { // load the packet data into the TX FIFO buffer + { // load the entire packet data into the TX FIFO buffer unsigned int i; const uint16_t *p = (const uint16_t *)packet; - for (i = 0; i < (size / 2); i++) - BK4819_WriteRegister(BK4819_REG_5F, p[i]); + for (i = 0; i < (size / sizeof(p[0])); i++) + BK4819_WriteRegister(BK4819_REG_5F, p[i]); // load 16-bits at a time } // enable tx interrupt @@ -2139,8 +2128,14 @@ void BK4819_PlayRogerMDC1200(void) // enable TX BK4819_WriteRegister(BK4819_REG_59, (1u << 11) | fsk_reg59); - { // a small packet takes 175ms long - unsigned int timeout = 500 / 5; // allow up to 500ms for the TX to complete + { // packet time is .. + // 173ms for PTT ID, acks, emergency + // 266ms for call alert and sel-calls + + // allow up to 350ms for the TX to complete + // if it takes any longer then somethings gone wrong, we shut the TX down + unsigned int timeout = 350 / 5; + while (timeout-- > 0) { SYSTEM_DelayMs(5); @@ -2161,6 +2156,8 @@ void BK4819_PlayRogerMDC1200(void) BK4819_WriteRegister(BK4819_REG_58, 0); } +#endif + void BK4819_Enable_AfDac_DiscMode_TxDsp(void) { BK4819_WriteRegister(BK4819_REG_30, 0x0000); diff --git a/driver/crc.c b/driver/crc.c index 800d7d2..855eb42 100644 --- a/driver/crc.c +++ b/driver/crc.c @@ -27,6 +27,7 @@ void CRC_Init(void) | CRC_CR_OUTPUT_INV_BITS_NORMAL | CRC_CR_DATA_WIDTH_BITS_8 | CRC_CR_CRC_SEL_BITS_CRC_16_CCITT; + CRC_IV = 0; } diff --git a/firmware.bin b/firmware.bin index 9cb3536..523382d 100644 Binary files a/firmware.bin and b/firmware.bin differ diff --git a/firmware.packed.bin b/firmware.packed.bin index 152296e..710d30d 100644 Binary files a/firmware.packed.bin and b/firmware.packed.bin differ diff --git a/mdc1200.c b/mdc1200.c index 7f85a93..ca4a5aa 100644 --- a/mdc1200.c +++ b/mdc1200.c @@ -1,7 +1,10 @@ #include +#include "bsp/dp32g030/crc.h" #include "mdc1200.h" +#include "misc.h" + /* uint8_t bitReverse8(uint8_t n) { @@ -30,12 +33,12 @@ uint32_t bitReverse32(uint32_t n) return n; } */ -uint16_t reverse_bits(const uint16_t bits_in, const unsigned int bit_num) +uint16_t reverse_bits(const uint16_t bits_in, const unsigned int num_bits) { uint16_t i; uint16_t bit; uint16_t bits_out; - for (i = 1u << (bit_num - 1), bit = 1u, bits_out = 0u; i > 0u; i >>= 1) + for (i = 1u << (num_bits - 1), bit = 1u, bits_out = 0u; i != 0; i >>= 1) { if (bits_in & i) bits_out |= bit; @@ -46,27 +49,58 @@ uint16_t reverse_bits(const uint16_t bits_in, const unsigned int bit_num) uint16_t compute_crc(const uint8_t *data, const unsigned int data_len) { + + // this can be done using the CPU's own CRC calculator once we know we're ok + unsigned int i; - uint16_t crc = 0x0000; + + #if 0 + uint16_t crc; + + CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_ENABLE; + #else + uint16_t crc = 0x0000; + #endif for (i = 0; i < data_len; i++) { - uint16_t mask; - - const uint16_t b = reverse_bits(*data++, 8); // bit reverse each data byte - - for (mask = 0x0080; mask > 0; mask >>= 1) - { - uint16_t bit = crc & 0x8000; - crc <<= 1; - if (b & mask) - bit ^= 0x8000; - if (bit) - crc ^= 0x1021; - } + #if 0 + + // bit reverse each data byte before adding it to the CRC + // the cortex CPU might have an instruction to bit reverse for us ? + // + CRC_DATAIN = reverse_bits(*data++, 8); + //CRC_DATAIN = bitReverse8(*data++); + + #else + uint8_t mask; + + // bit reverse each data byte before adding it to the CRC + // the cortex CPU might have an instruction to bit reverse for us ? + // + const uint8_t bits = reverse_bits(*data++, 8); + //const uint8_t bits = bitReverse8(*data++); + + for (mask = 0x0080; mask != 0; mask >>= 1) + { + uint16_t msb = crc & 0x8000; + if (bits & mask) + msb ^= 0x8000; + crc <<= 1; + if (msb) + crc ^= 0x1021; + } + #endif } - return reverse_bits(crc, 16) ^ 0xffff; // bit reverse and invert the CRC + #if 0 + crc = (uint16_t)CRC_DATAOUT; + CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_DISABLE; + #endif + + // bit reverse and invert the final CRC + return reverse_bits(crc, 16) ^ 0xffff; +// return bitReverse16(crc) ^ 0xffff; } uint8_t * encode_data(uint8_t *data) @@ -74,101 +108,123 @@ uint8_t * encode_data(uint8_t *data) unsigned int i; unsigned int k; unsigned int m; - int csr[7]; - int lbits[112]; + uint8_t csr[7]; + uint8_t lbits[(ARRAY_SIZE(csr) * 2) * 8]; - const uint16_t ccrc = compute_crc(data, 4); - data[4] = (ccrc >> 0) & 0x00ff; - data[5] = (ccrc >> 8) & 0x00ff; - - data[6] = 0; - - for (i = 0; i < 7; i++) + for (i = 0; i < ARRAY_SIZE(csr); i++) csr[i] = 0; - for (i = 0; i < 7; i++) + for (i = 0; i < ARRAY_SIZE(csr); i++) { - unsigned int j; - data[i + 7] = 0; - for (j = 0; j <= 7; j++) + unsigned int bit; + data[i + ARRAY_SIZE(csr)] = 0; + for (bit = 0; bit < 8; bit++) { - unsigned int b; + uint8_t b; for (k = 6; k > 0; k--) csr[k] = csr[k - 1]; - csr[0] = (data[i] >> j) & 1u; + csr[0] = (data[i] >> bit) & 1u; b = csr[0] + csr[2] + csr[5] + csr[6]; - data[i + 7] |= (b & 1u) << j; + data[i + ARRAY_SIZE(csr)] |= (b & 1u) << bit; } } - k = 0; - m = 0; - for (i = 0; i < 14; i++) + for (i = 0, k = 0, m = 0; i < (ARRAY_SIZE(csr) * 2); i++) { - unsigned int j; - for (j = 0; j <= 7; j++) + unsigned int bit; + for (bit = 0; bit < 8; bit++) { - lbits[k] = 1u & (data[i] >> j); + lbits[k] = (data[i] >> bit) & 1u; k += 16; - if (k > 111) + if (k >= ARRAY_SIZE(lbits)) k = ++m; } } - k = 0; - for (i = 0; i < 14; i++) + for (i = 0, k = 0; i < (ARRAY_SIZE(csr) * 2); i++) { - int j; + int bit; data[i] = 0; - for (j = 7; j >= 0; j--) + for (bit = 7; bit >= 0; bit--) if (lbits[k++]) - data[i] |= 1u << j; + data[i] |= 1u << bit; } - return &data[14]; + return data + 14; } -const uint8_t header[] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x07, 0x09, 0x2a, 0x44, 0x6f}; +// MDC1200 sync bit reversals and packet header +static const uint8_t header[] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x07, 0x09, 0x2a, 0x44, 0x6f}; + +void delta_modulation(uint8_t *data, const unsigned int size) +{ // xor succesive bits in the entire packet, including the bit reversing pre-amble + uint8_t b1; + unsigned int toggle_delay; + unsigned int i; + for (i = 0, toggle_delay = 27, b1 = 1u; i < size; i++) + { + int bit_num; + uint8_t in = data[i]; + uint8_t out = 0; + for (bit_num = 7; bit_num >= 0; bit_num--) + { + const uint8_t b2 = (in >> bit_num) & 1u; + if (toggle_delay > 0) + toggle_delay--; + if (b1 != b2 && toggle_delay == 0) + out |= 1u << bit_num; // previous bit and new bit are different +// out |= 1u << (7 - bit_num); + b1 = b2; + } + data[i] = out; + } +} unsigned int MDC1200_encode_single_packet(uint8_t *data, const uint8_t op, const uint8_t arg, const uint16_t unit_id) { - uint8_t *p = data; + unsigned int size; + uint8_t *p = data; + uint16_t crc; - #if 0 - memcpy(p, header, sizeof(header)); - p += sizeof(header); - #else - memcpy(p + 7, header, sizeof(header)); - p += sizeof(header) - 7; - #endif + memcpy(p, header, sizeof(header)); + p += sizeof(header); p[0] = op; p[1] = arg; p[2] = (unit_id >> 8) & 0x00ff; p[3] = (unit_id >> 0) & 0x00ff; + crc = compute_crc(p, 4); + p[4] = (crc >> 0) & 0x00ff; + p[5] = (crc >> 8) & 0x00ff; + p[6] = 0; p = encode_data(p); - return (unsigned int)(p - data); + size = (unsigned int)(p - data); + + delta_modulation(data, size); + + return size; // return 26; } unsigned int MDC1200_encode_double_packet(uint8_t *data, const uint8_t op, const uint8_t arg, const uint16_t unit_id, const uint8_t b0, const uint8_t b1, const uint8_t b2, const uint8_t b3) { + unsigned int size; uint8_t *p = data; + uint16_t crc; - #if 0 - memcpy(p, header, sizeof(header)); - p += sizeof(header); - #else - memcpy(p + 7, header, sizeof(header)); - p += sizeof(header) - 7; - #endif + memcpy(p, header, sizeof(header)); + p += sizeof(header); p[0] = op; p[1] = arg; p[2] = (unit_id >> 8) & 0x00ff; p[3] = (unit_id >> 0) & 0x00ff; + crc = compute_crc(p, 4); + p[4] = (crc >> 0) & 0x00ff; + p[5] = (crc >> 8) & 0x00ff; + p[6] = 0; p = encode_data(p); @@ -176,11 +232,19 @@ unsigned int MDC1200_encode_double_packet(uint8_t *data, const uint8_t op, const p[1] = b1; p[2] = b2; p[3] = b3; + crc = compute_crc(p, 4); + p[4] = (crc >> 0) & 0x00ff; + p[5] = (crc >> 8) & 0x00ff; + p[6] = 0; p = encode_data(p); + size = (unsigned int)(p - data); + + delta_modulation(data, size); + // return 40; - return (unsigned int)(p - data); + return size; } /* void test(void)