CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

2 serials problem.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ssaguiar



Joined: 02 Nov 2003
Posts: 11
Location: Brazil

View user's profile Send private message Visit poster's website

2 serials problem.
PostPosted: Mon Mar 01, 2010 9:31 pm     Reply with quote

Dear friends:

I am trying to implement a data logger (gps and adc), and, to achieve this, I need to:
-In the gps side, I use the hardware usart with interrupts;
-In the other side, i need to send/receive data thru software serial routines;

The problem is that, after some time working (some minutes), the system stops to work with the hardware usart stuff.
The code is below.
Can somebody indicate if this approach is the best for this kind of project and if somebody can give me some clue about this problem because I really am losing my last hairs.
Explanation of usart interrupts use:
When my state machine's enters the STATE_FUEL_READ state it means that it's time for the system to read the gps data and the adc stuff, so it enables the usart interrupt.
When the usart interrupt ends the gps data capture, the new state is STATE_GPS_REC. Here, we know that the gps data is ready to be processed and we can also capture and process the adc sensors, so we disable the usart interrupt and call the process routine which will capture and display data in the glcd.
I just don't know why the usart interrupt locks up after some time.

The code is:
Code:


/************************************************************************
****                      Controle Combustivel                       ****
****                                                                 ****
****                Rs-232 parameters : 9600,8,n,1                   ****
****                                                                 ****
*************************************************************************
****                                                                                            ****
*************************************************************************
*************************************************************************
****           _        _    _         _    _    _    _    _         ****
****          | |   |   _|   _|  |_|  |_   |_     |  |_|  |_|        ****
****          |_|   |  |_    _|    |   _|  |_|    |  |_|   _|        ****
****                                                                 ****
************************************************************************/

#include <18F4620.h>
#device ADC=10
#device PASS_STRINGS = IN_RAM
//#DEVICE HIGH_INTS=TRUE
#zero_ram
#case

/************************************************************************/

#FUSES NOWDT               // NO Watch Dog Timer
#FUSES WDT128                   // Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       // High speed Osc (> 4mhz)
//#FUSES H4                  // Multiply by 4?
#FUSES NOPROTECT                // Code not protected from reading
#FUSES NOIESO                   // Internal External Switch Over mode disabled
#FUSES NOBROWNOUT               // No brownout reset
#FUSES BORV21                   // Brownout reset at 2.1V
#FUSES PUT                      // Power Up Timer
#FUSES NOCPD                    // No EE protection
#FUSES STVREN                   // Stack full/underflow will cause reset
#FUSES NODEBUG                  // No Debug mode for ICD
#FUSES NOLVP                    // No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    // Program memory not write protected
#FUSES NOWRTD                   // Data EEPROM not write protected
#FUSES NOEBTR                   // Memory not protected from table reads
#FUSES NOCPB                    // No Boot Block code protection
#FUSES NOEBTRB                  // Boot block not protected from table reads
#FUSES NOWRTC                   // Configuration not registers write protected
#FUSES NOWRTB                   // Boot block not write protected
#FUSES NOFCMEN                  // Fail-safe clock monitor disabled
#FUSES NOXINST                  // Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOPBADEN                 // PORTB pins are not configured as analog input channels on RESET
#FUSES LPT1OSC                  // Timer1 configured for low-power operation
#FUSES MCLR                     // Master Clear pin enabled

#use delay(clock=20000000)
//#use delay(clock=48M, oscillator=20M)
//#use i2c ( master, scl=EEPROM_SCL, sda=EEPROM_SDA )
#use rs232(baud=4800, parity=N, bits=8, stop=1, xmit=PIN_C6, rcv=PIN_C7, STREAM=GPS, ERRORS)
#use rs232(baud=19200, parity=N, bits=8, stop=1, xmit=PIN_B6, rcv=PIN_B7, STREAM=RADIO)

/*****************************************************************************/
// ROM definitions

#ROM int8 0xf00000 =                // Start of EEPROM address.
{
   0,1,                     // Time between captures, in minutes byte 0 * 256 + byte 1 (max 65535).
   'L','Y','Q','4','1','3','7',0   // Vehicle's ID (7 chars).
}

#define LOCALID_ADD         2      // Start at ROM Address 2
#define ROM_Localid_Size   8      // 7 for id + trailling 0.


/*****************************************************************************/
// Includes

#include      <stdlib.h>
#include      <241025.c>
#include      "pcf8583.c"
#include      "vt100.h"

/*****************************************************************************/
// System defines

#define   _HAS_GLCD_         // Use Graph LCD?
//#undef   _HAS_GLCD_      // No.

#define PCF8583_SDA             PIN_C4
#define PCF8583_SCL             PIN_C3

#define EEPROM_SDA              PIN_C4
#define EEPROM_SCL              PIN_C3

#define BUZZER                  PIN_C2
#define BUTTON_1                PIN_E0
#define RX_IN                   PIN_C7
#define LED_OK                  PIN_E1
#define LED_SYS                 PIN_E2

#define ON                      1
#define OFF                     0
#define HIGH                    1
#define LOW                     0
#define TRUE                    1
#define FALSE                   0

#define EOF                     0x00
#define COMMA                   ','
#define SPACE                   ' '
#define PERIOD                  '.'
#define DOLLAR                  '$'
#define CR                      13

#define GPRMC_CODE              75
#define RX_BUFFER_SIZE          80

#define VDD                     14.00
#define EEPROM_BYTE_SIZE        131072 // 1 Mbits eeprom = 128 KBytes = 131072 Bytes
#define SAMPLE_COUNT_BANK       1
#define SAMPLE_COUNT_HI         2
#define SAMPLE_COUNT_LO         3

#define COMMAND_SIZE            30
#define NUM_COMMANDS            5
#define TIMER_COUNT_HI          0xf00000
#define TIMER_COUNT_LOW         0xf00001

