📄 user.c
字号:
/*********************************************************************
* FileName: user.c
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 2.30.01+
* Company: sprut
* Copyright: 2007-2010 Joerg Bredendiek (sprut)
*
*
********************************************************************/
/*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*** Pinbelegung*************************************************************
*
* PORTA 0 Comp-Eingang (-) (mit RA2 verbinden)
* 1 ADC-Eingang
* 2 Uref-Ausgang (mit RA0 verbinden)
* 3 Comp-Eingang (+) mit miniadsb verbinden
* 4 Comp-Ausgang -> RC0
*
* PORTB 0 SWITCH remote
* 1 SWITCH time
* 2 SWITCH CRC
* 3 PWM2 Ausgang
* 4 SWITCH DF17
* 5..7 TEST-LEDs
*
* PORTC 0 TTL-Eingang (mit PA4 verbinden)
* 1 LED HDR
* 2 LED FRM
* 4 USB D-
* 5 USB D+
*
*****************************************************************************/
//#define NO_CDC //MCD
//#define CDC_HEX // nonsens
#define CDC_ASCII
/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include <usart.h>
#include "system\typedefs.h"
#include "system\usb\usb.h"
#include "io_cfg.h" // I/O pin mapping
#include "delays.h"
//#include "system\interrupt\interrupt.h"
#include "user\user.h"
#include "user\adsbin.h"
#include "user\agc.h"
#include "timers.h"
#include "pwm.h"
/** V A R I A B L E S ********************************************************/
#pragma udata
#ifdef CDC_ASCII
char input_buffer[64];
byte rgetascii;
byte hb_counter = 0;
byte ib_counter = 0;
char asciiKor = 0;
byte befehl = 0; //eine gueltige Befehlszeile wurde empfangen
byte wertgueltig = 0; //steht in rgetascii schon was?
byte zeileangefangen = 0; //kam schon mal ein #?
#endif //CDC_ASCII
byte counter;
byte counter2;
DATA_PACKET dataPacket;
byte adsb[14]; // fuer den aktuell zu empfangenen Frame
byte Flags;
byte Zeit;
byte Lang;
byte adsbLoopL;
byte adsbLoopH;
char send_RAW;
DWORD CRC;
byte ADSB_Mode;
BYTE Time; // puffer
BYTE Time0;
BYTE Time1;
BYTE Time2;
BYTE Time3;
byte TimeCode = 0;
byte T2_PS;
byte pwm_period;
unsigned int pwm_dutycycle;
byte agc_offset = 100; // ref soll 100mV ueber pegel sein
byte agc_mode = 1; // 1-on 0-off
/** D E C L A R A T I O N S **************************************************/
#pragma code
//Aufruf nach Reset
void UserInit(void)
{
// alles analoge initialisieren
agc_init();
//PWM fuer Referenzspannungserzeugung
pwm_init();
//interne Uhr, Schritt = 21.33333 us = 64us/3
TMR0H = 0;
TMR0L = 0;
T0CON = 0x87; //timer0, 16 bit, 12MHz/256 = 46875 Hz, Ueberlauf nach 1.3981 s
INTCONbits.TMR0IF = 0;
Time0._byte = 0;
Time1._byte = 0;
Time2._byte = 0;
Time3._byte = 0;
TimeCode = 0; // Zeitmarken senden?
// init pins
TRISA = 0xEF; // RA4 ist output fuer Comparator
TRISB = 0x17; // RB5..7 Test-LEDs, RB3-PWM 0001 0111
TRISC = 0xF9; // RC1, RC2 -output for LEDs
INTCON2bits.NOT_RBPU = 0; // pull-up fuer PORTB einschalten
PORTA = 0;
PORTB = 0;
PORTC = 0;
send_RAW = 0;
CRC._dword = 0;
ADSB_Mode = 0;
}//end UserInit
/******************************************************************************
* Function: void ProcessIO(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This function is a place holder for other user routines.
* It is a mixture of both USB and non-USB tasks.
*
* Note: None
*****************************************************************************/
void ProcessIO(void)
{
// User Application USB tasks
if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) return;
ServiceRequests();
}//end ProcessIO
// A S C I I *****************************************************************************
#ifdef CDC_ASCII
// ermittelt, ob es sich bei einem Zeichen um ein Trennzeichen handelt
// ermittle den noetigen Wert fuer asciiKor
// alles ausser 0..9/a..f/A.F sind trennzeichen
// aus A..F/a..F wird 10..15 (0x0A..0x0F)
// input: zeichen
// output: -1 : Trennzeichen
// -2 : Zeilenende
// -3 : Zeilenanfang
// 0 : ASCII-Zeichen
byte trennzeichen(char zeichen)
{
if (zeichen== '#') return -3; //SOL
if (zeichen==0x00) return -2; //EOL
if (zeichen==0x0A) return -2; //EOL
if (zeichen==0x0D) return -2; //EOL
asciiKor = 0x00;
if (zeichen < '0') return -1; // .. /
if (zeichen <='9') // 0 .. 9
{
asciiKor = '0';
return 0;
}
if (zeichen < 'A') return -1; // : .. @
if (zeichen <='F') // A .. F
{
asciiKor = 'A'-10;
return 0;
}
if (zeichen < 'a') return -1; // G .. '
if (zeichen <='f') // a .. f
{
asciiKor = 'a'-10;
return 0;
}
return -1; // g ..
} //trennzeichen
// input_buffer[ib_counter] steht auf letztem Trennzeichen
// input_buffer lesen bis zum n鋍hsten Trennzeichen
// wandeln in Hex -> rgetascii
// bei Zeilenende -1
byte getascii(void)
{
rgetascii = 0;
while (trennzeichen(input_buffer[ib_counter]) == -1) ib_counter++; // trennzeichen 黚ersprinegn
if (trennzeichen(input_buffer[ib_counter]) == -2) return (-1); //EOL
// if (ib_counter >= mCDCGetRxLength()) return (-1); //EOL
while (trennzeichen(input_buffer[ib_counter]) == 0)
{
rgetascii <<= 4;
rgetascii += (input_buffer[ib_counter] - asciiKor);
ib_counter++;
}
return(0);
} //getascii
//input_buffer -> dataPacket
// #xx-xx-xx-xx-xx-xx
// einlesen der per RS232 empfangenen Zeichen
// beim Zeilenende wird befehl=1 gesetzt
void AsciiToHexParser(void)
{
for (ib_counter = 0; ib_counter < mCDCGetRxLength(); ib_counter++)
{
switch (trennzeichen(input_buffer[ib_counter]))
{
case -3: //zeilenanfang
for (hb_counter = 0; hb_counter < 64; hb_counter++)
dataPacket._byte[hb_counter] = 0;
hb_counter = 0;
befehl = 0;
rgetascii = 0;
wertgueltig = 0;
zeileangefangen = 1;
break;
case -2: //zeilenende
if (wertgueltig == 1)
{
dataPacket._byte[hb_counter] = rgetascii;
hb_counter++;
wertgueltig = 0;
}
rgetascii = 0;
if (zeileangefangen == 1) befehl = 1;
break;
case -1: //trennzeichen
if (wertgueltig == 1)
{
dataPacket._byte[hb_counter] = rgetascii;
hb_counter++;
wertgueltig = 0;
}
rgetascii = 0;
break;
case 0: //ziffer
rgetascii <<= 4;
rgetascii += (input_buffer[ib_counter] - asciiKor);
wertgueltig = 1;
break;
} //switch
}
} //AsciiToHexParser
// wandelt Zahl (0..15) in Zeichen ('0' .. 'A')
char zeichen( byte wert)
{
if (wert < 10) return (wert+'0');
return (wert-10+'A');
}
//dataPacket -> input_buffer
void HexToAsciiParser(void)
{
char puffer;
for (ib_counter= 0; ib_counter<64; ib_counter++)
input_buffer[ib_counter] = 0;
ib_counter = 1;
hb_counter = 0;
input_buffer[0] = '@';
for (hb_counter= 0; hb_counter<16; hb_counter++)
{
puffer = dataPacket._byte[hb_counter];
input_buffer[ib_counter] = zeichen((puffer & 0xF0) >> 4);
ib_counter++;
input_buffer[ib_counter] = zeichen( puffer & 0x0F);
ib_counter++;
input_buffer[ib_counter] = '-';
ib_counter++;
}
input_buffer[ib_counter] = 0x0A;
ib_counter++;
input_buffer[ib_counter] = 0x0D;
ib_counter++;
input_buffer[ib_counter] = 0x00;
counter = ib_counter;
}
#endif //CDC_ASCII
// Kommando auswerten und ausf黨ren **********************
void ServiceRequests(void)
{
byte index;
word big_counter;
WORD uidaten;
// wurde via USB etwas empfangen?
#ifdef NO_CDC // MCD Treiber
if(USBGenRead((byte*)&dataPacket,sizeof(dataPacket))) //byte USBGenRead(byte *buffer, byte len) //normal
#endif //NO_CDC
#ifdef CDC_HEX //CDC-Treiber im HEX-Format (nonsens)
if(getsUSBUSART((char*)&dataPacket,sizeof(dataPacket))) //byte getsUSBUSART(char *buffer, byte len) //cdc hex
#endif //CDC_HEX
#ifdef CDC_ASCII // CDC Treiber
if(getsUSBUSART((char*)&input_buffer,sizeof(input_buffer))) //byte getsUSBUSART(char *buffer, byte len) //cdc ascii
AsciiToHexParser();
if (befehl==1)
#endif //CDC_ASCII
{
counter = 0;
#ifdef CDC_ASCII
befehl = 0;
#endif //CDC_ASCII
switch(dataPacket.CMD) //das ist in Assembler ein riesieger Sprungverteiler
{
// eine Kennummer aus dem PIC auslesen
case READ_VERSION:
//dataPacket._byte[1] is len
dataPacket._byte[2] = MINOR_VERSION; // Firmware-Version steht in user.h
dataPacket._byte[3] = MAJOR_VERSION; // Hardware-Version
counter=0x04;
break;
// adsb-Datenpaket empfangen
case READ_DATA:
// 2 - 2=fehler, 1=112Bits, 0=56bits
// 3..16 - Daten
// ADSB-Empfang
//adsbLoop = 255;
adsbLoopH = dataPacket._byte[1]; // 100 = 15 ms
adsbLoopL = 0;
dataPacket._byte[2] = 2; // fehler
LATBbits.LATB7 = 1; // LED an
if (!adsb_in())
{
dataPacket._byte[2] = Lang;
for (counter=0; counter<14; counter++) dataPacket._byte[counter+3] = adsb[counter];
}
LATBbits.LATB7 = 0; // LED aus
counter = 17;
break;
// nur DEBUG
case SYS_KEY:
adsb_CRC();
dataPacket._byte[1] = CRC.byte2;
dataPacket._byte[2] = CRC.byte1;
dataPacket._byte[3] = CRC.byte0;
counter = 4;
break;
// betriebsart einstellen
// 0 - OFF
// 1 - reserved
// 2 - all received data
// 3 - only DF17
// 4 - only DF17 + CRC-ok
case SET_MODE:
ADSB_Mode = dataPacket._byte[1] & 0x0F;
TimeCode = (dataPacket._byte[1] & 0x10); // Zeitmarken senden
counter = 2;
break;
// AGC automatische Pegeleinstellung
case SET_OFFSET:
agc_offset = dataPacket._byte[3]; // offset in mV
agc_mode = dataPacket._byte[2]; // 1= agc-on 0=agc-off
// offset im EEPROM auf 0x00 speichern
EECON1bits.EEPGD = 0; /* WRITE step #1 */
EECON1bits.WREN = 1; /* WRITE step #2 */
EEADR = 0x00; /* WRITE step #3 */
EEDATA = agc_offset; /* WRITE step #4 */
EECON2 = 0x55; /* WRITE step #5 */
EECON2 = 0xaa; /* WRITE step #6 */
EECON1bits.WR = 1; /* WRITE step #7 */
while (!PIR2bits.EEIF) /* WRITE step #8 */
;
PIR2bits.EEIF = 0; /* WRITE step #9 */
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -