/** * \brief Return system packet * * \param packet The address pointer of system packet that will return */ void return_system_packets(system_packets_t *packet) { uint8_t i; uint8_t *buf; buf=(uint8_t *)packet; buf[packet->packet_length-1]=0; for(i=0; i<packet->packet_length-1; i++) { buf[packet->packet_length-1]^=buf[i]; } data_transmit(buf,packet->packet_length); }
/** * \brief Return system packet result * * \param packet The address pointer of system packet * \param data The data byte will return * \param len The length of return data packet */ void return_packets(system_packets_t *packet,uint8_t *data,uint8_t len) { uint8_t i; uint8_t *buf; packet->packet_length=6+len; memcpy((uint8_t *)&packet->data[0],data,len); buf=(uint8_t *)packet; buf[packet->packet_length-1]=0; for(i=0; i<packet->packet_length-1; i++) { buf[packet->packet_length-1]^=buf[i]; } data_transmit(buf,packet->packet_length); }
// handle_serial_paket() // verarbeitet "paket" mit len optionalen Daten (Header NICHT mitgerechnet). __inline void handle_pc_paket(int len) { answer.head.len = 0; // no answer. last_pc_activity = Get_system_register(AVR32_COUNT); switch (rxdatapacket.head.cmd) { // Kommando-Byte case RPTR_GET_STATUS: if (len==1) { // request update_status(); answer.data[PKT_PARAM_IDX+0] = status_control; answer.data[PKT_PARAM_IDX+1] = status_state; answer.data[PKT_PARAM_IDX+2] = rptr_tx_state; answer.data[PKT_PARAM_IDX+3] = VoiceRxBufSize; answer.data[PKT_PARAM_IDX+4] = VoiceTxBufSize; answer.data[PKT_PARAM_IDX+5] = rptr_get_unsend(); // unsend frames left (incl. gaps) answer.head.len = 7; } else if (len==2) { // enable/disable U8 new_control = (status_control & 0xF0) | (rxdatapacket.data[PKT_PARAM_IDX] & 0x0F); if ((new_control^status_control) & STA_RXENABLE_MASK) { if (new_control & STA_RXENABLE_MASK) { trx_receive(); // set receiving rptr_receive(); // enable receiving } else { idle_timer_start(); // disable receiving } } // fi sw RX if ( (new_control^status_control) & STA_TXENABLE_MASK) { // Enable / Disable selected output of modulation DAC dac_power_ctrl(new_control&STA_TXENABLE_MASK); // Enable / Disable Reference-DAC MAX5820 set_dac_power_mode((new_control&STA_TXENABLE_MASK)?TWI_DAC_POWERUP:TWI_DAC_POWERDOWN); } // fi sw TX status_control = new_control; pc_send_byte(ACK); } else { // invalid - more than one parameter byte pc_send_byte(NAK); } break; case RPTR_GET_VERSION: answer.data[PKT_PARAM_IDX+0] = FIRMWAREVERSION & 0xFF; answer.data[PKT_PARAM_IDX+1] = FIRMWAREVERSION >> 8; memcpy(answer.data+PKT_PARAM_IDX+2, VERSION_IDENT, sizeof(VERSION_IDENT)); answer.head.len = sizeof(VERSION_IDENT)+3-1; // cut String-Terminator /0 break; case RPTR_GET_SERIAL: memcpy(answer.data+PKT_PARAM_IDX, (void *)SERIALNUMBER_ADDRESS, 4); answer.head.len = 5; break; case RPTR_GET_CONFIG: if (len==1) { // request all config char *nextblock = cfg_read_c0(answer.data+PKT_PARAM_IDX); nextblock = cfg_read_c1(nextblock); //... answer.head.len = nextblock - answer.data - 3; } else if (len==2) { // request a single block switch(rxdatapacket.data[PKT_PARAM_IDX]) { case 0xC0: cfg_read_c0(answer.data+PKT_PARAM_IDX); answer.head.len = sizeof(CONFIG_C0)+3; break; case 0xC1: cfg_read_c1(answer.data+PKT_PARAM_IDX); answer.head.len = CONFIG_C1_SIZE+3; break; default: pc_send_byte(NAK); break; } } else { pc_send_byte(NAK); } break; case RPTR_SET_CONFIG: if (config_setup(rxdatapacket.data+PKT_PARAM_IDX, len-1)) { pc_send_byte(ACK); } else { pc_send_byte(NAK); } break; case RPTR_START: // early Turn-On xmitter, if configured a long TXD if ((status_control & STA_TXENABLE_MASK) && (len==3)) { if (rxdatapacket.data[PKT_PARAM_IDX] != current_txid) { rptr_transmit_preamble(); // PTTon, wait for a header to start TX if (rptr_tx_state <= RPTRTX_preamble) // starts w/o interrupting a running transmission current_txid = rxdatapacket.data[PKT_PARAM_IDX]; } } else pc_send_byte(NAK); break; case RPTR_HEADER: // start transmitting TXDelay-Preamble-Start-Header if (rptr_tx_state != RPTRTX_header) // update only, if not transmitting just this moment rptr_init_header((tds_header *)&rxdatapacket.data[PKT_PARAM_IDX+4]); if (status_control & STA_TXENABLE_MASK) { if ((rptr_tx_state <= RPTRTX_preamble) || (rxdatapacket.data[PKT_PARAM_IDX] != current_txid)) { rptr_transmit(); // Turn on Xmitter current_txid = rxdatapacket.data[PKT_PARAM_IDX]; } // fi // -> ignore a HEADER msg with same TXID while sending add_icom_voice_reset(); } else pc_send_byte(NAK); // keep 2 bytes for future use, keep layout identical to RX break; case RPTR_RXSYNC: // start transmitting TXDelay-Preamble-Start-Header if (rptr_tx_state != RPTRTX_header) // update only, if not transmitting just this moment rptr_replacement_header(); if (status_control & STA_TXENABLE_MASK) { if ((rptr_tx_state <= RPTRTX_preamble) || (rxdatapacket.data[PKT_PARAM_IDX] != current_txid)) { rptr_transmit(); // Turn on Xmitter only if PTT off current_txid = rxdatapacket.data[PKT_PARAM_IDX]; } // if idle // (transmission use last header) add_icom_voice_reset(); } else pc_send_byte(NAK); break; case RPTR_DATA: // transmit data (voice and slowdata or sync) if (rxdatapacket.data[PKT_PARAM_IDX] == current_txid) add_icom_voice_2_rptr(rxdatapacket.data[PKT_PARAM_IDX+1], &rxdatapacket.data[PKT_PARAM_IDX+4]); //add_multi_voice_2_rptr(len); break; case RPTR_EOT: // end transmission with EOT tail if (len == 3) { if (rxdatapacket.data[PKT_PARAM_IDX] == current_txid) rptr_endtransmit(rxdatapacket.data[PKT_PARAM_IDX+1]); } else rptr_endtransmit(0xFF); // stop after buffer is empty break; case RPTR_SET_SPECIALFUNCT: handle_special_func_cmd(len); break; default: pc_send_byte(NAK); break; } // hctiws if ((answer.head.len > 0)&&(answer.head.len<(PAKETBUFFERSIZE-4))) { U32 anslen = answer.head.len+5; answer.head.id = FRAMESTARTID; answer.head.cmd = 0x80|rxdatapacket.head.cmd; answer.head.len = swap16(answer.head.len); append_crc_ccitt(answer.data, anslen); data_transmit(answer.data, anslen); } // fi send }
void handle_hfdata(void) { static bool transmission = false; if (RPTR_is_set(RPTR_INDICATOR_MASK)) { if (RPTR_is_set(RPTR_RX_1STPREAMBLE)) { RPTR_clear(RPTR_RX_1STPREAMBLE); ctrldata.head.cmd = RPTR_RXPREAMBLE; append_crc_ccitt((char *)&ctrldata, sizeof(ctrldata)); data_transmit((char *)&ctrldata, sizeof(ctrldata)); } if (RPTR_is_set(RPTR_RX_FRAMESYNC)) { RPTR_clear(RPTR_RX_FRAMESYNC); if (!transmission) { ctrldata.head.cmd = RPTR_RXSYNC; ctrldata.rxid++; headerdata.rxid = ctrldata.rxid; voicedata.rxid = ctrldata.rxid; append_crc_ccitt((char *)&ctrldata, sizeof(ctrldata)); data_transmit((char *)&ctrldata, sizeof(ctrldata)); transmission = true; } } if (RPTR_is_set(RPTR_RX_FRAME)) { RPTR_clear(RPTR_RX_FRAME); voicedata.pktcount = rptr_copycurrentrxvoice(&voicedata.DVdata); voicedata.rssi = swap16(gmsk_get_rssi_avrge()); append_crc_ccitt((char *)&voicedata, sizeof(voicedata)); data_transmit((char *)&voicedata, sizeof(voicedata)); } // fi voice data if (RPTR_is_set(RPTR_RX_START)) { RPTR_clear(RPTR_RX_START); ctrldata.head.cmd = RPTR_START; ctrldata.rxid++; headerdata.rxid = ctrldata.rxid; voicedata.rxid = ctrldata.rxid; append_crc_ccitt((char *)&ctrldata, sizeof(ctrldata)); data_transmit((char *)&ctrldata, sizeof(ctrldata)); transmission = true; } // fi start detected if (RPTR_is_set(RPTR_RX_STOP)) { RPTR_clear(RPTR_RX_STOP); #ifdef SIMPLIFIED_FIFO // simplified Fifo buffer behavior, as requested by DG1HT voicedata.pktcount = 0x40; voicedata.rssi = swap16(gmsk_get_rssi_avrge()); append_crc_ccitt((char *)&voicedata, sizeof(voicedata)); data_transmit((char *)&voicedata, sizeof(voicedata)); #else ctrldata.head.cmd = RPTR_EOT; ctrldata.rsvd = voicedata.pktcount; append_crc_ccitt((char *)&ctrldata, sizeof(ctrldata)); data_transmit((char *)&ctrldata, sizeof(ctrldata)); #endif transmission = false; } // fi start detected if (RPTR_is_set(RPTR_RX_LOST)) { RPTR_clear(RPTR_RX_LOST); #ifdef SIMPLIFIED_FIFO // simplified Fifo buffer behavior, as requested by DG1HT voicedata.pktcount = 0x40; voicedata.rssi = swap16(gmsk_get_rssi_avrge()); append_crc_ccitt((char *)&voicedata, sizeof(voicedata)); data_transmit((char *)&voicedata, sizeof(voicedata)); #else ctrldata.head.cmd = RPTR_RXLOST; ctrldata.rsvd = voicedata.pktcount; append_crc_ccitt((char *)&ctrldata, sizeof(ctrldata)); data_transmit((char *)&ctrldata, sizeof(ctrldata)); #endif transmission = false; } // fi start detected if (RPTR_is_set(RPTR_RX_HEADER)) { RPTR_clear(RPTR_RX_HEADER); if (!transmission) { ctrldata.rxid++; headerdata.rxid = ctrldata.rxid; voicedata.rxid = ctrldata.rxid; transmission = true; } // fi no tx headerdata.biterrs = dstar_decodeheader(&headerdata.header, rptr_getheader()); // Checking header-crc: headerdata.flags = 0x00; if (!dstar_checkheader(&headerdata.header)) { headerdata.flags |= 0x80; // if corrupt set Bit7 of flags rptr_forcefirstsync(); } // fi crc append_crc_ccitt((char *)&headerdata, sizeof(headerdata)); data_transmit((char *)&headerdata, sizeof(headerdata)); } // fi start detected } // fi do something // Testet, ob was emfangen wurde. // sendet sofort an pc }