#ifdef   _HAS_GLCD_
#include      <HDM64GS12.c>
#include      <GRAPHICS.c>
#endif

#include      "auxiliar.c"

/*****************************************************************************/
// Define Variables

int                     Timer_1ms, Timer_100ms, Timer_1s, count1, plottemp;
long                    Timer_1m, plotfuel, plotSolar, Timer_100ms2;
static char             cstate, cChar;
date_time_t             dt;
char                    DateTime[36];
static long             iSampleCount;
long                    iVal, maxtemp, mintemp;
long                    SampleCap;
float                   iSolar;
float                   iTemp;
char         g_CWD[200] = ""; //current working directory
char         Solar[12];
char         Temp[12];
char         MaxTemps[12];
char         MinTemps[12];
char         ReadSample[20];
char         LocalID [8] = {0, 0, 0, 0, 0, 0, 0, 0};
char         buffer[255];
char         *cmd, *option1, *option2;
int            i, speed, old_speed, readsindex, fuel, gauge, fuel_old, errflag;
char         speed_val[9];
char         latitude_val[13];
char         longitude_val[14];
char         speedt[4];

static char      cC[ 10 ];                   // local buffer
static char      tmp[10];                   // temp conversion buffer
static char      cTimeOut;
static char      cRxBuffer [ RX_BUFFER_SIZE ];   // Fifo
static char      cRxByteCnt;                  // Number of bytes in the recv fifo
static char      *cRxBufferWritePtr;          // Pointers for the Rx buffer
static char      *cRxBufferReadPtr;
static char      cRxIsrState, cRxMsgTypeReceived, cRxMsgTypeDesired;
static char      cReceiveFlag;
static char      cSkip;
static char      updatetime;

long         result;
int            day, month_index,min,sec;
signed int      hour;

enum
{
   STATE_IDDLE,
   STATE_SECOND,
   STATE_SHOW_TIME,
   STATE_FUEL_READ,
   STATE_FUEL_READY,
   STATE_SERIAL_READY,
   STATE_GPS_REC
};

char commands[NUM_COMMANDS][COMMAND_SIZE]=
{
   "RTC",      // Option1=date/time.Sets date and time.
   "TIME",      // Ask for remote sensor's time
   "DUMP",      // Dump Data
   "SETID",   // Set vehicle's ID
   "help"      // help!
};

/*****************************************************************************/
// Functions Prototypes

void         ShowHelp   (void);
char         * GetCMD   (char *in);
char         * GetOption   (char *in);
void         ShowHelp   (void);
int            FindCommand   (char *cmd);
int            SetTime      (char *opt_buffer);
void         DisplayPrompt(void);
void         showtime   (void);
void         readadc      (void);
void         readadc2   (void);
void         glcd_imagen   (void);
void         ShowLocalTime(char *id);
void         DumpData   (void);
void         SysStart   (void);

#separate void   read_eeprom_string(char * array, int8 address, int8 max_size);
#separate void   write_eeprom_string(char * array, int8 address, int8 max_size);
#separate void   play(void);
#separate void   GpsProcess(void);
#separate void   SkipField (char cCnt);
#separate char   GetField (void);
#separate void   InitRxBuffer (char cCode);
#separate char   GetRxChar (void);
#separate void   AtolProcess (void);

#ifdef   _HAS_GLCD_
#separate void GlcdInit(void);
#endif

#include   "image.h"

/****************************************************************************
* DESCRIPTION: USART interrupt for data from GPS.
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

#int_rda
// Apenas para lembrar:
// NUNCA NUNCA NUNCA!!! Chamar funções externas à interrupção...
// Isto bagunça o sistema de interrupts.
   
void SerialInterrupt ( void )
{
   /*
   Reads incoming data from the USART and puts in in a rolling buffer
   ( but in this application, it should never roll.)
   If the buffer is full, this routine just discards the received byte.
   Not checking the LRC byte at the end of the NMEA-0183 sentence.
   */

   if ( rs232_errors & 0x04 )            // get framing error bit from Rx status reg
   {
      //cRxErrorFlag = ON;
   }

   output_high(LED_SYS);

   cChar = getc();                     // get char from UART, clear any errors

   if ( cRxByteCnt == RX_BUFFER_SIZE )      // is recv fifo full ???
   {
      goto done;
   }

   switch ( cRxIsrState )
   {
      case 0:
      {
         if ( cChar == DOLLAR )         // if start of NMEA0183 message
         {
            cRxByteCnt = 0;            // reset byte count
            cReceiveFlag = OFF;         // default to off
            cRxMsgTypeReceived = NULL;   // set hashed value to null
            cRxIsrState++;            // next state
         }
      break;

      }
      case 1:                        // five type characters to obtain
      case 2:
      case 3:
      case 4:
      case 5:
      {
         cRxMsgTypeReceived ^= cChar;   // hash in msg type
         if ( cRxIsrState++ == 5 )      // if time to check message type
         {
            if ( cRxMsgTypeReceived == cRxMsgTypeDesired )// if good
            {
               cReceiveFlag = YES;      // enable receiving
               cRxBufferWritePtr = cRxBuffer;// reset to beginning of buffer
            }
            else                  // don't want this message
            {
               cRxIsrState = 0;      // reset to look for next msg
            }
         }
      break;
      }

      case 6:
      {
         /* Case 6 skips the comma character following msg type */
         cRxIsrState++;
      break;
      }

      default:                     // remainder of characters
      {
         if ( cReceiveFlag == YES )      // if this message is wanted
         {
            *cRxBufferWritePtr = cChar;   // put char in fifo
            cRxBufferWritePtr++;      // increment pointer
            if ( cRxBufferWritePtr == ( cRxBuffer + RX_BUFFER_SIZE ) ) // pointer past end ?
            {
               cRxBufferWritePtr = cRxBuffer;// set pointer to start of fifo
            }
            cRxByteCnt++;            // Increment byte count
            if ( cChar == CR )
            {
              cReceiveFlag = NO;      // no more receive
              cstate = STATE_GPS_REC;   // GPS data ready to process...
              output_low(LED_SYS);
            }
         }
      }
   }
   done:;
   output_low(LED_SYS);
}

