# Il protocollo SNAP

Descrizione del protocollo:

* [Protocollo](https://pi3g.com/2019/04/23/introduction-to-the-snap-protocol/)

Struttura del pacchetto:

<img src="./snap1.png">

* SYNC: unique byte with the following structure: 01010100 (0x54), indicates the start of the packet
* HDB2, HDB1: The header definition bytes HDB2 and HDB1 define how long the packet will be, and which features will be used.
* DAB1: Destination Address Byte (0x12 per il PIC campione)
* SAB1: Source Address Byte (0x00 per il PC)
* DB1: Data Byte 1 – the payload for your application
* CRC2: high byte of CRC-16
* CRC1: low byte of CRC-16

Address 0 is reserved as a broadcast address and should not be used for anything else. (DAB / SAB)

Nel caso di Valter abbiamo per HDB2

* DD=01 (Un byte di indirizzo destinazione)
* SS=01 (Un byte di indirizzo sorgente)
* PP=00 Non usato
* AA
  * 00 = No Ack request (Tx)
  * 01 = Ack request (Tx)
  * 10 = Ack response (Rx)
  * 11 = NAK response (Rx) 

e per HDB1

* CMD=0
* EDM=error detection method 100 = 16 bit CRC.
* NDB=Numero di byte nel campo DB1 

<img src="./snap2.jpg">

Trasmissione di una richiesta dall'applicativo di Valter

Da Master a Nodo slave

	| 54   | 51   | 41   | 12      | 00       | 02       | 34   | C8   |
	| SYNC | HDB2 | HDB1 | PC ADDR | PIC ADDR | PAYLOAD  | CRC2 | CRC1 |

	HDB2=0x51
		1 byte di indirizzo destinazione
		1 byte di indirizzo sorgente
		Ack richiesto

	HDB=0x41
		1 byte dati
		16 bit CRC


## Calcolo del CRC16

	/ Online C compiler to run C program online
	#include <stdio.h>
	
	void Crc16(unsigned short *crc, char c) {
	
		int i,j;
	
		for (i=0; i!=8; c>>=1, i++) {
			j = (c^(*crc)) & 1;
			(*crc)>>=1;
	
			if (j) {
				(*crc)^=0xa001;
			}
		}
	}
	
	unsigned char data[]={0x51,0x41,0x12,0x00,0x02};
	
	int main() {
	    unsigned short crc=0x0;
	    
	    for (int i=0;i<5;i++) {
	        Crc16(&crc,data[i]);
	        printf("0x%02x\n",data[i]);
	    }
	    
	    // Write C code here
	    printf("0x%04x\n",crc);
	    
	    return 0;
	}


## Calcolo on-line del CRC-16

* <https://www.lammertbies.nl/comm/info/crc-calculation>

## Varie

* [Arduino SNAP Library](https://github.com/PHaroZ/arduino-snap)
* [ArduinoRS485 library]()

platformio.ini

	lib_deps =
	  arduino-libraries/ArduinoRS485 @ ^1.0.2

## Prove RS485 fatte con ESP-32

ESP-32 e RS485

* <https://www.mischianti.org/2020/05/11/interface-arduino-esp8266-esp32-rs-485/>

### Definizione Sercom0 RS485

In /home/pi/lora3a-boards/boards/lora3a-sensor1/include/periph_conf.h

aggiungere

	{    /* Virtual COM Port */
        .dev      = &SERCOM0->USART,
        .rx_pin   = GPIO_PIN(PA, 5),
        .tx_pin   = GPIO_PIN(PA, 4),
	#ifdef MODULE_PERIPH_UART_HW_FC
        .rts_pin  = GPIO_UNDEF,
        .cts_pin  = GPIO_UNDEF,
	#endif
        .mux      = GPIO_MUX_C,
        .rx_pad   = UART_PAD_RX_1,
        .tx_pad   = UART_PAD_TX_0,
        .flags    = UART_FLAG_NONE,
        .gclk_src = SAM0_GCLK_MAIN,
    }
