tangibleInterface.c 5.79 KB
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "serial.h"
#include "ethernet.h"
#include "w5100.h"
#include "socket.h"

#define MAC_SIZE	6
#define IPV4_SIZE	4
#define PRESCALER 1024
#define NB_TICK 6250
#define DELAY 300

bool sleep = false; //Etat de l'interface : true = mode sommeil / false = mode eveillé
unsigned char comMem[2] = {'\0'}; //Commande en mémoire
unsigned char msg[2]; //Message qui sera envoyé via TCP
typedef enum type_msg {TCP,UDP}type_msg;
bool isTCP_received = false; // <- Msg TCP reçu ou non? Permet la réouverture de la socket TCP pour la réécoute TCP

void init_led(void)
{
  DDRD = 0xFF;
  if (sleep == true) // si IT dort
    {
      PORTD = 0x08;
    }
  else
    {
      PORTD = 0x00;
    }
}

void init_timer(void)
{
  TCCR1B |= _BV(WGM12);
  TCCR1B |= _BV(CS12);  // Facteur de division 1024
  TCCR1B |= _BV(CS10);
  OCR1A  = NB_TICK;
  TIMSK1 |= _BV(OCIE1A);
}

ISR(TIMER1_COMPA_vect)
{
  if(sleep == false)
    PORTD ^= 0x20;
}


void request(SOCKET sock,uint8 rq[2],uint8 addr[IPV4_SIZE],type_msg type)
{
  uint8 x = rq [0] & 0xE0; //Récupération de la commande
  x = x >> 5;
  uint16 y = rq[0] & 0x1F; //Récupération du pourcentage
  y = y << 8;
  y += rq[1];
  float per = y*0.0122;

  if (type == UDP)
    {
      SOCKET s = 2; //Creation socket TCP pour réponse à la broadcast UDP
      switch(x)
	{
	  
	case 0: // GETSTATUS + connection ( Reçu via UDP broadcast, mais on répond en TCP ! )
	  printf("Reception UDP getstatus\n");
	  if(socket(s,Sn_MR_TCP,2020,0) == 0)
	    {
	      printf("SOCKET TCP NON INITILIASEE \n");
	      break;
	    }
	  if (connect(s,addr,2020))
	    {
	      _delay_ms(DELAY); //l'IT doit attendre un peu avant d'envoyer
	      if (sleep==false)
		{
		  strcpy(msg,"\x20\x01");
		}
	      else
		{
		  strcpy(msg,"\x20\x00");
		}
	      send(s,msg,sizeof(char)*strlen(msg));
	      disconnect(s);
	    }	  
	  break;

	case 2: // SLEEP MODE ON/OFF
	  if ((y == 0x0001) & (sleep == true))
	    {
	      sleep = false;
	      printf("MODE EVEILLE\n");
	      PORTD = PORTD ^ 0x08;
	    }
	  else if ((y == 0x0000) & (sleep == false))
	    {
	      sleep = true;
	      printf("MODE SOMMEIL\n");
	      PORTD = 0x08;
	    }
	  break;

	case 3: // GETCOMMAND
	  if(socket(s,Sn_MR_TCP,2020,0) == 0)
	    {
	      printf("SOCKET TCP NON INITILIASEE \n");
	      break;
	    }
	  if (connect(s,addr,2020))
	    {
	      _delay_ms(DELAY); //l'IT doit attendre un peu avant d'envoyer
	      msg[0]=comMem[0];
	      msg[1]=comMem[1];	      
	      send(s,msg,sizeof(char)*strlen(msg));
	      disconnect(s);
	    }
	  break;
	  
	case 5: // SETCOMMANDE
	  if (sleep == false)
	    {
	      OCR1A = NB_TICK - 53*(int)per;
	      comMem[0] = rq[0]; comMem[1] = rq [1]; //save
	    }
	  break;
	  
	}
    }
  else if (type == TCP)
    {
      switch(x)
	{
	  
	case 0: // GETSTATUS
	  if (sleep==false)
	    {
	      strcpy(msg,"\x20\x01");
	    }
	  else
	    {
	      strcpy(msg,"\x20\x00");
	    }
	  send(sock,msg,sizeof(char)*strlen(msg));
	  disconnect(sock);
	  break;

	case 2: // SLEEP MODE ON/OFF
	  if ((y == 0x0001) & (sleep == true))
	    {
	      sleep = false;
	      printf("MODE EVEILLE\n");
	      PORTD = PORTD ^ 0x08;
	    }
	  else if ((y == 0x0000) & (sleep == false))
	    {
	      sleep = true;
	      printf("MODE SOMMEIL\n");
	      PORTD = 0x08;
	    }
	  disconnect(sock);
	  break;
	  
	case 3: // GETCOMMAND
	  printf("Request ComMem\n");
	  strcpy(msg,comMem);
	  send(sock,msg,sizeof(char)*strlen(msg));
	  disconnect(sock);
	  break;
	  
	case 5: // SETCOMMANDE
	  if (sleep == false)
	    {
	      OCR1A = NB_TICK - 53*(int)per;
	      comMem[0] = rq[0]; comMem[1] = rq [1]; //save
	    }
	  disconnect(sock);
	  break;	  
	}
    }  
}
  