/****************************************************************************
* DESCRIPTION: Timer 1 Interrupt ISR
* Overflow: 1/((20000000/4)/8)) = 1/(5000000/8) = 1/625000 = 0,0000016s=1.6us.
* If timer1 is preloaded with 65535 = Overflow = 1.6us * 65536 = 0,1048576 s.
* For an overflow of 100ms:
* 0,100 = 0,0000016 * X
* X = 0,100/0,0000016 => X = 62500
* For an overflow of 100ms, preload Timer1 with: 65536-62500, wich is: 3036.
*
* RETURN:      none
* ALGORITHM:   none
* NOTES:       interrupt every 100ms
*****************************************************************************/
 #INT_TIMER1
 void TIMER1_isr(void)
 {
    output_toggle(LED_OK);
    set_timer1(8700 - get_timer1());//(3036 - get_timer1());         // Restart 100 ms timming
   if(Timer_100ms++ == 10)                // 1 second?
    {
      Timer_100ms2++;
      Timer_100ms = 0;
      Timer_1s++;
      cstate = STATE_SHOW_TIME;
      if (Timer_1s == 10)               // 1 minute?
      {
         Timer_1s = 0;
         Timer_1m++;
         if (Timer_1m == SampleCap)      // Time to capture adc data?
         {
            Timer_1m = 0;
            cstate = STATE_FUEL_READ;   // Capture adc
         }
      }
    }
 }

/****************************************************************************
* DESCRIPTION: Main program
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

void main()
{
   SysStart();

   while (TRUE)
   {
      if (cstate == STATE_FUEL_READ)
      {
         enable_interrupts ( INT_RDA );         // Enable serial interrupt - start to capture GPS data...
         cstate = STATE_IDDLE;
      }
      if (cstate == STATE_SERIAL_READY)         // Nothing yet...
      {
         cstate = STATE_IDDLE;
      }
      if (cstate == STATE_SHOW_TIME)
      {
         showtime();
         cstate = STATE_IDDLE;
      }

      if (cstate == STATE_GPS_REC)
      {
         disable_interrupts ( INT_RDA );         // Disable serial interrupt so we can process gps data and adc
         GpsProcess();
         InitRxBuffer( GPRMC_CODE );
         cstate = STATE_IDDLE;
      }

      if (kbhit(RADIO))                     // Receive data from soft serial port.
      {
         buffer[i] = fgetc(RADIO);
      
         // Check for a backspace
         if(buffer[i] != 8)
         {
            fprintf(RADIO, "%c", buffer[i]);
            i++;
         }
         else if(i > 0)
         {
            // Delete the last character
            i--;
            fputc(8, RADIO);
            fputc(' ', RADIO);
            fputc(8, RADIO);
         }
       buffer[i] = '\0';
      }

      if (buffer[i - 1] == '\r')
      {
         // Parse the command and options
         cmd = GetCMD(buffer);
         option1 = GetOption(cmd + strlen(cmd) + 1);
         option2 = GetOption(option1 + strlen(option1) + 1);

         if (cmd)
         {
            i = 0;
            switch(FindCommand(cmd))
            {
               case 0:  // RTC
                  SetTime(option1);
                  DisplayPrompt();
               break;

               case 1: // TIME
                  if (strstr(option1, LocalID) )
                  {
                     ShowLocalTime(option1);
                  }
               break;

               case 2: // DUMP
                  if (strstr(option1, LocalID) )
                  {
                     DumpData();
                  }
               break;

               case 3: // SETID
                  if (strstr(option1, LocalID) )
                  {
                     if (strlen(option2)==7)
                     {
                        write_eeprom_string (option2, LOCALID_ADD, ROM_Localid_Size);
                        read_eeprom_string (LocalID, LOCALID_ADD, ROM_Localid_Size);
                     }
                  }
               break;

               case 4:  // Help
                  ShowHelp();
                  DisplayPrompt();
               break;

               default:
                  fprintf(RADIO, "\r\nUnkown Command '%s'", cmd);
                  DisplayPrompt();
               break;
            }
         }
      }

   }
}

/****************************************************************************
* DESCRIPTION: ShowHelp function
* RETURN:      none
* ALGORITHM:   none
* NOTES:       Send a help text thru rs-232
*****************************************************************************/

void ShowHelp()
{
   __VT100_GOTOXY(0, 4)
   fprintf(RADIO, _NORMAL_ _FG_BLACK_);
   fprintf(RADIO, _BRIGHT_ _FG_YELLOW_ "\r\nLog System help");
   fprintf(RADIO, _NORMAL_ _BRIGHT_ "\r\n\n RTC ddmmYYhhmmss\t\t--- Sets Date / Time for remote sensors (all)");
   fprintf(RADIO, "\r\n TIME VehicleId\t\t\t--- Ask for vehicle's date/time");
   fprintf(RADIO, "\r\n DUMP XXX0000\t\t\t--- Dump Vehicle's data");
   fprintf(RADIO, "\r\n SETID AAA0000 BBB9999\t\t--- Set vehicle's ID");
   fprintf(RADIO, "\r\n\ help\tThis help.");
   fprintf(RADIO, _NORMAL_ "\r\n\n Enclose parameter with quotes if it has spaces.");

   DisplayPrompt();
}

