tangibleInterface.c 5.13 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 isComMem = false; // Commande déjà enregistrée ou non?
bool sleep = true; //Etat de l'interface : true = mode sommeil / false = mode eveillé
uint8 comMem[2]; //Commande en mémoire
char msg[30]={'\0'};

void init_led(void)
{
  DDRD = 0xFF;
  PORTD = 0x08;
}

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 requestTCP(SOCKET s,uint8 rq [2])
{
  
  if (!isComMem) //Aucune commande en mémoire
    {
      isComMem = true;
      comMem[0] = rq[0]; comMem[1] = rq [1];
    }
  
  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];
  switch(x)
    {
    case 0: // GETSTATUS
      if (sleep==false)
	{
	  strcpy(msg,"\x20\x01");
	}
      else
	{
	  strcpy(msg,"\x20\x00");				    
	}
      send(s,msg,sizeof(char)*strlen(msg)); // REPONSE JE DORS OU NON
      disconnect(s);
      comMem[0] = rq[0]; comMem[1] = rq [1]; // SAVE
      break;
      
    case 3:
      printf("Request ComMem\n");
      strcpy(msg,comMem);
      send(s,msg,sizeof(char)*strlen(msg));
      comMem[0] = rq[0]; comMem[1] = rq [1]; // SAVE
      break;
    }
}

void requestUDP(uint8_t addr[IPV4_SIZE],uint8 rq [2])
{
  SOCKET s = 2; //Socket TCP pour réponse à la broadcast UDP
  if (!isComMem) //Aucune commande en mémoire
    {
      isComMem = true;
      comMem[0] = rq[0]; comMem[1] = rq [1];
    }
  
  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;
  
  switch(x)
    {
      
    case 0: // GETSTATUS ( Via UDP broadcast, on répond en TCP ! )
      if(socket(s,Sn_MR_TCP,2020,0) == 0)
	{
	  printf("SOCKET NON INITILIASEE \n");
	}
      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);
	}
      comMem[0] = rq[0]; comMem[1] = rq [1]; //save
      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;
	}
      comMem[0] = rq[0]; comMem[1] = rq [1]; //save 
      break;
      
    case 5: // SETCOMMANDE
      if (sleep == false)
	{
	  OCR1A = NB_TICK - 53*(int)per;
	  comMem[0] = rq[0]; comMem[1] = rq [1]; //save 
	}
      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 buf[2]; // <- Sert à stocker les deux octets recus via TCP & UDP
  uint16 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
  bool isTCP_received = false; // <- Msg TCP reçu ou non? Permet la réouverture de la socket TCP pour permettre la réécoute TCP


  /*init*/
  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;
    }
  
  while(1)
    {
      socket(sTCP,Sn_MR_TCP,2020,0);
      listen(sTCP);
      isTCP_received=false;
      while(!isTCP_received)
	{
	  sei();
	  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)
		  {
		      printf("MESSAGE RECU VIA TCP %x %x \n",buf[0],buf[1]);
		      requestTCP(sTCP,buf); // 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();
	      printf("MESSAGE RECU VIA UDP %x %x \n",buf[0],buf[1]);
	      requestUDP(addr,buf); // On traite le message du client
	      isTCP_received = true;
	    }
	}
    }
  close(sTCP);
  close(sUDP);
  return 0;
}