int main(void)
{
  /* VARIABLES */
        
  SOCKET sUDP=0,sTCP=1; 
  uint8_t mac[MAC_SIZE] = {0xA0,0xBD,0xCD,0xDD,0xED,0xFD}; // <- Adresse MAC de l'IT
  uint8_t ip[IPV4_SIZE] = {192,168,1,205}; // <- Adresse IPV4 de l'IT
  uint8_t gateway[4] = {192,168,1,1}; // <- Adresse passerelle 
  uint8_t mask[4] = {255,255,255,0}; // <- Masque de sous réseau
  uint8_t buf[2]; // <- Sert à stocker les deux octets recus via TCP & UDP
  uint16_t datasize; // <- Sert à stocker la longueur du datagramme
  uint8_t addr[IPV4_SIZE]; // <- Sert à stocker l'adresse IP de l'émetteur
  uint16_t port; // <- Sert à stocker le port utilisé par l'émetteur
  type_msg type; // <- Enumeration : type de message recu {TCP,UDP}

  /* INITIALISATION */
    
  init_led(); // <- Initialise les LEDS 
  init_timer(); // <- Initialise le compteur pour la fréquence du clignotement LED
  init_printf(); // <- Initialise la communication série
  ethernet_init(mac,ip,gateway,mask); // <- Initialise le shield ethernet
  
  if (!socket(sUDP,Sn_MR_UDP,2020,0))
    {
      return -1;
    }
    
  if (!socket(sTCP,Sn_MR_TCP,2020,0))
    {
      return -1;
    }
  
  comMem[0] = 0xA0; comMem[1] = 0x00; // Commande en mémoire (default)
  
  listen(sTCP);

  /* BOUCLE PRINCIPALE */

  while(1)
    {
      sei();	
      if (isTCP_received == true)
	{
	  socket(sTCP,Sn_MR_TCP,2020,0);
	  listen(sTCP);
	  isTCP_received=false;
	}

      if (IINCHIP_READ(Sn_SR(sTCP)) == SOCK_ESTABLISHED) // Quelqu'un s'est connecté en TCP
	{
	  cli();
	  while(!isTCP_received) // On boucle en attendant le message du client
	    {
	      if(recv(sTCP,buf,2)>0)
		{
		  type=TCP;
		  request(sTCP,buf,NULL,type); // On traite le message du client
		  isTCP_received=true;
		}
	    }
	}

	    
      if((datasize=recvfrom(sUDP,buf,sizeof(buf),addr,&port)) == 8) // Quelqu'un a envoyé 2 octets via UDP
	{
	  cli();
	  type=UDP;
	  printf("MESSAGE RECU VIA UDP %x %x \n",buf[0],buf[1]);
	  request(sUDP,buf,addr,type); // On traite le message du client
	}
	
    }
  close(sTCP);
  close(sUDP);
  return 0;
}