/****************************************************************************
* DESCRIPTION: Parse the command in the receive buffer.
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

char * GetCMD(char *in)
{
   char tokens[]=" \r\n";
   return(strtok(in,tokens));
}

/****************************************************************************
* DESCRIPTION: Parse the option(s) in the command
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

char * GetOption(char *in)
{
   char tokensSpace[]=" \r\n";
   char tokensQuote[]="\"\r\n";
   
   // Trim leading spaces
   while (*in==' ')
      in++;
   
   // If first char is a quote, then end token on a quote.  ELSE end token on a space
   if (*in == '\"')
      return(strtok(in,tokensQuote));
   else
      return(strtok(in,tokensSpace));
}

/****************************************************************************
* DESCRIPTION: Search if the command exist in the command table
* RETURN:      none
* ALGORITHM:   none
* NOTES:       Find if the command received from rs-232 exists.
*****************************************************************************/

int FindCommand(char *cmd)
{
   char buf[COMMAND_SIZE];
   int i;
   
   for (i=0; i<NUM_COMMANDS; i++)
   {
      strcpy(buf, &commands[i][0]);
      if (stricmp(buf, cmd)==0)
         return(i);
   }
   
   return(0xFF);
}

/****************************************************************************
* DESCRIPTION: Set date/time in the RTC, from the rs-232 receive buffer.
* RETURN:      none
* ALGORITHM:   none
* NOTES:       The buffer has the form: ddmmyyhhmmss
*****************************************************************************/

int SetTime(char *opt_buffer)
{
   char day[3];
   char month[3];
   char year[3];
   char hour[3];
   char min[3];
   char sec[3];

   strncpy   (day, opt_buffer,    2);
   strcpy   (day + 2, "\0");
   strncpy (month, opt_buffer+2,  2);
   strcpy   (month + 2, "\0");
   strncpy (year, opt_buffer+4,  2);
   strcpy   (year + 2, "\0");
   strncpy (hour, opt_buffer+6,    2);
   strcpy   (hour + 2, "\0");
   strncpy (min, opt_buffer+8,  2);
   strcpy   (min + 2, "\0");
   strncpy (sec, opt_buffer+10,  2);
   strcpy   (sec + 2, "\0");

   dt.month   = atoi(month);
   dt.day     = atoi(day);
   dt.year    = atoi(year);
   dt.hours   = atoi(hour);
   dt.minutes = atoi(min);
   dt.seconds = atoi(sec);
   //dt.weekday = 0;     // 0 = Sunday, 1 = Monday, etc.

   PCF8583_set_datetime(&dt);
   
   return(0);
}

/****************************************************************************
* DESCRIPTION: Display a prompt thru rs-232
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

void DisplayPrompt(void)
{
   __VT100_GOTOXY(0, 16)
   fprintf(RADIO, "\r\n\n%s> ", g_CWD);
}

/****************************************************************************
* DESCRIPTION: Show the date/time in the selected output.
* RETURN:      none
* ALGORITHM:   none
* NOTES:       Read date/time from RTC chip (pcf8583)
*****************************************************************************/

void showtime(void)
{
   PCF8583_read_datetime(&dt);

#ifdef   _HAS_GLCD_
   glcd_text35(60,59,DateTime,OFF);
#endif

   sprintf(DateTime,"%02u/%02u/%02u %02u:%02u:%02u", dt.day, dt.month, dt.year, dt.hours, dt.minutes, dt.seconds);

#ifdef _HAS_GLCD_
   glcd_text35(60,59,DateTime,ON);
#endif
}

/****************************************************************************
* DESCRIPTION: Read the adc channels and plot the results and the date/time
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

void readadc(void)
{
   //output_high(LED_SYS);

   set_adc_channel ( 0 );
   delay_ms(10);
   iVal = read_adc();
   delay_ms(10);
   iSolar = ( float ) iVal / 1023 * 5;
   set_adc_channel ( 1 );
   delay_ms(10);
   iVal = read_adc();
   delay_ms(10);
   iTemp = ( float ) iVal / 1023 * 5;
   iTemp = iTemp * 100;

#ifdef   _HAS_GLCD_

   glcd_text35(26,59,Solar,OFF);
   sprintf ( Solar, "%02.2fV", iSolar );
   glcd_text35(26,59,Solar,ON);
   glcd_text35(00,59,Temp,OFF);
   sprintf ( Temp, "%02.1foC", iTemp );
   glcd_text35(00,59,Temp,ON);
   plotfuel = 55 - (int)iTemp;
   glcd_line(plottemp,55,plottemp,10,OFF);
   glcd_pixel(plottemp,plotfuel,ON);
   glcd_line(plottemp+1,55,plottemp+1,10,ON);

   if (plottemp++ == 60)
   {
      glcd_line(plottemp,55,plottemp,10,OFF);
      plottemp=12;//126) plottemp=12;
   }
   if (maxtemp < iVal)
   {
      maxtemp = iVal;
      //glcd_rect(66,55,70,10,YES,OFF);
      //glcd_rect(66,55,70,plotfuel,YES,ON);
      glcd_text35(85,00,MaxTemps,OFF);//74,50,MaxTemps,OFF);
      sprintf ( MaxTemps, "%02.1f", iTemp );
      glcd_text35(85,00,MaxTemps,ON);//74,50,MaxTemps,ON);
   }
   if (mintemp > iVal)
   {
      mintemp = iVal;
      //glcd_rect(96,55,100,10,YES,OFF);
      //glcd_rect(96,55,100,plotfuel,YES,ON);
      glcd_text35(110,00,MinTemps,OFF);//104,50,MinTemps,OFF);
      sprintf ( MinTemps, "%02.1f", iTemp );
      glcd_text35(110,00,MinTemps,ON);//104,50,MinTemps,ON);
   }

   glcd_text35(66,17,latitude_val,ON);
   glcd_text35(66,32,longitude_val,ON);
   //glcd_text57(x,y,textptr,size,color)
   glcd_text57(80,40,speedt,2,ON);
   //glcd_text35(66,47,speedt, ON);

   //__VT100_GOTOXY(0, 20)
   //fprintf(RADIO, _NORMAL_ "Solar: %4.4f Temp.: %4.4f - %s \n\rLatitude: %s Longitude: %s Speed: %u", iSolar, iTemp, DateTime, latitude_val, longitude_val, speed);
   __VT100_GOTOXY(0, 24)
   fprintf (RADIO, _FG_RED_ "%s",LocalID);
   DisplayPrompt();

   //output_low(LED_SYS);

#endif

}

/****************************************************************************
* DESCRIPTION: Initialize the Graphic Lcd
* RETURN:      none
* ALGORITHM:   none
* NOTES:       Clears the GLCD screen
*****************************************************************************/

