//************************************************************** // Name : OPERA_Beacon_Keyer_CCSC_MPLAB_IDE.C * // Author : Rick Wakatori, 7L1RLL * // Notice : Copyright(C)2010 NAO JR6RMZ.All Rights Reserved * // Copyright for Language C : Rick Wakatori,7L1RLL * // Date : 2016/01/09 * // Version : 12.0002 * // Notes : Callsign for 7L1RLL * // : Translated by 7L1RLL for CCS-C * // : Memory usage : ROM=41%,RAM=46%,EEPROM=60% * // : BUILD SUCCEEDE Fri Oct 23 19:50:12 2015 * // Purposes: This program make AKI-PIC877A-V2 possible to * // QRSS_DFCW_OPERA_Beacon_Keyer. * // Usage : The program assumes additional circuit as follows;* // INPUT(Active State) OUTPUT(Active State)@ * // RD7: DFCW_SW(0) RB7: Dash-Lamp(0) * // RD6: 2or3dot_SW(0) RB6: Dash&Dot-Lamp(0) * // RD5: Speed 2^2(0) RB5: Dash-Lamp(0) * // RD4: Speed 2^1(0) RB4: Dot Keying(1) * // RD3: Speed 2^0(0) RB3: Not used * // RD2: MsgSW 2^2(0) RB2: Dash Keying(1) * // RD1: MsgSW 2^1(0) RB1: End-Msg-Lamp(0) * // RD0: MsgSW 2^0(0) RB0: Write-Lamp(0) * // RC7: RX(CN-C12) RC6: TX(CN-C13) * // 877-18:MCLR(CN-C-14) * //*************************************************************** #include <16F877A.h> #fuses HS, NOWDT, NOPROTECT,NOBROWNOUT, NOLVP #include #include #include #use delay(crystal=20MHz) #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Definitions --------------------------------------------------------------- #define PORTB 0x006 #define PORTC 0x007 #define PORTD 0x008 ////// Global Constants /////// const unsigned int8 maxMsg = 32; const int16 operaSym = 239; const char allLamps = 0b00000000; const char clear = 0b11100011; const char dash = 0b00010111; const char dot_DFCW = 0b10110011; const char dot_QRSS_CW_OP = 0b10110111; const char endLamp = 0b11100001; ///// Global Variables /////// int32 dashLen = 3; // dash Length <== dashLen * dotLen int32 dotLen = 150;// 150ms int1 dfcw = 0; // false for DFCW int8 opera = 0; // no for OPERA int32 pauseLen = 150;// pause length char msg[maxMsg] = ""; // message temporal storage ///// Declaration of Functions ////// void delay_s(int32 m); // delay second void get_messege(); // select a message void get_speed(); // select a speed and mode void lamp_test(); // all lamps test void prepair_eeprom(); // write messages into eeprom void read_str_eeprom(unsigned int8 address); void send_message(); // send a message void send_code(char cwd,int8 n);// send CW code per character void send_dot(); // send a dot element void send_dash(); // send a dash element void write_str_eeprom(unsigned int8 address, char *str); ///// OPERA functions for CCS-C compiler void send_opera_one_symbol(int1 symbol); void send_opera_beacon(void); //------------------------------------- void main(void) //------------------------------------- { set_tris_d(255); //Port D are all input set_tris_b(0); //Port B are all output set_tris_c(0x80);//Port C C7=input, the others are output lamp_test(); // lit all lamps for test prepair_eeprom();// write messages while(TRUE){ // endless loop output_b(clear); get_speed(); // check speed switch get_messege(); // check text switch if (opera != 0){ //Opera8 or Opera 32 send_opera_beacon(); } else // CW, QRSS or DFCW send_message(); } } // end of main() //--------------------------------------- void send_message(void) //--------------------------------------- { const char c_seq[43]="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789?/#$*_"; const int16 Morse[43]={ // Left Hand=Morse code(0=Make,1=Open) in Hexa representaion. // The code 0x00xx means a pause. // Right Hand=codelength or number of pause. 0xBF02,0x7F04,0x5F04,0x6F03,0x8F01, // ABCDE 0xDF04,0x2F03,0xFF04,0xCF02,0x8F04, // FGHIJ 0x5F03,0xBF04,0x3F02,0x4F02,0x1F03, // KLMNO 0x9F04,0x2F04,0xAF03,0xEF03,0x7F01, // PQRST 0xDF03,0xEF04,0x9F03,0x6F04,0x4F04, // UVWXY 0x3F04, // Z 0x0705,0x8705,0xC705,0xE705,0xF705, // 01234 0xF805,0x7F05,0x3F05,0x1F05,0x0F05, // 56789 0x3306,0x6F05,0x0000,0x0000,0x0000, // ?/#$* 0x0001}; // _ unsigned int8 ad = 0, d = 0, i = 0, j = 0, n = 0, lenMsg = 0; int16 mc = 0; char cwd = 0x00, c[2] = " ", seq[43]; strcpy(seq,c_seq); // convert to string strncpy(c,msg,1); // pick a character in the c lenMsg = strlen(msg); while ((c[0]!=0) && (i<=maxMsg) && (i"); output_b(endLamp); return; } switch (d){ case (unsigned)'#': output_low(PIN_B1); // on end-messege-lamp putchar('#'); break; case (unsigned)'$': // off end-message-lamp output_high(PIN_B1); putchar('$'); break; case (unsigned)'*': putchar('*'); // repeat //delay_s(dotLen*dashLen); return; case (unsigned)'_' : putchar('_'); //pause delay_s(dotLen*dashLen); // pause break; default : puts(c); ad=strcspn(seq,c); // Collarative seq. mc=Morse[ad]; // get Morse word cwd=((0xFF00 & mc) >> 8); // Morse code n=(0x00FF & mc); // code length send_code(cwd,n); break; } delay_s(dotLen*dashLen); // pause between two characters i++; for(j=0;j<=7;j++){ rotate_right(msg,maxMsg); // shift to next character } strncpy(c,msg,1); // pick a next character in the c } // while output_b(endLamp); delay_s(1000); } // end of send_message() //--------------------------------------- void delay_s(int32 t) // support longer than int16 //--------------------------------------- { unsigned int16 i = 0, m = 0, n = 0; m = t / 65535; if (m >0) { for (i = 0; i < m; i++) delay_ms(65535); } n = t - (65535 * m); if ( n > 0) delay_ms(n); } // end of delay_s //------------------------------- void lamp_test(void) //------------------------------- { output_b(allLamps); // all lamps on delay_s(1000); output_b(clear); delay_s(1000); } // end of lamps_test() //-------------------------------------- void send_dot(void) //-------------------------------------- { if (dfcw == 0) // QRSS, CW or OPERA output_b(dot_QRSS_CW_OP);// send a dot for QRSS, CW or OPERA else // DFCW output_b(dot_DFCW); // send a dot for DFCW delay_s(dotLen); // dot length output_b(clear); // end of a dot delay_s(pauseLen); // pause } // end of send_dot() //---------------------------------- void send_dash(void) //---------------------------------- { output_b(dash); // send a dash delay_s(dashLen*dotLen);// dash length output_b(clear); delay_s(pauseLen); // pause } // send_dash() //---------------------------------- void send_code(char cwd,int8 n) //---------------------------------- { int8 i; for (i=0;i<=n-1;i++){ if ((cwd & 0x0080) != 0) send_dot(); // dot else send_dash(); // dash cwd <<= 1; // shift cwd 1 bit left } } // end of send_code() //---------------------------------------------- void write_str_eeprom(unsigned int8 baseAddress, char* s) //---------------------------------------------- { int16 i, n; char c = '.'; i = baseAddress; n = strlen(s); while ((i < (baseAddress + n))||( c !=0x00)){ c = *s++; write_eeprom(i, c); i++; } while (i < (baseAddress + maxMsg)){ write_eeprom(i,0x00); i++; } }// end fo write_str_eeprom() //---------------------------------------------- void read_str_eeprom(unsigned int8 address) //---------------------------------------------- { char c[2]=""; unsigned int8 i = 0;//, maxAdrs; for (i = 0; i <= maxMsg; i++) msg[i] = 0x00;// clear msg i = 0; //maxAdrs = address + maxMsg; c[0] = (char) read_eeprom(address + i); c[1]= 0x00; while ((c[0] != 0x00) && (i < maxMsg)) { strcat(msg, c); i++; c[0] = read_eeprom(address + i); } } //end of read_str_eeprom() //---------------------------------------------- void send_opera_beacon(void) //---------------------------------------------- { // send 239 symbol from 30 byte int8 i = 0, j = 0, opByte = 0x00; int1 s = 0; int32 wait = 0; msg = " ";// discard previous msg for (i=0; i <= 29; i++){ opByte = read_eeprom(0xE0+i); for (j = 0; j <= 7; j++){ if (!((i == 29) && (j == 7))){ // discard a last bit s = bit_test(opByte, (7-j)); send_opera_one_symbol(s); } } // for j } // for i output_b(endLamp); //lit end lamp wait = dotLen * dashLen * operaSym; delay_s(wait); } // end of send_opera_beacon //---------------------------------------------- void prepair_eeprom(void) //---------------------------------------------- { strcpy(msg, "7L1RLL#_$_*"); write_str_eeprom(0x00, msg); strcpy(msg, "7L1RLL/1#_$_*"); write_str_eeprom(0x20, msg); strcpy(msg, "EX_VVV_VVV_VVV_DE_7L1RLL#_$_*"); write_str_eeprom(0x40, msg); strcpy(msg, "EX_VVV_VVV_VVV_DE_7L1RLL/1#_$_*"); write_str_eeprom(0x60, msg); strcpy(msg, "CQ_DE_7L1RLL_7L1RLL_K#_$_*"); write_str_eeprom(0x80, msg); strcpy(msg, "CQ_DE_7L1RLL/1_7L1RLL/1_K#_$_*"); write_str_eeprom(0xA0, msg); strcpy(msg, "CQ_TEST_DE_7L1RLL/1_K#_$_*"); write_str_eeprom(0xC0, msg); // OPERA 239 symbols represented in Hexa-notation write_eeprom(0xE0, 0xAD); write_eeprom(0xE1, 0x2D); write_eeprom(0xE2, 0x2A); write_eeprom(0xE3, 0xCA); write_eeprom(0xE4, 0xAA); write_eeprom(0xE5, 0xB4); write_eeprom(0xE6, 0xB2); write_eeprom(0xE7, 0xAB); write_eeprom(0xE8, 0x35); write_eeprom(0xE9, 0x2A); write_eeprom(0xEA, 0xAB); write_eeprom(0xEB, 0x53); write_eeprom(0xEC, 0x32); write_eeprom(0xED, 0xCC); write_eeprom(0xEE, 0xD2); write_eeprom(0xEF, 0xAB); write_eeprom(0xF0, 0x32); write_eeprom(0xF1, 0xCB); write_eeprom(0xF2, 0x4C); write_eeprom(0xF3, 0xD5); write_eeprom(0xF4, 0x53); write_eeprom(0xF5, 0x53); write_eeprom(0xF6, 0x2C); write_eeprom(0xF7, 0xCD); write_eeprom(0xF8, 0x4D); write_eeprom(0xF9, 0x4B); write_eeprom(0xFA, 0x4C); write_eeprom(0xFB, 0xB4); write_eeprom(0xFC, 0xAA); write_eeprom(0xFD, 0xAC); write_eeprom(0xFE, 0x00); write_eeprom(0xFF, 0x00); } // end of prepair_message() //---------------------------------------------- void get_messege(void) //---------------------------------------------- { // getting message depending on msgSW int8 msgSW = 0; // selection value of massage switch if (input(PIN_D0) == 0) msgSW+=1; // message switch bit xx1 if (input(PIN_D1) == 0) msgSW+=2; // message switch bit x1x if (input(PIN_D2) == 0) msgSW+=4; // message switch bit 1xx // msgSW = 6; // for debug *msg = ""; switch (msgSW){ case 0: // Text #1 callsing read_str_eeprom(0x00); break; case 1: // Text #2 callsign/portable read_str_eeprom(0x20); break; case 2: // Text #3 ex vvv callsign read_str_eeprom(0x40); break; case 3: // Text #4 ex vvv callsign/portable read_str_eeprom(0x60); break; case 4: // Text #5 CQ DE callsign read_str_eeprom(0x80); break; case 5: // Text #6 CQ DE callsign/portable read_str_eeprom(0xA0); break; case 6: // Text #7 CQ TEST DE callsign/portable read_str_eeprom(0xC0); break; case 7: // Text #8 callsign same as case 0 read_str_eeprom(0x00); break; default: // callsign read_str_eeprom(0x00); break; } // end of text_switch } // end of get_message() //---------------------------------------------------- void get_speed() //--- check both Speed switch and Dash length switch-- { int8 speedSW=0; int32 td=150; // in milli second // Scan the speed swithes(Switch: on=0,off=1) if (input(PIN_D3) == 0) speedSW+=1; //xx0 where zero = on if (input(PIN_D4) == 0) speedSW+=2; //x0x where zero = on if (input(PIN_D5) == 0) speedSW+=4; //0xx where zero = on switch (speedSW){ case 0: td = 150; break; // 0.1s case 1: td = 5000; break; // 5s case 2: td = 10000; break; // 10s case 3: td = 20000; break; // 20s case 4: td = 30000; break; // 30s case 5: td = 60000; break; // 60s case 6: td = 90000; break; // 90s case 7: td = 120000; break; // 120s default: td = 150; // same as case 0 } // end of speed Switch selection if (td < 1000){ // CW dotLen = td; dashLen = 3; pauseLen = dotLen; dfcw = 0; // 150ms } else if (td <= 5000){ // OPERA8 dotLen = 2048; // bit period for opera 8 pauseLen = 0; dashLen = 2; opera = 2; dfcw = 0; } else if (td <=10000){ // OPERA32 dotLen = 8192; // bit period for opera 32 pauseLen = 0; dashLen = 2; opera = 4; dfcw = 0; } else { // QRSS or DFCW dotLen = td; // from td=1000 to td=120000 // Getting DFCW-SW if (input(PIN_D7) == 0) { //DFCW SW on dfcw = 1; // DFCW ON dashLen = 1; // dash length is same as dot length for DFCW pauseLen = (dotLen / 2); } else if (opera == 0) { // QRSS dfcw = 0; if (input(PIN_D6) == 0){// 2or3dot_SW on dashLen = 3; pauseLen = dotLen; } else { dashLen = 2; // short dash for QRSS pauseLen = dotLen; } } } } // end of get_speed // --------------------------------------- void send_opera_one_symbol(int1 oneSymbol) //---------------------------------------- { if (oneSymbol == 0) { output_b(0b01000010); //dash lamp lit delay_s(dotLen); output_b(clear); } else send_dot(); } // end of send_opera_one_symbol() //========================================