All checks were successful
Build Firmware / build (push) Successful in 21s
264 lines
10 KiB
C
264 lines
10 KiB
C
//
|
|
// Created by bruno on 3/30/25.
|
|
//
|
|
|
|
#include "messages.h"
|
|
#include "ui/ui.h"
|
|
#include "driver/uart.h"
|
|
#include "driver/systick.h"
|
|
|
|
#define T9Count 9
|
|
|
|
const char T9Table[10][T9Count] = {
|
|
{'#', '(', ')', ';', ':', '<', '>', '/', '0'},
|
|
{',', '.', '?', '&', '!', ' ', '-', '_', '1'},
|
|
{'a', 'b', 'c', 'A', 'B', 'C', '[', ']', '2'},
|
|
{'d', 'e', 'f', 'D', 'E', 'F', '@', '%', '3'},
|
|
{'g', 'h', 'i', 'G', 'H', 'I', '~', '$', '4'},
|
|
{'j', 'k', 'l', 'J', 'K', 'L', '|', '*', '5'},
|
|
{'m', 'n', 'o', 'M', 'N', 'O', '{', '}', '6'},
|
|
{'p', 'q', 'r', 's', 'P', 'Q', 'R', 'S', '7'},
|
|
{'t', 'u', 'v', 'T', 'U', 'V', '"', '\'', '8'},
|
|
{'w', 'x', 'y', 'z', 'W', 'X', 'Y', 'Z', '9'}
|
|
};
|
|
|
|
|
|
uint8_t gActiveMessage = 0;
|
|
|
|
StoredPacket loadedPacket;
|
|
|
|
uint8_t gKeyTimeout = 0;
|
|
|
|
void MESSAGES_SAVE() {
|
|
uint8_t Data[8];
|
|
EEPROM_ReadBuffer(SEQParameterEEPROM, Data, 8);
|
|
uint8_t msgIndex = Data[1];
|
|
if (msgIndex >= MESSAGES_COUNT) {
|
|
msgIndex = 0;
|
|
}
|
|
Data[1]++;
|
|
EEPROM_WriteBuffer(SEQParameterEEPROM, Data);
|
|
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 0,
|
|
(uint8_t *) &inBoundPacket + 4); // metadata
|
|
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 8,
|
|
(uint8_t *) &inBoundPacket + 12); // message part 1
|
|
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 16,
|
|
(uint8_t *) &inBoundPacket + 20); // message part 2
|
|
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 24,
|
|
(uint8_t *) &inBoundPacket + 28); // message part 3
|
|
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 32,
|
|
(uint8_t *) &inBoundPacket + 36); // message part 4
|
|
|
|
}
|
|
|
|
void MESSAGES_GET() {
|
|
if (gActiveMessage == MESSAGES_COUNT) {
|
|
memcpy(&loadedPacket, (uint8_t *) &dataPacket + (sizeof(DataPacket) - sizeof(StoredPacket)),
|
|
sizeof(StoredPacket));
|
|
} else {
|
|
EEPROM_ReadBuffer(MESSAGES_START + (gActiveMessage * sizeof(StoredPacket)), &loadedPacket,
|
|
sizeof(StoredPacket));
|
|
}
|
|
}
|
|
|
|
void MESSAGES_DELETE() {
|
|
|
|
}
|
|
|
|
void updatePrevChar(KEY_Code_t Key) {
|
|
if (Key != prevKey) {
|
|
prevKey = Key;
|
|
}
|
|
|
|
}
|
|
|
|
void MESSAGES_TimeSlice500ms(void) {
|
|
if (gKeyTimeout && gKeyTimeout++ > 2) {
|
|
gKeyTimeout = 0;
|
|
prevKey = KEY_EXIT;
|
|
}
|
|
}
|
|
|
|
void MESSAGES_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
|
|
gKeyTimeout = 1;
|
|
if (gEnteringSMS != SMS_NOT_ENTERING && !bKeyHeld && Key <= KEY_9) {
|
|
if (!dataPTR || dataPTR < dataPacket.data) {
|
|
dataPTR = dataPacket.data;
|
|
}
|
|
if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
|
|
if (bKeyPressed) {
|
|
if (prevKey != Key) {
|
|
dataPTR++;
|
|
if (dataPTR - dataPacket.data >= DataPacketDataSize) {
|
|
dataPTR = dataPacket.data;
|
|
}
|
|
prevLetter = 0;
|
|
}
|
|
*(dataPTR - 1) = T9Table[Key][(prevLetter++) % T9Count];
|
|
updatePrevChar(Key);
|
|
}
|
|
return;
|
|
} else if (gEnteringSMS == SMS_ENTERING_DEST) {
|
|
if (bKeyPressed) {
|
|
dataPacket.dest *= 10;
|
|
dataPacket.dest += Key;
|
|
prevLetter = 0;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
switch (Key) {
|
|
case KEY_PTT:
|
|
case KEY_MENU:
|
|
if (gEnteringSMS == SMS_NOT_ENTERING) {
|
|
if (bKeyPressed) {
|
|
gEnteringSMS = SMS_ENTERING_DEST;
|
|
updatePrevChar(Key);
|
|
}
|
|
} else if (gEnteringSMS == SMS_ENTERING_DEST) {
|
|
if (bKeyPressed) {
|
|
memset(dataPacket.data, 0, DataPacketDataSize);
|
|
prepareDataPacket();
|
|
//dataPacket.flags = 0x80 | (gCurrentVfo->OUTPUT_POWER & 0x07);
|
|
if (dataPacket.src == 665 || dataPacket.src == 664) {
|
|
|
|
uint8_t out[5];
|
|
if (dataPacket.src == 665) {
|
|
const uint32_t id24 = 0xFFFFFF & (dataPacket.dest >> 4);
|
|
const uint8_t btn = 0x0F & (dataPacket.dest);
|
|
// mask just in case
|
|
// uint32_t id24 = 0x00A38C;
|
|
// uint8_t btn = 0x04;
|
|
|
|
// 3-byte big-endian ID
|
|
out[0] = (id24 >> 16) & 0xFF;
|
|
out[1] = (id24 >> 8) & 0xFF;
|
|
out[2] = (id24 >> 0) & 0xFF;
|
|
|
|
// first nibble redundancy copy: 0xBB if btn=0xB
|
|
out[3] = (btn << 4) | 0x04;
|
|
|
|
// second copy with MSB flipped (btn ^ 0x8) in the high nibble
|
|
out[4] = ((btn ^ 0x8) << 4);
|
|
}
|
|
else {
|
|
out[0] = (dataPacket.dest >> 8) & 0xFF;
|
|
out[1] = dataPacket.dest & 0xFF;
|
|
}
|
|
|
|
BK4819_EnterTxMute();
|
|
RADIO_SetTxParameters();
|
|
|
|
uint16_t datX = BK4819_REG_30_ENABLE_VCO_CALIB |
|
|
BK4819_REG_30_ENABLE_UNKNOWN |
|
|
BK4819_REG_30_DISABLE_RX_LINK |
|
|
BK4819_REG_30_DISABLE_AF_DAC |
|
|
BK4819_REG_30_ENABLE_DISC_MODE |
|
|
BK4819_REG_30_ENABLE_PLL_VCO |
|
|
BK4819_REG_30_ENABLE_PA_GAIN |
|
|
BK4819_REG_30_DISABLE_MIC_ADC |
|
|
BK4819_REG_30_ENABLE_TX_DSP |
|
|
BK4819_REG_30_DISABLE_RX_DSP;
|
|
BK4819_WriteRegister(BK4819_REG_30,
|
|
datX);
|
|
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
|
|
SYSTEM_DelayMs(20);
|
|
|
|
for (unsigned int x = 0; x < 15; x++) {
|
|
for (unsigned int y = 0; y < (dataPacket.src == 665 ? 5 : 2); y++) {
|
|
for (unsigned char i = 7; i < 8; i--) {
|
|
if ((out[y] >> i) & 1) {
|
|
// datX |= BK4819_REG_30_ENABLE_PA_GAIN;
|
|
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, true);
|
|
SYSTICK_DelayUs(400 * (dataPacket.src == 665 ? 3 : 2) - 325);
|
|
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
|
|
// datX &= ~BK4819_REG_30_ENABLE_PA_GAIN;
|
|
SYSTICK_DelayUs(400 * 1 - 325);
|
|
} else {
|
|
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, true);
|
|
// datX |= BK4819_REG_30_ENABLE_PA_GAIN;
|
|
SYSTICK_DelayUs(400 * 1 - 325);
|
|
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
|
|
// datX &= ~BK4819_REG_30_ENABLE_PA_GAIN;
|
|
SYSTICK_DelayUs(400 * (dataPacket.src == 665 ? 3 : 2) - 325);
|
|
}
|
|
}
|
|
}
|
|
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
|
|
SYSTEM_DelayMs((dataPacket.src == 665 ? 3 : 15));
|
|
}
|
|
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
|
|
SYSTEM_DelayMs(100);
|
|
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE);
|
|
gEnteringSMS = SMS_NOT_ENTERING;
|
|
} else {
|
|
gEnteringSMS = SMS_ENTERING_MESSAGE;
|
|
}
|
|
}
|
|
return;
|
|
} else if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
|
|
if (bKeyPressed) {
|
|
if (strlen((char *) dataPacket.data)) {
|
|
MSG_FSKSendData(&dataPacket);
|
|
gEnteringSMS = SMS_NOT_ENTERING;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
break;
|
|
case KEY_UP:
|
|
if (bKeyPressed) {
|
|
gActiveMessage++;
|
|
if (gActiveMessage > MESSAGES_COUNT) {
|
|
gActiveMessage = 0;
|
|
}
|
|
MESSAGES_GET();
|
|
}
|
|
break;
|
|
case KEY_DOWN:
|
|
if (bKeyPressed) {
|
|
gActiveMessage--;
|
|
if (gActiveMessage > MESSAGES_COUNT) {
|
|
gActiveMessage = MESSAGES_COUNT - 1;
|
|
}
|
|
MESSAGES_GET();
|
|
}
|
|
break;
|
|
case KEY_EXIT:
|
|
if (gEnteringSMS != SMS_NOT_ENTERING) {
|
|
if (bKeyHeld) {
|
|
if (bKeyPressed) {
|
|
gEnteringSMS = SMS_NOT_ENTERING;
|
|
dataPTR = dataPacket.data;
|
|
memset(dataPacket.data, 0, DataPacketDataSize);
|
|
}
|
|
} else {
|
|
if (bKeyPressed) {
|
|
if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
|
|
if (dataPacket.data <= dataPTR) {
|
|
*dataPTR = '\0';
|
|
if (dataPacket.data < dataPTR) {
|
|
dataPTR--;
|
|
}
|
|
*dataPTR = '\0';
|
|
}
|
|
} else if (gEnteringSMS == SMS_ENTERING_DEST) {
|
|
dataPacket.dest /= 10;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (bKeyPressed) {
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
}
|
|
}
|
|
updatePrevChar(Key);
|
|
break;
|
|
default:
|
|
if (!bKeyHeld && bKeyPressed)
|
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
|
break;
|
|
}
|
|
} |