#ifdef   _HAS_GLCD_

#separate void GlcdInit(void)
{
   glcd_init(ON);
   glcd_fillScreen(OFF);
   delay_ms(200);
}

#endif

/****************************************************************************
* DESCRIPTION: Plot image on GLCD (128X64)
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

void glcd_imagen()
{
   char i,j;
   signed char k;
   for( i = 0 ; i < 64 ; i ++ )
   {
      for( j = 0 ; j < 16 ; j ++)
      {   
         for(k=7;k>-1;k--)
         {     
            if( bit_test(imagen[i][j] ,7-k ))
               glcd_pixel( j*8+k,i, ON );
               
         }
      }
   }
}

/****************************************************************************
* DESCRIPTION: Inform local time to net manager
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

void ShowLocalTime (char *id)
{
   PCF8583_read_datetime(&dt);
   sprintf(DateTime,"%02u/%02u/%02u %02u:%02u:%02u", dt.day, dt.month, dt.year, dt.hours, dt.minutes, dt.seconds);
   fprintf(RADIO, "Date/Time of %s: %s", id, DateTime);
}

/****************************************************************************
* DESCRIPTION: Dump captured data to net manager
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

void DumpData(void)
{
   // Dump captured data to net manager
}

/****************************************************************************
* DESCRIPTION: Read a string from EEPROM.
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

#separate void read_eeprom_string(char * array, int8 address, int8 max_size)

{
   int8 i=0;
   *array=0;

   while (i<max_size)
   {
      *array = read_eeprom(address+i);
      if (*array == 0) {i=max_size;}
      else {
         array++;
         *array=0;
      }
      i++;
   }
}

/****************************************************************************
* DESCRIPTION: Write a string to EEPROM
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

#separate void write_eeprom_string(char * array, int8 address, int8 max_size)

{
   int8 i=0;

   while (i<max_size) {
      write_eeprom(address+i,*array);
      if (*array == 0) {i=max_size;}
      array++;
      i++;
   }
}

/****************************************************************************
* DESCRIPTION: Init all system's units and variables.
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

void SysStart (void)
{
   delay_ms ( 200 );                  // Wait enough time after Vdd rise
   Timer_1ms   = 0;                       // Reset Timer counters
   Timer_100ms = 0;                       //   "     "       "
   Timer_1s    = 0;                       //   "     "       "
   Timer_1m   = 0;                  //   "     "       "
   cstate      = STATE_IDDLE;
   i         = 0;
   plottemp   = 12;
   maxtemp      = 0;
   mintemp      = 1023;
   cSkip      = 0;

   // Read Vehicle's ID from internal eeprom.
   read_eeprom_string (LocalID, LOCALID_ADD, ROM_Localid_Size);
   // Read Sample period, in minutes (from 1 to 65535 minutes), from internal eeprom.
    SampleCap   = ( 256 * read_eeprom ( TIMER_COUNT_HI ) ) + read_eeprom ( TIMER_COUNT_LOW );

   output_float ( RX_IN );                // Ensure Rx input is HiZ
   output_float ( BUTTON_1 );             // Ensure switch input is HiZ

   cstate = STATE_IDDLE;
   output_low (BUZZER);
   PCF8583_init();

#ifdef   _HAS_GLCD_
   GlcdInit();
   delay_ms(200);
#endif

   glcd_imagen();
   delay_ms(4000);
   glcd_fillScreen(OFF);

   InitRxBuffer( GPRMC_CODE );

    setup_ccp1      ( CCP_OFF );
    setup_ccp2      ( CCP_OFF );
   setup_comparator(NC_NC_NC_NC);
   setup_psp      (PSP_DISABLED);
   setup_timer_1   ( T1_INTERNAL | T1_DIV_BY_8 );
   setup_adc_ports (AN0_TO_AN1);
   setup_adc      (ADC_CLOCK_DIV_16 | ADC_TAD_MUL_0);//Vide: http://www.ccsinfo.com/forum/viewtopic.php?t=41205&highlight=adc
   set_timer1      (8700 - get_timer1());
   enable_interrupts ( INT_TIMER1 );      // Enable Timer1 interrupt
   enable_interrupts ( GLOBAL );          // Enable all interrupts

   __VT100_GOTOXY(0, 0)
   fprintf(RADIO, _NORMAL_ _FG_BLACK_ _CLRSCR_);
   fprintf(RADIO, _BRIGHT_ _FG_YELLOW_ "Sistema de Monitoramento de Combustivel");

#ifdef _HAS_GLCD_

   glcd_line(0,57,127,57,ON);
   glcd_line(0,7,127,7,ON);

   glcd_text35(0,0,"TINYLOGGER 1.0",ON);//  (c)2010 ssaguiar",ON);
   glcd_text35(0,11,"40_",ON);
   glcd_text35(0,21,"30_",ON);
   glcd_text35(0,31,"20_",ON);
   glcd_text35(0,41,"10_",ON);
   glcd_text35(0,51,"00_",ON);

   glcd_line(62,10,62,55,ON);

   glcd_text35(66,10,"Latitude:",ON);
   glcd_text35(66,25,"Longitude:",ON);

#endif

   DisplayPrompt();
   play();
}

/****************************************************************************
* DESCRIPTION: Play a beep.
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

#separate void  play()
{
   output_high (BUZZER);               // Buzzer on
   output_high (LED_OK);               // Led_OK on
   delay_ms (50);                     // Wait a bit...
   output_low (BUZZER);               // Buzzer off
   output_low (LED_OK);               // Led_Ok off
}

/****************************************************************************
* DESCRIPTION: Display GPS data received .
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

void GpsProcess (void)
{

/*
SEE: http://www.ccsinfo.com/forum/viewtopic.php?t=34404&highlight=gps
To transform 2 ASCII bytes to 1 bcd byte:
UTC_Mins = 0x10 * (GPS_String[8]-0x30) + (GPS_String[9]-0x30);
*/

