/* * Copyright (C) 2009-2016 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Config.h" #include "Globals.h" #include "CalDStarTX.h" const uint8_t HEADER[] = {0x00U, 0x00U, 0x00U, 'D', 'I', 'R', 'E', 'C', 'T', ' ', ' ', 'D', 'I', 'R', 'E', 'C', 'T', ' ', ' ', 'C', 'Q', 'C', 'Q', 'C', 'Q', ' ', ' ', 'M', 'M', 'D', 'V', 'M', ' ', ' ', ' ', 'T', 'E', 'S', 'T', 0xA9U, 0x6AU}; const uint8_t SLOW_DATA_TEXT[] = {'M', 'M', 'D', 'V', 'M', ' ', 'M', 'o', 'd', 'e', 'm', ' ', 'T', 'e', 's', 't', ' ', ' ', ' ', ' '}; CCalDStarTX::CCalDStarTX() : m_transmit(false), m_count(0U) { } void CCalDStarTX::process() { dstarTX.process(); if (!m_transmit) return; uint16_t space = dstarTX.getSpace(); if (space < 5U) return; uint8_t buffer[DSTAR_DATA_LENGTH_BYTES]; for (uint8_t i = 0U; i < DSTAR_DATA_LENGTH_BYTES; i++) buffer[i] = DSTAR_DATA_SYNC_BYTES[i]; if ((m_count % 21U) == 0U) { // Sync is already included } else if (m_count == 1U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ (DSTAR_SLOW_DATA_TYPE_TEXT | 0U); buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ SLOW_DATA_TEXT[0U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ SLOW_DATA_TEXT[1U]; } else if (m_count == 2U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ SLOW_DATA_TEXT[2U]; buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ SLOW_DATA_TEXT[3U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ SLOW_DATA_TEXT[4U]; } else if (m_count == 3U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ (DSTAR_SLOW_DATA_TYPE_TEXT | 1U); buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ SLOW_DATA_TEXT[5U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ SLOW_DATA_TEXT[6U]; } else if (m_count == 4U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ SLOW_DATA_TEXT[7U]; buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ SLOW_DATA_TEXT[8U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ SLOW_DATA_TEXT[9U]; } else if (m_count == 5U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ (DSTAR_SLOW_DATA_TYPE_TEXT | 2U); buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ SLOW_DATA_TEXT[10U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ SLOW_DATA_TEXT[11U]; } else if (m_count == 6U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ SLOW_DATA_TEXT[12U]; buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ SLOW_DATA_TEXT[13U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ SLOW_DATA_TEXT[14U]; } else if (m_count == 7U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ (DSTAR_SLOW_DATA_TYPE_TEXT | 3U); buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ SLOW_DATA_TEXT[15U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ SLOW_DATA_TEXT[16U]; } else if (m_count == 8U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ SLOW_DATA_TEXT[17U]; buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ SLOW_DATA_TEXT[18U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ SLOW_DATA_TEXT[19U]; } else if (m_count != 1U && (m_count % 21U) == 1U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ (DSTAR_SLOW_DATA_TYPE_HEADER | 5U); buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[0U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[1U]; } else if (m_count != 2U && (m_count % 21U) == 2U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ HEADER[2U]; buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[3U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[4U]; } else if (m_count != 3U && (m_count % 21U) == 3U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ (DSTAR_SLOW_DATA_TYPE_HEADER | 5U); buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[5U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[6U]; } else if (m_count != 4U && (m_count % 21U) == 4U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ HEADER[7U]; buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[8U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[9U]; } else if (m_count != 5U && (m_count % 21U) == 5U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ (DSTAR_SLOW_DATA_TYPE_HEADER | 5U); buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[10U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[11U]; } else if (m_count != 6U && (m_count % 21U) == 6U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ HEADER[12U]; buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[13U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[14U]; } else if (m_count != 7U && (m_count % 21U) == 7U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ (DSTAR_SLOW_DATA_TYPE_HEADER | 5U); buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[15U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[16U]; } else if (m_count != 8U && (m_count % 21U) == 8U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ HEADER[17U]; buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[18U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[19U]; } else if (m_count != 9U && (m_count % 21U) == 9U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ (DSTAR_SLOW_DATA_TYPE_HEADER | 5U); buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[20U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[21U]; } else if (m_count != 10U && (m_count % 21U) == 10U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ HEADER[22U]; buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[23U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[24U]; } else if (m_count != 11U && (m_count % 21U) == 11U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ (DSTAR_SLOW_DATA_TYPE_HEADER | 5U); buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[25U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[26U]; } else if (m_count != 12U && (m_count % 21U) == 12U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ HEADER[27U]; buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[28U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[29U]; } else if (m_count != 13U && (m_count % 21U) == 13U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ (DSTAR_SLOW_DATA_TYPE_HEADER | 5U); buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[30U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[31U]; } else if (m_count != 14U && (m_count % 21U) == 14U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ HEADER[32U]; buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[33U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[34U]; } else if (m_count != 15U && (m_count % 21U) == 15U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ (DSTAR_SLOW_DATA_TYPE_HEADER | 5U); buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[35U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[36U]; } else if (m_count != 16U && (m_count % 21U) == 16U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ HEADER[37U]; buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[38U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ HEADER[39U]; } else if (m_count != 17U && (m_count % 21U) == 17U) { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ (DSTAR_SLOW_DATA_TYPE_HEADER | 1U); buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ HEADER[40U]; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ 'f'; } else { buffer[9U] = DSTAR_SCRAMBLER_BYTES[0U] ^ 'f'; buffer[10U] = DSTAR_SCRAMBLER_BYTES[1U] ^ 'f'; buffer[11U] = DSTAR_SCRAMBLER_BYTES[2U] ^ 'f'; } dstarTX.writeData(buffer, DSTAR_DATA_LENGTH_BYTES); m_count = (m_count + 1U) % (30U * 21U); } uint8_t CCalDStarTX::write(const uint8_t* data, uint8_t length) { if (length != 1U) return 4U; bool transmit = data[0U] == 1U; if (transmit && !m_transmit) { m_count = 0U; dstarTX.writeHeader(HEADER, DSTAR_HEADER_LENGTH_BYTES); } else if (!transmit && m_transmit) { dstarTX.writeEOT(); } m_transmit = transmit; return 0U; }