/*
 * Project name:
     RS485_Slave_Example (RS485 Library demo - Slave side)
 * Copyright:
     (c) Mikroelektronika, 2005-2010.
 * Revision History:
     20080930:
       - initial release;
* Description:
     This is a simple demonstration on how to use the mikroC's RS485 library.
     It is being used in pair with the RS485_Master_Example project. Slave (this
     machine) initializes itself (on address 160) and waits to receive data from
     the master. Then it increments the first byte of received data and sends it
     back to the master. The data received is shown on PORTB, Error on receive
     and number of consecutive unsuccessful retries on PORTC.
     Several situations are shown here:
       - RS485 Slave Init sequence;
       - Data sending slave-to-master;
     Also shown here, but not strictly related to RS485 library, is:
       - Function calling from the interrupt routine - which data is to be saved,
         and how.
     For further explanations on RS485 library, please consult the mikroC Help.
 * Test configuration:
     MCU:             ATmega16
                      http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf
     Dev.Board:       EasyAVR6
                      http://www.mikroe.com/eng/products/view/321/easyavr6-development-system/
     Oscillator:      External, 8.0000 MHz
     Ext. Modules:    ac:RS485_Board on PORTD  
     SW:              mikroC PRO for AVR
                      http://www.mikroe.com/eng/products/view/228/mikroc-pro-for-avr/
 * NOTES:
     - Be careful to initialize the UART module before performing RS485 init!
     - RS485 module is connected to PORTD, i.e. where the MCU's UART module is.
 */

char dat[9];             // buffer for receving/sending messages
char i,j;

sbit  rs485_rxtx_pin  at PORTD2_bit;         // set transcieve pin
sbit  rs485_rxtx_pin_direction at DDD2_bit;  // set transcieve pin direction

// Interrupt routine
void interrupt() org IVT_ADDR_USART_RXC {
  RS485Slave_Receive(dat);
}

void main() {
  PORTB = 0;                         // clear PORTB
  PORTC = 0;                         // clear PORTC

  DDRB = 0xFF;                       // set PORTB as output
  DDRC = 0xFF;                       // set PORTC as output

  UART1_Init(9600);                  // initialize UART1 module
  Delay_ms(100);
  RS485Slave_Init(160);              // Intialize MCU as slave, address 160

  dat[4] = 0;                        // ensure that message received flag is 0
  dat[5] = 0;                        // ensure that message received flag is 0
  dat[6] = 0;                        // ensure that error flag is 0

  SREG_I_bit = 1;                    // enable global interrupt
  RXCIE_bit  = 1;                    // enable interrupt on UARTs receive

  while (1) {
  
    if (dat[5])  {                   // if an error detected, signal it by
      PORTC = dat[5];                //   setting PORTC
      dat[5] = 0;
    }
    if (dat[4]) {                    // upon completed valid message receive
      dat[4] = 0;                    //   data[4] is set to 0xFF
      j = dat[3];

      for (i = 1; i <= dat[3];i++){  // show data on PORTB
        PORTB = dat[i-1];
      }
      dat[0] = dat[0]+1;             // increment received dat[0]
      Delay_ms(1);
      RS485Slave_Send(dat,1);        //   and send it back to master
    }
  }
}