#ifdef _HAS_GLCD_
   glcd_text35(66,17,latitude_val,OFF);
   glcd_text35(66,32,longitude_val,OFF);
   glcd_text57(80,40,speedt,2,OFF);
#endif

   GetField();      //Time hh:mm:ss

   GetField();                        // Status -> A = OK, V = warning
   if ( cC [ 0 ] == 'A' )
   {
      GetField();                     // LATITUDE
         latitude_val[0]=cC[0];
         latitude_val[1]=cC[1];
         latitude_val[2]=':';
         latitude_val[3]=cC[2];
         latitude_val[4]=cC[3];
         latitude_val[5]=cC[4];
         latitude_val[6]=cC[5];
         latitude_val[7]=cC[6];
         latitude_val[8]=cC[7];
         latitude_val[9]=cC[8];
         latitude_val[10]=' ';
         GetField();                  // NS
         latitude_val[11]=cC[0];
         latitude_val[12]=0;

      GetField();                     // LONGITUDE
         longitude_val[0]=cC[0];
         longitude_val[1]=cC[1];
         longitude_val[2]=cC[2];
         longitude_val[3]=':';
         longitude_val[4]=cC[3];
         longitude_val[5]=cC[4];
         longitude_val[6]=cC[5];
         longitude_val[7]=cC[6];
         longitude_val[8]=cC[7];
         longitude_val[9]=cC[8];
         longitude_val[10]=cC[9];
         longitude_val[11]=' ';

      GetField();                     // EW
         longitude_val[12]=cC[0];
         longitude_val[13]=0;
   }
   else
   {
      play();
      //__VT100_GOTOXY(70, 24)
      //fprintf(RADIO, _FG_RED_ "WARNING!");
      latitude_val   = "ERROR       ";
      longitude_val   = "ERROR       ";
      errflag         = TRUE;
   }

   GetField();                        // Get Speed
      AtolProcess();
      result = atol (tmp);
      result *= 1.852;               // in Km/h
      speed = (int)result;
      if (errflag == TRUE)
      {
         speed = 0;
         errflag = FALSE;
      }

   sprintf (speedt, "%03u", speed);

   readadc();
}

/****************************************************************************
* DESCRIPTION: get field's data
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

#separate char GetField ( void )
{
   char cX, cIndex;
   cX = NULL;
   cIndex = 0;
   while ( !cSkip )
   {
      cX = GetRxChar();
      if ( ( cX == COMMA ) || ( cX == CR ) )
      {
         break;
      }
      cC [ cIndex++ ] = cX;
   }
   cC [ cIndex ] = EOF;
   return ( cIndex );                  // return number of characters in field
}

/****************************************************************************
* DESCRIPTION: skip field's data
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

#separate void SkipField ( char cCnt )
{
   char cX;

   for ( cX = 0; cX < cCnt; cX++ )
   {
      while ( GetRxChar() != COMMA );
   }
}

/****************************************************************************
* DESCRIPTION: get next byte in fifo buffer
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

#separate char GetRxChar ( void )
{
// Get the next available byte in the recv fifo.
// Call this function ONLY if the recv fifo contains data.
char cValue;

cValue = 0;
if ( cRxByteCnt > 0 )                  // For safety, check if there is any data
{
   cValue = *cRxBufferReadPtr++;         // Read byte from fifo
   if ( cRxBufferReadPtr == ( cRxBuffer + RX_BUFFER_SIZE ) ) // Did tail ptr wrap ?
   {
      cRxBufferReadPtr = cRxBuffer;      // If so, reset it to start of buffer
   }
   cRxByteCnt--;                     // Decrement byte count
}
return ( cValue );
}

/****************************************************************************
* DESCRIPTION: Init rx buffer and variables
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

#separate void InitRxBuffer ( char cCode )
{
   cRxBufferWritePtr = cRxBuffer;         // point to beginning of buffer
   cRxBufferReadPtr = cRxBuffer;
   cRxByteCnt = 0;
   cRxIsrState = 0;
   cRxMsgTypeDesired = cCode;
}

/****************************************************************************
* DESCRIPTION: AtolProcess - modified ATOL
* RETURN:      none
* ALGORITHM:   none
* NOTES:       none
*****************************************************************************/

#separate void AtolProcess ()
{
   int count;
   count = 0;
   while (cC[count] != '.')            // Find the decimal dot...
   {
      tmp[count] = cC[count];
      count++;
   }
   tmp[count] = 0;// for atol/atoi work
}

/**********************************/



And the vt100.h file's content is:

Code:

/*****************************************************************************/
// VT100 defines

/******************************************************************************
 VT100 definitions
******************************************************************************/

#define _ESC_      "\033"      // octal 033 = hexadecimal 01B = <_ESC_>

