// tab space = 4
/***********************************************************************/
/* */
/* FILE :main.c */
/* DATE :July 6, 2004 */
/* DESCRIPTION :Main Program */
/* */
/***********************************************************************/
#include "skp_bsp.h" // include SKP board support package
#include "skp_lcd.h" // include SKP LCD support package
#include <stdio.h>
#define TIME_CONFIG 0x40
/* 01000000 value to load into timer mode register
||||||||_ TMOD0,TMOD1: TIMER MODE SELECTED
||||||____ MR0: NO PULSE OUTPUT
|||||_____ MR1,MR2: GATE FUNCTION NOT SELECTED
|||_______ MR3: SET TO 0 IN TIMER MODE
||________ TCK0,TCK1: F DIVIDED BY 8 SELECTED */
#define FREQ_RESOLUTION (f1_CLK_SPEED/8)
#define TIME_RELOAD (unsigned int)(((FREQ_RESOLUTION)*5e-3) - 1) //5ms
#define BUTTON_TICK 500 // 500ms
#define DATA_TIMEOUT 1000 // 1 Seconds
#define CNTR_IPL 0x03 // TA2 priority interrupt level
#define INT2_IPL 0x02 //INT0 priority interrupt level
#define MAX_EVENTS 128 //
#define MENUS 9
#define MENU_Spy 8
#define MENU_Voltage 7
#define MENU_Detect 6
#define MENU_Analyse 5
#define MENU_Guess 4
#define MENU_Freq 1
#define MENU_Period 2
#define MENU_Events 3
#define MENU_Title 0
#define MODE_DETECT 0
#define MODE_ACQUIRE 1
#define MODE_ANALYSE 2
#define MODE_SPY 3
#define HISTROGRAM_MAX 12
#define ROLLOVER FALSE
#define NONE 0
#define ODD 1
#define EVEN 2
/* Defins for HW connections */
#define AN_F2 ad3 //p10_3 // Analog input for Female DB9 pin 2
#define AN_F3 ad2 //p10_2 // Analog input for Female DB9 pin 3
#define AN_M2 ad5 //p10_5 // Analog input for Male DB9 pin 2
#define AN_M3 ad4 //p10_4 // Analog input for Male DB9 pin 3
#define RXD_F p8_4 // RXD from Female DB9
#define RXD_M p8_3 // RXD from Male DB9
#define ENFA p7_3 // Enable Female tranciever, Normal
#define ENFB p7_5 // Enable Female tranciever, X over
#define ENMA p7_6 // Enable Male tranciever, Normal
#define ENMB p7_7 // Enable Male tranciever, X over
#define DDR_RXD_F pd8_4 // RXD from Female DB9
#define DDR_RXD_M pd8_3 // RXD from Male DB9
#define DDR_ENFA pd7_3 // Enable Female tranciever, Normal
#define DDR_ENFB pd7_5 // Enable Female tranciever, X over
#define DDR_ENMA pd7_6 // Enable Male tranciever, Normal
#define DDR_ENMB pd7_7 // Enable Male tranciever, X over
#define VOLTAGE_232 613 //613 = ((-5V/-10 + 2.5V)/ 5V )* 1023
unsigned int this_edge;
unsigned int last_edge;
unsigned int time_cnt;
unsigned int dtime_cnt;
unsigned int ovf_count;
unsigned char event_cnt; // Global event counter points to current event
unsigned char event_total;
long event[MAX_EVENTS]; // storage for transition times
unsigned char event_lvl[(MAX_EVENTS/8)+1]; //storage for bit levels
unsigned int event_bits[MAX_EVENTS]; // storage for transition times (in bits)
unsigned char display[2][9]; // variable to hold/construct display string
unsigned char menu;
unsigned char Update_LCD;
unsigned char waiting;
unsigned char reset_on_next;
unsigned char Mode;
unsigned char integer_fmt;
unsigned char histogram[HISTROGRAM_MAX];
unsigned int VoltageF;
unsigned int VoltageM;
char gParity;
char gDataBits;
char gStopBits=1;
char U0_in; // declare UART0 recieve variable
char U2_in; // declare UART2 recieve variable
char cables=0;
#define BAUDRATES 17
const unsigned long BAUD_TABLE[BAUDRATES] =
{110,300,600,1200,2400,4800,9600,
14400,19200,28800,38400,57600,76800,
115200,230400,256000};
#pragma INTERRUPT ta2_irq
#pragma INTERRUPT int0_irq
#pragma INTERRUPT int1_irq
#pragma INTERRUPT int2_irq
#pragma INTERRUPT U0rec_ISR
#pragma INTERRUPT U2rec_ISR
/* Prototype declarations */
void mcu_init(void); // MCU initialization
void main(void);
void LCD_Update(void);
void buttons(void);
void tmr_init(void);
void int_init(char channel);
void ta2_irq (void);
void int2_irq(void);
void U0rec_ISR (void);
void U2rec_ISR (void);
unsigned long int_period(void);
unsigned long int_baud(void);
float flt_period(void);
float flt_baud(void);
char guess_baud(void);
void bit_analysis(void);
void configurePins(void);
void StopMonitoring(void);
void StartMonitoring(void);
void text_write ( _far char * msg_string);
/******************************************************************************
Name : main
Parameters : none
Returns : nothing
Description: Main template
******************************************************************************/
void main(void)
{
integer_fmt = TRUE;
/* Initialize MCU
*/
mcu_init();
InitDisplay();
tmr_init();
DisplayString(LCD_LINE1 ,RENESAS_LOGO);
DisplayString(LCD_LINE2, __TIME__);
/* Detect RS232 Voltages and setup Pins
*/
Mode = MODE_DETECT;
configurePins();
menu=MENU_Detect;
time_cnt = 0;
dtime_cnt =0;
ovf_count = 0;
event_cnt=0;
event_total=0;
reset_on_next=TRUE;
ENABLE_LEDS; /* LED initialization for this demo - macro defined in skp_bsp.h */
ENABLE_SWITCHES;
while(1){
buttons();
if (Update_LCD){
Update_LCD = FALSE;
LCD_Update();
}
};
}
/*****************************************************************************
Name: configurePins
Parameters: none
Returns: none
Description: Checks the analog levels of rs232 pins to decide which are
TXD and RXD pins on each connector.
**************************************************************************** */
void configurePins(void)
{
int f2=512;
int f3=512;
int m2=512;
int m3=512;
cables =0;
while (cables==0){
// disable trancievers
DDR_ENFA = 1;
DDR_ENFB = 1;
DDR_ENMA = 1;
DDR_ENMB = 1;
ENFA = FALSE;
ENFB = FALSE;
ENMA = FALSE;
ENMB = FALSE;
//setup ADC
adcon0 = 0x90;
/*
10010000; ** Repeat sweep mode 0, soft trigger, fAD/2
||||||||______Analog input select bit 0
|||||||_______Analog input select bit 1
||||||________Analog input select bit 2
|||||_________A/D operation mode select bit 0
||||__________A/D operation mode select bit 1
|||___________Trigger select bit
||____________A/D conversion start flag
|_____________Frequency select bit 0 */
adcon1 = 0x3A;
/*
00111010; ** Scan AN0-AN%, 10-bit mode, fAD/2, Vref connected
||||||||______A/D sweep pin select bit 0
|||||||_______A/D sweep pin select bit 1
||||||________A/D operation mode select bit 1
|||||_________8/10 bit mode select bit
||||__________Frequency select bit 1
|||___________Vref connect bit
||____________External op-amp connection mode bit 0
|_____________External op-amp connection mode bit 1 */
adcon2 = 0x01;
/*
00000001; ** Sample and hold enabled, fAD/2
||||||||______AD conversion method select bit
|||||||_______AD input group select bit 0
||||||________AD input group select bit 1
|||||_________Reserved
||||__________Frequency select bit 2
|||___________Reserved
||____________Reserved
|_____________Reserved */
adst = 1; // Start a conversion here
while (adst); // wait for conversions to be done.
f2= AN_F2 & 0x03ff; // Mask off the upper 6 bits of the
// variable leaving only the result
// in the variable itself
f3= AN_F3 & 0x03ff; // Mask off the upper 6 bits of the
// variable leaving only the result
// in the variable itself
m2= AN_M2 & 0x03ff; // Mask off the upper 6 bits of the
// variable leaving only the result
// in the variable itself
m3= AN_M3 & 0x03ff; // Mask off the upper 6 bits of the
// variable leaving only the result
// in the variable itself
// enable correct trancievers by looking for negative voltages
if (f2>VOLTAGE_232){ // 573 = ((-3V/-10 + 2.5V)/ 5V )* 1023
DisplayString(LCD_LINE2 ,"DB9F ");
ENFA = TRUE;
ENFB = FALSE;
VoltageF = (f2-512) ;
}else if (f3>VOLTAGE_232){
DisplayString(LCD_LINE2 ,"DB9F Xvr");
ENFA = FALSE;
ENFB = TRUE;
VoltageF = (f3-512);
}else{ // no DB9F Detected
//DisplayString(LCD_LINE2 ,"No DB9F ");
}
if (m2>VOLTAGE_232){
DisplayString(LCD_LINE1, "DB9M ");
ENMA = FALSE;
ENMB = TRUE;
VoltageM = (m2-512) ;
}else if (m3>VOLTAGE_232){
DisplayString(LCD_LINE1, "DB9M Xvr");
ENMA = TRUE;
ENMB = FALSE;
VoltageM = (m3-512) ;
}else{ // no DB9M Detected
//DisplayString(LCD_LINE1, "No DB9M ");
}
// check number of cables and setup interrupts accordingly.
cables = (char) (ENFA + ENFB + ENMA + ENMB);
switch (cables){
case 0:
DisplayString(LCD_LINE1 ,"No cable");
DisplayString(LCD_LINE2, "detected");
int_init(0);
break;
case 1:
if (ENFA+ENFB){ // DB9F
int_init(2);
}else{ // DB9M
int_init(1);
}
break;
case 2:
int_init(2); // DB9F by default
break;
}
}
// while(!S2);
}
/*****************************************************************************
Name: buttons
Parameters: none
Returns: none
Description: Polls buttons and adjust apropriate gloabl variables
**************************************************************************** */
void buttons(void)
{
if (!waiting){
if (!S3){ // next
menu ++;
Update_LCD=TRUE;
waiting=TRUE;
}
// if (!S1){ // prev
// menu --;
// Update_LCD=TRUE;
// waiting=TRUE;
// }
if (!S2){ //enter
Update_LCD =TRUE;
Mode != Mode;
switch (menu % (MENUS)){
case MENU_Freq:
case MENU_Voltage:
case MENU_Period:
integer_fmt ^= TRUE;
waiting=TRUE;
break;
case MENU_Events:
event_cnt=0;
event_total =0;
//event[0]=-1;
waiting=TRUE;
break;
case MENU_Spy:
waiting=TRUE;
if (Mode == MODE_SPY){
Mode = MODE_ACQUIRE;
StopMonitoring();
}else{
Mode = MODE_SPY;
StartMonitoring();
}
//case MENU_Guess: //switch to analyse mode
//case MENU_Analyse:
}
}
}
}
/*****************************************************************************
Name: LCD_Update
Parameters: integer_fmt, show numbers as floats or integers
Returns: none
Description: display current data on LCD
**************************************************************************** */
void LCD_Update(void)
{
float error=0;
float temp=0;
float temp2=0;
LCD_write(CTRL_WR,LCD_CLEAR);
switch (menu % (MENUS)){
case MENU_Freq:
LCD_write(CTRL_WR,LCD_CLEAR);
if (integer_fmt){
sprintf(display[0],"%8u",int_baud());
}
else{
sprintf(display[0],"%8.1f",flt_baud());
}
DisplayString(LCD_LINE1 ,"Baud bps");
DisplayString(LCD_LINE2 ,display[0]);
break;
case MENU_Period:
temp=flt_period();
if (integer_fmt){
if (temp>1000)
sprintf(display[0],"%6umS",(temp/=1000));
else
sprintf(display[0],"%6uuS",int_period());
}
else{
if (temp>1000)
sprintf(display[0],"%6.1fms",(temp/=1000));
else
sprintf(display[0],"%6.1fus",flt_period());
}
DisplayString(LCD_LINE1 ,"Period ");
DisplayString(LCD_LINE2 ,display[0]);
break;
case MENU_Events:
LCD_write(CTRL_WR,LCD_CLEAR);
sprintf(display[0],"%d/%d",event_cnt,event_total);
DisplayString(LCD_LINE1 ,"Events");
DisplayString(LCD_LINE2 ,display[0]);
break;
case MENU_Title:
DisplayString(LCD_LINE1 ," Quick ");
DisplayString(LCD_LINE2 ,"Coms 0.1");
break;
case MENU_Guess:
LCD_write(CTRL_WR,LCD_CLEAR);
error = (1- ( (float) flt_baud() / (float) BAUD_TABLE[guess_baud()]) )*100;
if (error>0)
error = 100-error;
else
error +=100;
sprintf(display[0],"%8.0f",(float) BAUD_TABLE[guess_baud()]);
sprintf(display[1],"%7.2f%%",error);
DisplayString(LCD_LINE1 ,display[1]);
DisplayString(LCD_LINE2 ,display[0]);
break;
case MENU_Analyse:
Mode = MODE_ANALYSE;
bit_analysis();
break;
case MENU_Detect:
Mode = MODE_DETECT;
configurePins();
Mode = MODE_ACQUIRE;
break;
case MENU_Voltage:
temp = (float) VoltageF /20.0;
temp2= (float) VoltageM /20.0;
switch(cables){
case 0:
menu++; // skip to next menu
break;
case 1:
sprintf(display[0],"Voltage");
if (integer_fmt){
if (ENFA+ENFB){
sprintf(display[1],"%dV",VoltageF/20);
}else{
sprintf(display[1],"%dV",VoltageM/20);
}
}else{
if (ENFA+ENFB){
sprintf(display[1],"%2.2fV",temp);
}else{
sprintf(display[1],"%2.2fV",temp2);
}
}
break;
case 2:
if (integer_fmt){
sprintf(display[0],"M: %dV",VoltageM/20);
sprintf(display[1],"F: %dV",VoltageF/20);
}else{
sprintf(display[0],"M: %2.2fV",temp2);
sprintf(display[1],"F: %2.2fV",temp);
}
}
DisplayString(LCD_LINE1 ,display[0]);
DisplayString(LCD_LINE2 ,display[1]);
break;
case MENU_Spy:
DisplayString(LCD_LINE1 ,"Monitor");
if (Mode == MODE_SPY){
DisplayString(LCD_LINE2," Stop ");
}else{
DisplayString(LCD_LINE2," Start ");
}
break;
}
}
void int0_irq(void)
{
}
void int1_irq(void)
{
// capture timer reading
this_edge = ta2;
if (Mode == MODE_ACQUIRE){
// clear all data after a timeout
if (reset_on_next){
event_cnt=0;
event_total=0;
RED_LED = LED_OFF;
reset_on_next = FALSE;
}
// store timer value and overflows
if (!ovf_count){
event[event_cnt] = last_edge - this_edge;
}else if(ovf_count==1){
event[event_cnt] = last_edge + (TIME_RELOAD - this_edge);
}else{
event[event_cnt] = last_edge + (TIME_RELOAD - this_edge) + ((ovf_count-1) * TIME_RELOAD);
}
// record the level.
if (p8_3)
event_lvl[event_cnt/8] |= (1<<(char)(event_cnt%8));//set this bit
else
event_lvl[event_cnt/8] &= ~(1<<(char)(event_cnt%8));//clear this bit
event_cnt++;
// reset timmers
last_edge = this_edge;
ovf_count=0;
time_cnt=0;
dtime_cnt=0;
// let user know event has been captured
GRN_LED = LED_ON;
if (ROLLOVER){
if (event_cnt==MAX_EVENTS){ // reset pointer to start of buffer
event_cnt=0;
}
}else if (event_cnt==MAX_EVENTS){
Mode=MODE_ANALYSE;
}
if (event_total<MAX_EVENTS){ // move pointer to fil the buffer
event_total++;
}
}
}
void int2_irq(void)
{
// capture timer reading
this_edge = ta2;
if (Mode == MODE_ACQUIRE){
// clear all data after a timeout
if (reset_on_next){
event_cnt=0;
event_total=0;
RED_LED = LED_OFF;
reset_on_next = FALSE;
}
// store timer value and overflows
if (!ovf_count){
event[event_cnt] = last_edge - this_edge;
}else if(ovf_count==1){
event[event_cnt] = last_edge + (TIME_RELOAD - this_edge);
}else{
event[event_cnt] = last_edge + (TIME_RELOAD - this_edge) + ((ovf_count-1) * TIME_RELOAD);
}
// record the level.
if (p8_4)
event_lvl[event_cnt/8] |= (1<<(char)(event_cnt%8));//set this bit
else
event_lvl[event_cnt/8] &= ~(1<<(char)(event_cnt%8));//clear this bit
event_cnt++;
// reset timmers
last_edge = this_edge;
ovf_count=0;
time_cnt=0;
dtime_cnt=0;
// let user know event has been captured
GRN_LED = LED_ON;
if (ROLLOVER){
if (event_cnt==MAX_EVENTS){ // reset pointer to start of buffer
event_cnt=0;
}
}else if (event_cnt==MAX_EVENTS){
Mode=MODE_ANALYSE;
}
if (event_total<MAX_EVENTS){ // move pointer to fil the buffer
event_total++;
}
}
}
/*****************************************************************************
Name: ta2_irq()
Parameters: none
Returns: nothing
Description:Timer A2 Interrupt Service Routine. Interrupts every 5 msec,
toggles LED every second, and increments global'count'
**************************************************************************** */
void ta2_irq (void)
{
if (Mode == MODE_ACQUIRE){
ovf_count++;
}
if ((time_cnt += 5) > (BUTTON_TICK)){
YLW_LED ^= 1; // toggle LED ON-OFF-ON
if (GRN_LED == LED_ON){
GRN_LED = LED_OFF; // turn off green light
Update_LCD=TRUE;
}
if ( (menu % (MENUS))== MENU_Detect){
if (cables>0)
configurePins();
Update_LCD=TRUE;
}
time_cnt = 0;
waiting = FALSE; //clear button timer
}
if((dtime_cnt+=5)> (DATA_TIMEOUT)){
RED_LED =1;
reset_on_next = TRUE;
/* if (Mode == MODE_ANALYSE){
Mode = MODE_ACQUIRE;
}else if((Mode == MODE_ACQUIRE )&&(event_total>5)){//wehave data?
Mode = MODE_ANALYSE;
bit_analysis();
}*/
}
}
void alert(void){
GRN_LED = LED_ON;
RED_LED = LED_ON;
YLW_LED = LED_ON;
}
/*****************************************************************************
Name: tmr_init()
Parameters: none
Returns: nothing
Description: Setup timer A2 setup for 5msec interrupts. BCLK is set to f1
(divide by 1) in the ncrt0 startup file.
**************************************************************************** */
void tmr_init(){
ta2mr = TIME_CONFIG;
ta2 = (unsigned int)TIME_RELOAD ;
/* The recommended procedure for writing an Interrupt Priority Level is shown
below (see M16C datasheets under 'Interrupts' for details). */
DISABLE_IRQ // disable irqs before setting irq registers - macro defined in skp_bsp.h
ta2ic = CNTR_IPL;
ENABLE_IRQ // enable interrupts macro defined in skp_bsp.h
ta2s = 1; // start timer
}
/*****************************************************************************
Name: int2_init
Parameters: inturrup to use, 1,2 or 0 for none.
Returns: none
Description: Initialize the INT2 interrupt
**************************************************************************** */
void int_init(char channel)
{
ifsr2=1; // trigger INT2 on rising and falling edges;
ifsr1=1; // trigger INT1 on rising and falling edges;
DISABLE_IRQ // disable irqs before setting irq registers - macro defined in skp_bsp.h
switch (channel){
case 1:
int1ic= INT2_IPL;
int2ic = 0;
break;
case 2:
int1ic = 0;
int2ic= INT2_IPL;
break;
case 0:
int2ic = 0;
int1ic = 0;
}
ENABLE_IRQ // enable interrupts macro defined in skp_bsp.h
}
/*****************************************************************************
Name: min_event_time()
Parameters: none
Returns: Unsigned Long
Description: Calculates the smallest time between events
**************************************************************************** */
unsigned long min_event_time(void)
{
unsigned long period;
unsigned long temp;
char i;
period = event[0];
for (i=0;i<event_total;i++){
temp = event[i]; // ta2 is a down counter
if (temp<period)
period=temp;
}
return period;
}
/*****************************************************************************
Name: int_baud()
Parameters: none
Returns: unsigned integer containing largest baud rate from data
Description: calculates the baudrate of the shortest bit
**************************************************************************** */
unsigned long int_baud(void){
unsigned long period;
if (event_total<1){
return 0;
}
period = min_event_time();
if (period>0){
return (unsigned long) ((unsigned long) FREQ_RESOLUTION / period) ;
}
else{
return 0;
}
}
/*****************************************************************************
Name: flt_baud()
Parameters: none
Returns: float containing largest baud rate from data
Description: calculates the baudrate of the shortest bit
**************************************************************************** */
float flt_baud(void){
unsigned long period;
if (event_total<1){
return 0;
}
period = min_event_time();
if (period>0){
return (float) FREQ_RESOLUTION / (float) period ;
}
else{
return 0;
}
}
/*****************************************************************************
Name: int_period()
Parameters: none
Returns: Pulse width in uS
Description: calculates the minumum period between any two events
**************************************************************************** */
unsigned long int_period(void){
unsigned long long out;
unsigned long long period;
if (event_total<1){
return 0;
}
period = min_event_time();
period *= 1000000; // scale to uS
out = (period / FREQ_RESOLUTION );
return (unsigned long)out ; // return period
}
/*****************************************************************************
Name: flt_period()
Parameters: none
Returns: Pulse width in uS
Description: calculates the minumum period between any two events
**************************************************************************** */
float flt_period(void){
float out;
if (event_total<1){
return 0;
}
out = min_event_time();
out *= 1000000;
out /= FREQ_RESOLUTION ;
return out ; // return period
}
/*****************************************************************************
Name: guess_baud
Parameters: none
Returns: char index to B
Description:
**************************************************************************** */
char guess_baud(void){
char guess,best=0;
unsigned long actual;
float diff,last;
if (BAUDRATES<1){
return 0;
}
actual = int_baud();
if (actual > BAUD_TABLE[0]){
last = (actual - BAUD_TABLE[0]);
}else{
last = (BAUD_TABLE[0] - actual);
}
for (guess=1;guess<BAUDRATES;guess++){
if (actual > BAUD_TABLE[guess]){
diff = (actual - BAUD_TABLE[guess]);
}else{
diff = (BAUD_TABLE[guess] - actual);
}
if (diff<last){
last = diff;
best = guess;
}
}
return best;
}
/*****************************************************************************
Name: bit_analysis
Parameters: none
Returns: none
Description: analyses the event memory to estimate encodeing scheme.
**************************************************************************** */
void bit_analysis(void)
{
float period ;
float calc;
float error;
unsigned char i,j,k;
unsigned char score[13],bitval;
unsigned char word[13],wordlength;
unsigned int bitLength, bitsReceived,bitsTotal,wordsTotal,wordsPossible;
unsigned char parityBit,parity, even,odd; // counters for parity scoring
// convert events to bit time (rounding up to nearest period)
period = FREQ_RESOLUTION/BAUD_TABLE[guess_baud()];
for (i=0;i<event_total;i++){
calc = ((float) event[i]+(period/2))/period;
if (calc > 12 )
calc =1; //filter large pauses
event_bits[i]=calc;
}
// produce histogram for statistical analysis
for(i=0;i<HISTROGRAM_MAX;i++)
histogram[i]=0;
for (i=0;i<event_total;i++){
if (event_bits[i] <HISTROGRAM_MAX)
histogram[event_bits[i]]++;
else
histogram[0]++;
}
bitsTotal=0;
for(i=0;i<HISTROGRAM_MAX;i++)
bitsTotal+=(histogram[i]*i);
//check start stop combinations 1 stop bit
for (bitLength=7;bitLength<13;bitLength++){
bitsReceived = 0;
score[bitLength]=0;
for(i=1;i<event_total;i++){
bitsReceived += event_bits[i];
if (bitsReceived == (bitLength)) {//this is a single stop bit
if (!(event_lvl[i/8] & (1<<i%8))) {// stop bit is set
score[bitLength]++; // add one to the score
bitsReceived=0;
}else{// we've got exact bits but wrong level?? do we go forward or back??
bitsReceived=0;
i++;// try starting from next bit
//i-=2;// try starting next word from previous bit.
}
}
if (bitsReceived > (bitLength)) {// overran a stop bit
// this should find next/last 0 bit
if ((event_lvl[i/8] & (1<<i%8)))
i++;// try starting next word from previous bit.
bitsReceived=0;
// break;
}
}
}
// analyse best score/ total bits recieved.
// find best bit rate
j=6;
score[j]=0;
for (i=7;i<13;i++){
if (score[i]>score[j]){
j=i;
}
}
LCD_write(CTRL_WR,LCD_CLEAR);
wordsPossible=(bitsTotal/j);
wordsTotal=score[j];
wordlength=j;
//error = (wordsTotal*100)/wordsPossible;
if (j>6){//found a winner
sprintf(display[0],"%d words",wordsTotal);
sprintf(display[1],"%d bit",j);
DisplayString(LCD_LINE1 ,display[0]);
DisplayString(LCD_LINE2 ,display[1]);
//
// analyse Parity
//
parityBit=wordlength-2;
bitsReceived=0;
parity=0;
even=0;
odd=0;
for(i=1;i<event_total;i++){
if (event_bits[i]>12)
event_bits[i]=1; // blast long pauses
bitval = ((event_lvl[(i-1)/8] & (1<<(i-1)%8))!=0);// get pulse value
for (k=0; k<event_bits[i]; k++){ // expand out into individual bits
word[k+bitsReceived]= bitval;
parity += word[k+bitsReceived]; // keep track of parity
}
bitsReceived += event_bits[i];
if (bitsReceived == (wordlength)) {//this is a single stop bit
parity -= word[parityBit] + word[wordlength-1]; //don't count the stop bit and parity bit
// check for parity bit?
if (parity & 0x01){ // odd number of ones
even += word[parityBit];// 1 is correct
odd += (1-word[parityBit]);// 0 is correct
}else{
even += (1-word[parityBit]);// 0 is correct
odd += word[parityBit];// 1 is correct
}
bitsReceived=0;
parity=0;
}
if (bitsReceived > (wordlength)) {// overran a stop bit, pause between chars??
// this should find next/last 0 bit
if (((char)event_lvl[i/8] & (1<<i%8)))
i++;// try starting next word from previous bit.
bitsReceived=0;
// alert();
// while(S2);
break;
}
}
if (even == wordsTotal){ //even parity
//Databits = wordLength - 3 // assuming 1 start 1 stop 1 parity
sprintf(display[1],"%d E 1 ",wordlength - 3);
DisplayString(LCD_LINE2 ,display[1]);
gParity=EVEN;
gDataBits=wordlength - 3;
gStopBits=1;
}else if (odd == wordsTotal){ // odd parity
sprintf(display[1],"%d O 1 ",wordlength - 3);
DisplayString(LCD_LINE2 ,display[1]);
gParity= ODD;
gDataBits=(char) wordlength - 3;
gStopBits=1;
}else if( ((odd+even)==wordsTotal) &&(wordsTotal==wordsPossible)){// guess no parity
sprintf(display[1],"%d N 1 ",wordlength - 2);
DisplayString(LCD_LINE2 ,display[1]);
gParity= NONE;
gDataBits= wordlength - 2;
gStopBits=1;
}
} else{
DisplayString(LCD_LINE1 ,"NoMATCH");
// DisplayString(LCD_LINE2 ,display[0]);
}
// waiting=TRUE;
// while(waiting);
// while(S2);
waiting=TRUE;
Mode = MODE_ACQUIRE;
}
/*****************************************************************************
Name: uart0_init
Parameters: None
Returns: None
Description: Uart0 initialization - 19200 baud, 8 data bits, 1 stop bit, no parity.
*****************************************************************************/
void uart0_init(long baudRate0,char data,char parity,char stop) {
char temp;
u0brg = (unsigned char)(((f1_CLK_SPEED/16)/baudRate0)-1); // set UART0 bit rate generator
/*
bit rate can be calculated by:
bit rate = ((BRG count source / 16)/baud rate) - 1
in this example: BRG count source = f1 (12MHz - Xin in SKP16C62P)
baud rate = 19200
bit rate = ((12MHz/16)/19200) - 1 = 38
** one has to remember that the value of BCLK does not affect BRG count source */
ucon = 0x00; // UART transmit/receive control register 2
/*
00000000; // transmit irq not used
||||||||______UART0 transmit irq cause select bit, U0IRS
|||||||_______UART1 transmit irq cause select bit, U1IRS
||||||________UART0 continuous receive mode enable bit, U0RRM - set to 0 in UART mode
|||||_________UART1 continuous receive mode enable bit, U1RRM - set to 0 in UART mode
||||__________CLK/CLKS select bit 0, CLKMD0 - set to 0 in UART mode
|||___________CLK/CLKS select bit 1, CLKMD1 - set to 0 in UART mode
||____________Separate CTS/RTS bit, RCSP
|_____________Reserved, set to 0 */
u0c0 = 0x10; // UART0 transmit/receive control register 1
/*
00010000; // f1 count source, CTS/RTS disabled, CMOS output
||||||||______BRG count source select bit, CLK0
|||||||_______BRG count source select bit, CLK1
||||||________CTS/RTS function select bit, CRS
|||||_________Transmit register empty flag, TXEPT
||||__________CTS/RTS disable bit, CRD
|||___________Data output select bit, NCH
||____________CLK polarity select bit, CKPOL - set to 0 in UART mode
|_____________Transfer format select bit, UFORM - set to 0 in UART mode */
u0c1 = 0x00; // UART0 transmit/receive control register 1
/*
00000000; // disable transmit and receive
||||||||______Transmit enable bit, TE
|||||||_______Transmit buffer empty flag, TI
||||||________Receive enable bit, RE
|||||_________Receive complete flag, RI
||||__________Reserved, set to 0
|||___________Reserved, set to 0
||____________Data logic select bit, U0LCH
|_____________Error signal output enable bit, U0ERE */
temp =0x00;
if (parity ==EVEN)
temp |= 0x60;
else if(parity ==ODD)
temp |= 0x40;
if (stop==2)
temp |= 0x10;
switch (data){
case 7:
temp |= 4;
break;
case 8:
temp |= 5;
break;
case 9:
temp |= 6;
break;
}
u0mr = temp; // UART0 transmit/receive mode register, not reversed
/*
00000101; // 8-bit data, internal clock, 1 stop bit, no parity
||||||||______Serial I/O Mode select bit, SMD0
|||||||_______Serial I/O Mode select bit, SMD1
||||||________Serial I/O Mode select bit, SMD2
|||||_________Internal/External clock select bit, CKDIR
||||__________Stop bit length select bit, STPS
|||___________Odd/even parity select bit, PRY
||____________Parity enable bit, PRYE
|_____________TxD, RxD I/O polarity reverse bit */
u0tb = u0rb; // clear UART0 receive buffer by reading
u0tb = 0; // clear UART0 transmit buffer
DISABLE_IRQ // disable irqs before setting irq registers
s0ric = 0x04; // Enable UART0 receive interrupt, priority level 4
ENABLE_IRQ // Enable all interrupts
u0c1 = 0x05; // UART0 transmit/receive control register 1
/*
00000101; // enable transmit and receive
||||||||______Transmit enable bit, TE
|||||||_______Transmit buffer empty flag, TI
||||||________Receive enable bit, RE
|||||_________Receive complete flag, RI
||||__________Reserved, set to 0
|||___________Reserved, set to 0
||____________Data logic select bit, U0LCH
|_____________Error signal output enable bit, U0ERE */
}
/*****************************************************************************
Name: uart2_init
Parameters: None
Returns: None
Description: Uart0 initialization - 19200 baud, 8 data bits, 1 stop bit, no parity.
*****************************************************************************/
void uart2_init(long baudRate0,char data,char parity,char stop) {
char temp;
u2brg = (unsigned char)(((f1_CLK_SPEED/16)/baudRate0)-1); // set UART0 bit rate generator
/*
bit rate can be calculated by:
bit rate = ((BRG count source / 16)/baud rate) - 1
in this example: BRG count source = f1 (12MHz - Xin in SKP16C62P)
baud rate = 19200
bit rate = ((12MHz/16)/19200) - 1 = 38
** one has to remember that the value of BCLK does not affect BRG count source */
ucon = 0x00; // UART transmit/receive control register 2
/*
00000000; // transmit irq not used
||||||||______UART0 transmit irq cause select bit, U0IRS
|||||||_______UART1 transmit irq cause select bit, U1IRS
||||||________UART0 continuous receive mode enable bit, U0RRM - set to 0 in UART mode
|||||_________UART1 continuous receive mode enable bit, U1RRM - set to 0 in UART mode
||||__________CLK/CLKS select bit 0, CLKMD0 - set to 0 in UART mode
|||___________CLK/CLKS select bit 1, CLKMD1 - set to 0 in UART mode
||____________Separate CTS/RTS bit, RCSP
|_____________Reserved, set to 0 */
u2c0 = 0x10; // UART0 transmit/receive control register 1
/*
00010000; // f1 count source, CTS/RTS disabled, CMOS output
||||||||______BRG count source select bit, CLK0
|||||||_______BRG count source select bit, CLK1
||||||________CTS/RTS function select bit, CRS
|||||_________Transmit register empty flag, TXEPT
||||__________CTS/RTS disable bit, CRD
|||___________Data output select bit, NCH
||____________CLK polarity select bit, CKPOL - set to 0 in UART mode
|_____________Transfer format select bit, UFORM - set to 0 in UART mode */
u2c1 = 0x00; // UART0 transmit/receive control register 1
/*
00000000; // disable transmit and receive
||||||||______Transmit enable bit, TE
|||||||_______Transmit buffer empty flag, TI
||||||________Receive enable bit, RE
|||||_________Receive complete flag, RI
||||__________Reserved, set to 0
|||___________Reserved, set to 0
||____________Data logic select bit, U0LCH
|_____________Error signal output enable bit, U0ERE */
temp =0x00;
if (parity ==EVEN)
temp |= 0x60;
else if(parity ==ODD)
temp |= 0x40;
if (stop==2)
temp |= 0x10;
switch (data){
case 7:
temp |= 4;
break;
case 8:
temp |= 5;
break;
case 9:
temp |= 6;
break;
}
u2mr = temp; // UART0 transmit/receive mode register, not reversed
/*
00000101; // 8-bit data, internal clock, 1 stop bit, no parity
||||||||______Serial I/O Mode select bit, SMD0
|||||||_______Serial I/O Mode select bit, SMD1
||||||________Serial I/O Mode select bit, SMD2
|||||_________Internal/External clock select bit, CKDIR
||||__________Stop bit length select bit, STPS
|||___________Odd/even parity select bit, PRY
||____________Parity enable bit, PRYE
|_____________TxD, RxD I/O polarity reverse bit */
u2tb = u2rb; // clear UART0 receive buffer by reading
u2tb = 0; // clear UART0 transmit buffer
DISABLE_IRQ // disable irqs before setting irq registers
s2ric = 0x04; // Enable UART0 receive interrupt, priority level 4
ENABLE_IRQ // Enable all interrupts
u2c1 = 0x05; // UART0 transmit/receive control register 1
/*
00000101; // enable transmit and receive
||||||||______Transmit enable bit, TE
|||||||_______Transmit buffer empty flag, TI
||||||________Receive enable bit, RE
|||||_________Receive complete flag, RI
||||__________Reserved, set to 0
|||___________Reserved, set to 0
||____________Data logic select bit, U0LCH
|_____________Error signal output enable bit, U0ERE */
}
void uart0_stop(void){
u0c1 = 0x00; // UART0 transmit/receive control register 1
}
void uart2_stop(void){
u2c1 = 0x00; // UART0 transmit/receive control register 1
}
/*****************************************************************************
Name:
Parameters: none
Returns: none
Description:
**************************************************************************** */
void StartMonitoring(void)
{
uart0_init(BAUD_TABLE[guess_baud()],gDataBits,gParity,gStopBits);
uart2_init(BAUD_TABLE[guess_baud()],gDataBits,gParity,gStopBits);
text_write("Quick Coms: RS232 analyser\r\n");
}
void StopMonitoring(void)
{
uart0_stop();
uart2_stop();
menu = MENU_Detect;
configurePins;
}
/*****************************************************************************
Name: UART0 Receive Interrupt Routine
Parameters: none
Returns: none
Description: Interrupt routine for UART0 receive
Reads character received from keyboard and stores U0_in variable
*****************************************************************************/
void U0rec_ISR(void){
if (Mode= MODE_SPY){
while(ri_u0c1 == 0); // make sure receive is complete
U0_in = (char) u0rb; // read in received data
while(ti_u0c1 == 0); //echo on u0
u0tb = U0_in;
}
}
/*****************************************************************************
Name: UART2 Receive Interrupt Routine
Parameters: none
Returns: none
Description: Interrupt routine for UART0 receive
Reads character received from keyboard and stores U0_in variable
*****************************************************************************/
void U2rec_ISR(void){
if (Mode= MODE_SPY){
while(ri_u2c1 == 0); // make sure receive is complete
U2_in = (char) u2rb; // read in received data
while(ti_u0c1 == 0); //echo on u0
u0tb = U2_in;
}
}
/*****************************************************************************
Name: text_write
Parameters: msg_string -> the text string to output
Returns: none
Description: The following sends a text string to the terminal program
*****************************************************************************/
void text_write ( _far char * msg_string)
{
char i;
for (i=0; msg_string[i]; i++){ // This loop reads in the text string and
while(ti_u0c1 == 0); // puts it in the UART 0 transmit buffer
u0tb = msg_string[i];
}
}