diff --git a/Makefile b/Makefile index 0a9f563..aa089f4 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,7 @@ ENABLE_REDUCE_LOW_MID_TX_POWER := 1 # Tx Alarm 0.6 kB ENABLE_ALARM := 0 ENABLE_TX1750 := 0 +ENABLE_MDC1200 := 1 ENABLE_PWRON_PASSWORD := 0 ENABLE_RESET_AES_KEY := 1 ENABLE_BIG_FREQ := 0 @@ -180,6 +181,9 @@ OBJS += frequencies.o OBJS += functions.o OBJS += helper/battery.o OBJS += helper/boot.o +ifeq ($(ENABLE_MDC1200),1) + OBJS += mdc1200.o +endif OBJS += misc.o OBJS += radio.o OBJS += scheduler.o @@ -317,6 +321,9 @@ endif ifeq ($(ENABLE_TX1750),1) CFLAGS += -DENABLE_TX1750 endif +ifeq ($(ENABLE_MDC1200),1) + CFLAGS += -DENABLE_MDC1200 +endif ifeq ($(ENABLE_PWRON_PASSWORD),1) CFLAGS += -DENABLE_PWRON_PASSWORD endif diff --git a/driver/bk4819.c b/driver/bk4819.c index 50b2e87..2f13dfd 100644 --- a/driver/bk4819.c +++ b/driver/bk4819.c @@ -14,7 +14,7 @@ * limitations under the License. */ -#include // NULL +#include // NULL and memset #include "bk4819.h" #include "bsp/dp32g030/gpio.h" @@ -23,6 +23,9 @@ #include "driver/system.h" #include "driver/systick.h" #include "misc.h" +#ifdef ENABLE_MDC1200 + #include "mdc1200.h" +#endif #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) @@ -1924,14 +1927,28 @@ void BK4819_start_fsk_rx(const unsigned int packet_size) void BK4819_PlayRogerMDC1200(void) { - 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; + #ifdef ENABLE_MDC1200 + const uint8_t op = 0x12; + const uint8_t arg = 0x34; + const uint16_t id = 0x5678; + + uint8_t packet[8 + 40]; + memset(packet + 0, 0x00, 4); + memset(packet + 4, 0xff, 4); + const unsigned int size = 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 + BK4819_SetAF(BK4819_AF_MUTE); // BK4819_SetAF(BK4819_AF_BEEP); @@ -2020,7 +2037,7 @@ void BK4819_PlayRogerMDC1200(void) (96u << 0)); // Set FSK data length - BK4819_WriteRegister(BK4819_REG_5D, ((sizeof(MDC1200_DATA) - 1) << 8)); + BK4819_WriteRegister(BK4819_REG_5D, ((size - 1) << 8)); // REG_59 // @@ -2103,10 +2120,10 @@ void BK4819_PlayRogerMDC1200(void) // 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++) + { // load the 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]); } @@ -2116,8 +2133,8 @@ void BK4819_PlayRogerMDC1200(void) // enable TX BK4819_WriteRegister(BK4819_REG_59, (1u << 11) | fsk_reg59); - { // packet is 175ms long - unsigned int timeout = 250 / 5; // allow up to 250ms for the TX to complete + { // packet takes 175ms long + unsigned int timeout = 250 / 5; // allow up to 250ms for the TX to complete while (timeout-- > 0) { SYSTEM_DelayMs(5); diff --git a/firmware.bin b/firmware.bin index c9ad9f0..975e9f0 100644 Binary files a/firmware.bin and b/firmware.bin differ diff --git a/firmware.packed.bin b/firmware.packed.bin index b8d143c..07e9fd9 100644 Binary files a/firmware.packed.bin and b/firmware.packed.bin differ diff --git a/mdc1200.c b/mdc1200.c new file mode 100644 index 0000000..79258da --- /dev/null +++ b/mdc1200.c @@ -0,0 +1,150 @@ + +#include + +#include "mdc1200.h" + +uint16_t flip_crc(const uint16_t crc, const unsigned int bit_num) +{ + uint16_t i; + uint16_t bit; + uint16_t crc_out; + for (i = 1u << (bit_num - 1), bit = 1u, crc_out = 0u; i > 0u; i >>= 1) + { + if (crc & i) + crc_out |= bit; + bit <<= 1; + } + return crc_out; +} + +uint16_t compute_crc(const uint8_t *data, const unsigned int data_len) +{ + unsigned int i; + uint16_t crc = 0x0000; + + for (i = 0; i < data_len; i++) + { + unsigned int mask; + const uint16_t c = flip_crc(*data++, 8); + for (mask = 0x80; mask > 0; mask >>= 1) + { + uint16_t bit = crc & 0x8000; + crc <<= 1; + if (c & mask) + bit ^= 0x8000; + if (bit) + crc ^= 0x1021; + } + } + + return ~flip_crc(crc, 16); +} + +uint8_t * encode_data(uint8_t *data) +{ + unsigned int i; + unsigned int k; + unsigned int m; + int csr[7]; + int lbits[112]; + + 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++) + csr[i] = 0; + + for (i = 0; i < 7; i++) + { + unsigned int j; + data[i + 7] = 0; + for (j = 0; j <= 7; j++) + { + unsigned int b; + for (k = 6; k > 0; k--) + csr[k] = csr[k - 1]; + csr[0] = (data[i] >> j) & 1u; + b = csr[0] + csr[2] + csr[5] + csr[6]; + data[i + 7] |= (b & 1u) << j; + } + } + + k = 0; + m = 0; + for (i = 0; i < 14; i++) + { + unsigned int j; + for (j = 0; j <= 7; j++) + { + lbits[k] = 1u & (data[i] >> j); + k += 16; + if (k > 111) + k = ++m; + } + } + + k = 0; + for (i = 0; i < 14; i++) + { + int j; + data[i] = 0; + for (j = 7; j >= 0; j--) + if (lbits[k++]) + data[i] |= 1u << j; + } + + return &data[14]; +} + +const uint8_t header[] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x07, 0x09, 0x2a, 0x44, 0x6f}; + +int MDC1200_encode_single_packet(uint8_t *data, const uint8_t op, const uint8_t arg, const uint16_t unit_id) +{ + memcpy(data, header, sizeof(header)); + data += sizeof(header); + + data[0] = op; + data[1] = arg; + data[2] = (unit_id >> 8) & 0x00ff; + data[3] = (unit_id >> 0) & 0x00ff; + + encode_data(data); + + return 26; +} + +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) +{ + memcpy(data, header, sizeof(header)); + data += sizeof(header); + + data[0] = op; + data[1] = arg; + data[2] = (unit_id >> 8) & 0x00ff; + data[3] = (unit_id >> 0) & 0x00ff; + + data = encode_data(data); + + data[0] = b0; + data[1] = b1; + data[2] = b2; + data[3] = b3; + + encode_data(data); + + return 40; +} +/* +void test(void) +{ + uint8_t data[14 + 14 + 5 + 7]; + + const int size = MDC1200_encode_single_packet(data, 0x12, 0x34, 0x5678); + +// const int size = MDC1200_encode_double_packet(data, 0x55, 0x34, 0x5678, 0x0a, 0x0b, 0x0c, 0x0d); +} +*/ \ No newline at end of file diff --git a/mdc1200.h b/mdc1200.h new file mode 100644 index 0000000..3681193 --- /dev/null +++ b/mdc1200.h @@ -0,0 +1,10 @@ + +#ifndef MDC1200H +#define MDC1200H + +#include + +int MDC1200_encode_single_packet(uint8_t *data, const uint8_t op, const uint8_t arg, const uint16_t unit_id); +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); + +#endif