/******************************************************************************
 VT100 Set Display Attributes definitions
******************************************************************************/
// Font mode
#define VT100_NORMAL      0
#define VT100_BRIGHT      1
#define VT100_DIM         2
#define VT100_UNDERLINE      3
#define VT100_BLINK         4
#define VT100_REVERSE      5
#define VT100_HIDDEN      6

// Foreground colours
#define VT100_FG_BLACK      30
#define VT100_FG_RED      31
#define VT100_FG_GREEN      32
#define VT100_FG_YELLOW      33
#define VT100_FG_BLUE      34
#define VT100_FG_MAGENTA   35
#define VT100_FG_CYAN      36
#define VT100_FG_WHITE      37

// Background colours
#define VT100_BG_BLACK      40
#define VT100_BG_RED      41
#define VT100_BG_GREEN      42
#define VT100_BG_YELLOW      43
#define VT100_BG_BLUE      44
#define VT100_BG_MAGENTA   45
#define VT100_BG_CYAN      46
#define VT100_BG_WHITE      47

//Set disp attr macro
#define __VT100_DISP_ATTR(_ATTR_)      { printf(_ESC_"[%dm",_ATTR_); }
#define __VT100_ATTR(_ATTR_)         { printf(_ESC_"[%dm",_ATTR_); }
#define __VT100_GOTOXY(X, Y)         { printf(_ESC_"[%d;%df", Y, X); }

/******************************************************************************
 VT100 Device Status definitions
******************************************************************************/

#define _GOTOXY_         _ESC_"[%u;%uf"

#define _TERM_RESET_      _ESC_ "c"
#define _CURSOR_HOME_      _ESC_ "[H"
#define _CURSOR_UP_         _ESC_ "[A"
#define _CURSOR_DOWN_      _ESC_ "[B"
#define _CURSOR_FORWARD_   _ESC_ "[C"
#define _CURSOR_BACKWARD_   _ESC_ "[D"

#define _CURSOR_PUSH_      _ESC_ "[s"
#define _CURSOR_POP_      _ESC_ "[u"
#define _ATTR_PUSH_         _ESC_ "7"
#define _ATTR_POP_         _ESC_ "8"

#define _CLREOL_         _ESC_ "[K"
#define _CLRSOL_         _ESC_ "[1K"
#define _CLRLN_            _ESC_ "[2K"
#define _CLRDOWN_         _ESC_ "[J"
#define _CLRUP_            _ESC_ "[1J"
#define _CLRSCR_         _ESC_ "[2J"

#define _NORMAL_         _ESC_ "[0m"
#define _BRIGHT_         _ESC_ "[1m"
#define _DIM_            _ESC_ "[2m"
#define _UNDERLINE_         _ESC_ "[4m"
#define _BLINK_            _ESC_ "[5m"
#define _REVERSE_         _ESC_ "[7m"
#define _HIDDEN_         _ESC_ "[8m"

#define _FG_BLACK_         _ESC_ "[30m"
#define _FG_RED_         _ESC_ "[31m"
#define _FG_GREEN_         _ESC_ "[32m"
#define _FG_YELLOW_         _ESC_ "[33m"
#define _FG_BLUE_         _ESC_ "[34m"
#define _FG_MAGENTA_      _ESC_ "[35m"
#define _FG_CYAN_         _ESC_ "[36m"
#define _FG_WHITE_         _ESC_ "[37m"

// Background colours
#define _BG_BLACK_         _ESC_ "[40m"
#define _BG_RED_         _ESC_ "[41m"
#define _BG_GREEN_         _ESC_ "[42m"
#define _BG_YELLOW_         _ESC_ "[43m"
#define _BG_BLUE_         _ESC_ "[44m"
#define _BG_MAGENTA_      _ESC_ "[45m"
#define _BG_CYAN_         _ESC_ "[46m"
#define _BG_WHITE_         _ESC_ "[47m"


The pc8583.c (found in this forum) is:
Code:

// PCF8583.C

#ifndef PCF8583_SDA
#define PCF8583_SDA  PIN_C4
#define PCF8583_SCL  PIN_C3
#endif

#use i2c(MASTER, sda=PCF8583_SDA, scl=PCF8583_SCL)

#ifndef PCF8583_WRITE_ADDRESS
#define PCF8583_WRITE_ADDRESS 0xA0
#define PCF8583_READ_ADDRESS  0xA1
#endif

// Register addresses
#define PCF8583_CTRL_STATUS_REG    0x00
#define PCF8583_100S_REG           0x01
#define PCF8583_SECONDS_REG        0x02
#define PCF8583_MINUTES_REG        0x03
#define PCF8583_HOURS_REG          0x04
#define PCF8583_DATE_REG           0x05
#define PCF8583_MONTHS_REG         0x06
#define PCF8583_TIMER_REG          0x07

#define PCF8583_ALARM_CONTROL_REG  0x08
#define PCF8583_ALARM_100S_REG     0x09
#define PCF8583_ALARM_SECS_REG     0x0A
#define PCF8583_ALARM_MINS_REG     0x0B
#define PCF8583_ALARM_HOURS_REG    0x0C
#define PCF8583_ALARM_DATE_REG     0x0D
#define PCF8583_ALARM_MONTHS_REG   0x0E
#define PCF8583_ALARM_TIMER_REG    0x0F

// Use the first NVRAM address for the year byte.
#define PCF8583_YEAR_REG           0x10


// Commands for the Control/Status register.
#define PCF8583_START_COUNTING     0x00
#define PCF8583_STOP_COUNTING      0x80



char const weekday_names[7][10] =
{
{"Dom"},
{"Seg"},
{"Ter"},
{"Qua"},
{"Qui"},
{"[spam]"},
{"Sab"}
};   
               
// This structure defines the user's date and time data.
// The values are stored as unsigned integers.  The user
// should declare a structure of this type in the application
// program. Then the address of the structure should be
// passed to the PCF8583 read/write functions in this
// driver, whenever you want to talk to the chip.
typedef struct
{
int8 seconds;    // 0 to 59
int8 minutes;    // 0 to 59
int8 hours;      // 0 to 23  (24-hour time)
int8 day;        // 1 to 31
int8 month;      // 1 to 12
int8 year;       // 00 to 99
int8 weekday;    // 0 = Sunday, 1 = Monday, etc.
}date_time_t;


//----------------------------------------------
void PCF8583_write_byte(int8 address, int8 data)
{
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(address);
i2c_write(data);
i2c_stop();
enable_interrupts(GLOBAL);
}   

//----------------------------------------------
int8 PCF8583_read_byte(int8 address)
{
int8 retval;

disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(address);
i2c_start();
i2c_write(PCF8583_READ_ADDRESS);
retval = i2c_read(0);
i2c_stop();
enable_interrupts(GLOBAL);
return(retval);
}   


void PCF8583_init(void)
{
PCF8583_write_byte(PCF8583_CTRL_STATUS_REG,
                              PCF8583_START_COUNTING);
}   

//----------------------------------------------
// This function converts an 8 bit binary value
// to an 8 bit BCD value.
// The input range must be from 0 to 99.

int8 bin2bcd(int8 value)
{
char retval;

retval = 0;

while(1)
  {
   // Get the tens digit by doing multiple subtraction
   // of 10 from the binary value.
   if(value >= 10)
     {
      value -= 10;
      retval += 0x10;
     }
   else // Get the ones digit by adding the remainder.
     {
      retval += value;
      break;
     }
   }

return(retval);
}

//----------------------------------------------
// This function converts an 8 bit BCD value to
// an 8 bit binary value.
// The input range must be from 00 to 99.

char bcd2bin(char bcd_value)
{
char temp;

temp = bcd_value;

// Shifting the upper digit right by 1 is
// the same as multiplying it by 8.
temp >>= 1;

// Isolate the bits for the upper digit.
temp &= 0x78;

// Now return: (Tens * 8) + (Tens * 2) + Ones
return(temp + (temp >> 2) + (bcd_value & 0x0f));

}

//----------------------------------------------
void PCF8583_set_datetime(date_time_t *dt)
{
int8 bcd_sec;
int8 bcd_min;
int8 bcd_hrs;
int8 bcd_day;
int8 bcd_mon;

// Convert the input date/time into BCD values
// that are formatted for the PCF8583 registers.
bcd_sec = bin2bcd(dt->seconds);
bcd_min = bin2bcd(dt->minutes);
bcd_hrs = bin2bcd(dt->hours);   
bcd_day = bin2bcd(dt->day) | (dt->year << 6);
bcd_mon = bin2bcd(dt->month) | (dt->weekday << 5);

// Stop the RTC from counting, before we write to
// the date and time registers.
PCF8583_write_byte(PCF8583_CTRL_STATUS_REG,
                              PCF8583_STOP_COUNTING);

// Write to the date and time registers.  Disable interrupts
// so they can't disrupt the i2c operations.
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(PCF8583_100S_REG);   // Start at 100's reg.   
i2c_write(0x00);               // Set 100's reg = 0
i2c_write(bcd_sec);
i2c_write(bcd_min);
i2c_write(bcd_hrs);   
i2c_write(bcd_day);
i2c_write(bcd_mon);
i2c_stop();
enable_interrupts(GLOBAL);

// Write the year byte to the first NVRAM location.
// Leave it in binary format.
PCF8583_write_byte(PCF8583_YEAR_REG, dt->year);

// Now allow the PCF8583 to start counting again.
PCF8583_write_byte(PCF8583_CTRL_STATUS_REG,
                              PCF8583_START_COUNTING);
}

//----------------------------------------------
// Read the Date and Time from the hardware registers
// in the PCF8583.   We don't have to disable counting
// during read operations, because according to the data
// sheet, if any of the lower registers (1 to 7) is read,
// all of them are loaded into "capture" registers.
// All further reading within that cycle is done from
// those registers.

void PCF8583_read_datetime(date_time_t *dt)
{
int8 year_bits;
int8 year;

int8 bcd_sec;
int8 bcd_min;
int8 bcd_hrs;
int8 bcd_day;
int8 bcd_mon;

// Disable interrupts so the i2c process is not disrupted.
disable_interrupts(GLOBAL);

// Read the date/time registers inside the PCF8583.
i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(PCF8583_SECONDS_REG);   // Start at seconds reg.
i2c_start();
i2c_write(PCF8583_READ_ADDRESS);

bcd_sec = i2c_read();     
bcd_min = i2c_read();     
bcd_hrs = i2c_read();
bcd_day = i2c_read();
bcd_mon = i2c_read(0);
i2c_stop();

enable_interrupts(GLOBAL);

// Convert the date/time values from BCD to
// unsigned 8-bit integers.  Unpack the bits
// in the PCF8583 registers where required.
dt->seconds = bcd2bin(bcd_sec);     
dt->minutes = bcd2bin(bcd_min);     
dt->hours   = bcd2bin(bcd_hrs & 0x3F);
dt->day     = bcd2bin(bcd_day & 0x3F);
dt->month   = bcd2bin(bcd_mon & 0x1F);
dt->weekday = bcd_mon >> 5;
year_bits   = bcd_day >> 6;   

// Read the year byte from NVRAM.
// This is an added feature of this driver.
year = PCF8583_read_byte(PCF8583_YEAR_REG);

// Check if the two "year bits" were incremented by
// the PCF8583.  If so, increment the 8-bit year
// byte (read from NVRAM) by the same amount.
while(year_bits != (year & 3))
      year++;

dt->year = year;

// Now update the year byte in the NVRAM
// inside the PCF8583.
PCF8583_write_byte(PCF8583_YEAR_REG, year);

}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group