diff --git a/.mcuxpressoide_packages_support/info.properties b/.mcuxpressoide_packages_support/info.properties
index 4ba8becb3e76996e863847896311315eaf00e0ca..be7d125a480cdc097230f72c15b7346449c26559 100644
--- a/.mcuxpressoide_packages_support/info.properties
+++ b/.mcuxpressoide_packages_support/info.properties
@@ -1,5 +1,5 @@
 #MCUXpresso IDE
-#Wed Mar 19 11:08:44 CET 2025
+#Wed Apr 02 09:41:42 CEST 2025
 product.name=MCUXpresso IDE v11.10.0 [Build 3148] [2024-07-03]
 product.version=11.10.0
 product.build=3148
diff --git a/G3_TP1_labyrinth_etu/src/accelerometer.h b/G3_TP1_labyrinth_etu/src/accelerometer.h
index b0647413eac2d5ca4c0adfc8f545a05c108cd000..7da74982041d29adfcf78544806ffd32e01291e5 100644
--- a/G3_TP1_labyrinth_etu/src/accelerometer.h
+++ b/G3_TP1_labyrinth_etu/src/accelerometer.h
@@ -76,6 +76,13 @@ typedef struct
 	int16_t temperature;
 } accel_t;
 
+typedef struct
+{
+	int16_t accel_x;
+	int16_t accel_y;
+	int16_t accel_z;
+} accel_fx_t;
+
 int accel_init(void);
 
 /*
@@ -84,6 +91,7 @@ int accel_init(void);
  * Return: ACC_NOERROR if no error or error code
  */
 int accel_read(accel_t *accel);
+int accel_read_fx(accel_fx_t *accel);
 
 
 #endif /* ACCELEROMETER_H_ */
diff --git a/G3_TP1_labyrinth_etu/src/custom_rand.h b/G3_TP1_labyrinth_etu/src/custom_rand.h
index 08d1f799f60f3431802a6008cd95f4bed0a0cc96..70d036863bd98c708dfd905cc0fa0b07b860f277 100644
--- a/G3_TP1_labyrinth_etu/src/custom_rand.h
+++ b/G3_TP1_labyrinth_etu/src/custom_rand.h
@@ -1,5 +1,11 @@
-//---------------------------------------------------------------------------
-
+/*
+ * crc.h
+ *
+ *  Pseudo random algorithm. Should be used instead of rand() which is wrongly implemented.
+ *
+ *  Created on: sept 2020
+ *  Author: V. Pilloux
+ */
 #ifndef custom_randH
 #define custom_randH
 //---------------------------------------------------------------------------
diff --git a/G3_TP1_labyrinth_etu/src/ethmac.h b/G3_TP1_labyrinth_etu/src/ethmac.h
index 86c0018b4367c6bccab85c65eae3c4cb0e65fb06..f64c4933eb8596e33beaf27170a8759732563452 100644
--- a/G3_TP1_labyrinth_etu/src/ethmac.h
+++ b/G3_TP1_labyrinth_etu/src/ethmac.h
@@ -1,13 +1,15 @@
 /******************************************************************
  *****                                                        *****
- *****  Name: cs8900.h                                        *****
+ *****  Name: ethmac.h                                        *****
  *****  Ver.: 1.0                                             *****
  *****  Date: 07/05/2001                                      *****
+ *****  last release: 13.4.2018
  *****  Auth: Andreas Dannenberg                              *****
  *****        HTWK Leipzig                                    *****
  *****        university of applied sciences                  *****
  *****        Germany                                         *****
- *****        adannenb@et.htwk-leipzig.de                     *****
+ *****        adannenb@et.htwk-leipzig.de
+ *****        V. Pilloux                    *****
  *****  Func: header-file for cs8900.c                        *****
  *****                                                        *****
  ******************************************************************/
@@ -20,6 +22,8 @@
 #ifndef __ETHMAC_H
 #define __ETHMAC_H
 
+#include <stdbool.h>
+
 #define MYMAC_1              1                   // our ethernet (MAC) address
 #define MYMAC_2              2                   // (MUST be unique in LAN!)
 #define MYMAC_3              3
@@ -27,39 +31,23 @@
 #define MYMAC_5              5
 #define MYMAC_6              6
 
+#define NUM_FRAG  2			// forced to 2 as double buffering is required in this implementation
+
+typedef struct {
+	unsigned char *packet;
+	unsigned ctrl;
+} desc_t;
+
+typedef struct {
+	unsigned info;
+	unsigned hash;
+} stat_t;
+
+typedef struct {
+	desc_t desc[NUM_FRAG];
+	stat_t stat[NUM_FRAG];
+} eth_t;
 
-// *******
-// CodeRed -  defines for LPC1768 ethernet
-// *******
-
-/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */
-#define NUM_RX_FRAG         4           /* Num.of RX Fragments 4*1536= 6.0kB */
-#define NUM_TX_FRAG         2           /* Num.of TX Fragments 3*1536= 4.6kB */
-#define ETH_FRAG_SIZE       1536        /* Packet Fragment size 1536 Bytes   */
-
-#define ETH_MAX_FLEN        1536        /* Max. Ethernet Frame Size          */
-
-/* EMAC variables located in AHB SRAM bank 1*/
-// Below is base address for first silicon
-//#define RX_DESC_BASE        0x20004000
-// Below is base address for production silicon
-#define RX_DESC_BASE        0x2007c000
-#define RX_STAT_BASE        (RX_DESC_BASE + NUM_RX_FRAG*8)
-#define TX_DESC_BASE        (RX_STAT_BASE + NUM_RX_FRAG*8)
-#define TX_STAT_BASE        (TX_DESC_BASE + NUM_TX_FRAG*8)
-#define RX_BUF_BASE         (TX_STAT_BASE + NUM_TX_FRAG*4)
-#define TX_BUF_BASE         (RX_BUF_BASE  + NUM_RX_FRAG*ETH_FRAG_SIZE)
-
-/* RX and TX descriptor and status definitions. */
-#define RX_DESC_PACKET(i)   (*(unsigned int *)(RX_DESC_BASE   + 8*i))
-#define RX_DESC_CTRL(i)     (*(unsigned int *)(RX_DESC_BASE+4 + 8*i))
-#define RX_STAT_INFO(i)     (*(unsigned int *)(RX_STAT_BASE   + 8*i))
-#define RX_STAT_HASHCRC(i)  (*(unsigned int *)(RX_STAT_BASE+4 + 8*i))
-#define TX_DESC_PACKET(i)   (*(unsigned int *)(TX_DESC_BASE   + 8*i))
-#define TX_DESC_CTRL(i)     (*(unsigned int *)(TX_DESC_BASE+4 + 8*i))
-#define TX_STAT_INFO(i)     (*(unsigned int *)(TX_STAT_BASE   + 4*i))
-#define RX_BUF(i)           (RX_BUF_BASE + ETH_FRAG_SIZE*i)
-#define TX_BUF(i)           (TX_BUF_BASE + ETH_FRAG_SIZE*i)
 
 /* MAC Configuration Register 1 */
 #define MAC1_REC_EN         0x00000001  /* Receive Enable                    */
@@ -333,13 +321,11 @@
 #define LAN8720_ID          0x0007C0F0  /* PHY Identifier                    */
 
 
-void Init_EthMAC(void);
-void RequestSend(unsigned short FrameSize);
-unsigned short StartReadingFrame(void);
-void StopReadingFrame(void);
-unsigned int CheckIfFrameReceived(void); 
-void WriteFrame_EthMAC(unsigned char Data);
-unsigned char ReadFrame_EthMAC(void);
+void init_eth_mac(unsigned char *tx_double_buf, int double_len_tx, unsigned char *rx_double_buf,
+                  int double_len_rx);
+bool if_frame_rec(void);
+
+// power off the Ethernet module. Useful on LPC1769 board to remove glitches on power supply
 void ethernet_power_down(void);
 
 
diff --git a/G3_TP1_labyrinth_etu/src/fonts.h b/G3_TP1_labyrinth_etu/src/fonts.h
index 602ae770ff158d01c9526709b2d73b3e2ef57e34..08bbf3551931b061d784adddeb67ba2e0a374d3b 100644
--- a/G3_TP1_labyrinth_etu/src/fonts.h
+++ b/G3_TP1_labyrinth_etu/src/fonts.h
@@ -2,7 +2,7 @@
  * fonts.h
  *
  *  Created on: 19 avr. 2016
- *      Author: cma
+ *  Author: cma
  */
 
 #ifndef INC_FONTS_H_
@@ -12,7 +12,7 @@
 extern fontdatatype SmallFont[];
 extern fontdatatype BigFont[];
 
-#define SMALLFONT 0
-#define BIGFONT 1
+#define SMALLFONT 0		// Font Size	: 8x12
+#define BIGFONT 1			// Font Size	: 16x16
 
 #endif /* INC_FONTS_H_ */
diff --git a/G3_TP1_labyrinth_etu/src/labyrinth.c b/G3_TP1_labyrinth_etu/src/labyrinth.c
index 7c9f50ffd2a0351c1232683bd2bb6459863ff1e4..b8ad1d727be9566e593fd402d3dc85af7824dd72 100644
--- a/G3_TP1_labyrinth_etu/src/labyrinth.c
+++ b/G3_TP1_labyrinth_etu/src/labyrinth.c
@@ -85,6 +85,9 @@ static coord_fx_t labyrinth_points[]={
 void slave_info_rx(void *data, int len)
 {
 	// code executed when the slave sends an ethernet frame
+	if(len == sizeof(master_tx_t)){
+		master_tx_t mstr = (master_tx_t)data;
+	}
 }
 
 void Algo_main_ball(void *params);
@@ -112,7 +115,7 @@ int main(void)
 	//ethernet_init(..., slave_info_rx); // initialise ethernet and determine its callback function
 
 	draw_labyrinth(labyrinth_points);
-	init_traces(115200, 1, true); // initialise traces. Line to be removed if you implement your own traces
+	init_traces(115200, 1, false, true); // initialise traces. Line to be removed if you implement your own traces
 
 	accel_read(&ball_accel);	 // example: reading of the accelerometer
 
@@ -215,7 +218,7 @@ void Algo_main_ball(void *params){
 			ball->ball.pos.y = (LCD_MAX_HEIGHT - (ball->ball.radius+1));
 		}
 		lcd_filled_circle(round(ball->ball.pos.x), round(ball->ball.pos.y), ball->ball.radius, ball->ball.color);
-		vTaskDelay((portTickType)20/portTICK_RATE_MS);
+		vTaskDelay((portTickType)ball->ball.period/portTICK_RATE_MS);
 	}
 }
 
@@ -297,7 +300,7 @@ void Algo_bots(void *params){
 			ball->ball.pos.y = (LCD_MAX_HEIGHT - (ball->ball.radius+1));
 		}
 		lcd_filled_circle(round(ball->ball.pos.x), round(ball->ball.pos.y), ball->ball.radius, ball->ball.color);
-		vTaskDelay((portTickType)20/portTICK_RATE_MS);
+		vTaskDelay((portTickType)ball->ball.period/portTICK_RATE_MS);
 	}
 }
 
diff --git a/G3_TP1_labyrinth_etu/src/lcd.h b/G3_TP1_labyrinth_etu/src/lcd.h
index b07e4d8f7f58be869289a33ac38e1667e4cf321e..65a7ab8401884222bac8b1635d1cd2b20c281973 100644
--- a/G3_TP1_labyrinth_etu/src/lcd.h
+++ b/G3_TP1_labyrinth_etu/src/lcd.h
@@ -204,6 +204,12 @@ uint16_t *read_bmp_file(char *filename, uint16_t *width, uint16_t *height);
  */
 void display_bitmap16(uint16_t *bitmap, uint16_t x, uint16_t y, uint16_t width, uint16_t height);
 
+/* Description: save the whole screen in a ppm file
+ * Parameter: filename: name of the file to save. The file extension must be *.ppm.
+ * Note: the execution time of this function is long due to the use of fprintf()
+*/
+void save_screen_to_ppm(char *filename);
+
 /* Description: get pixel colors in a rectangle (16  bits format)
  * Parameter: x1: horizontal position of the top left corner
  *            y1: vertical position of the top left corner
diff --git a/G3_TP1_labyrinth_etu/src/ssp.h b/G3_TP1_labyrinth_etu/src/ssp.h
index 5584d85c06dbd3cb32c8d21c4c88a7bd509a14a2..b95764e23cd883cc1727e931a339060988e0577f 100644
--- a/G3_TP1_labyrinth_etu/src/ssp.h
+++ b/G3_TP1_labyrinth_etu/src/ssp.h
@@ -1,8 +1,13 @@
 /*
- * ssp.h
+ *  ssp.h
  *
- *  Created on: 12 mars 2014
- *      Author: christian
+ *  SSP driver. DMA can be used with a callback. Channels 2 and 3 are used.
+ *  WARNING: please add #include "dma_handler.h" ONLY ONCE somewhere in your code
+ *           to use DMA features. This way a the unique ISR for DMA will be declared
+ *           by Mylab library and be usable.
+ *
+ *  Created on: sept. 2020
+ *  Author: VP
  */
 
 #ifndef SSP_H_
@@ -16,9 +21,30 @@
 #define SSPSR_RFF               (1 << 3)
 #define SSPSR_BSY               (1 << 4)
 
+#define DMA_SSP_BAD_LENGTH 		-10
+#define DMA_SSP_OK				0
+
+typedef void (*ssp_dma_callback_t)(int err_stat);
+
+/* Description: setup a SSP port, possibly using DMA if a callback is defined.
+ * Parameters: spi_port: LPC_SSP0 or LPC_SSP1
+ *                       data_size_select: nb of bits/word of the transfer (example: 8)
+ * 						 scr: fix SSP CLK freq as: 50 MHz / (scr+1)
+ *                       callback: callback function called when a DMA transfer is finished
+ *                                 NULL otherwise.
+ */
+void ssp_init(LPC_SSP_TypeDef *spi_port, uint8_t data_size_select, uint8_t scr, ssp_dma_callback_t callback);
+
+
+// standard TX/RX functions with polling (no DMA)
+void ssp_send_buf(LPC_SSP_TypeDef *spi_port, uint8_t *buf, uint32_t length);
+void ssp_receive_buf(LPC_SSP_TypeDef *spi_port, uint8_t *buf, uint32_t length);
+uint8_t ssp_receive(LPC_SSP_TypeDef *spi_port);
+
+// DMA transfer from an SSP port to the memory: "callback" is called when the transfer ends
+int dma_copy_ssp_to_mem(LPC_SSP_TypeDef *spi_port, uint8_t *bytes, uint16_t bytes_len);
 
-void ssp_init_custom(uint8_t data_size_select, uint8_t scr);
-void ssp_send_buf(uint8_t *buf, uint32_t length);
-void ssp_receive_buf(uint8_t *buf, uint32_t length);
+// DMA transfer from SSP1 to SSP0 ports. "callback" is called when the transfer ends
+int dma_copy_ssp1_to_ssp0(uint16_t bytes_len);
 
 #endif /* SSP_H_ */
diff --git a/G3_TP1_labyrinth_etu/src/traces_ref.h b/G3_TP1_labyrinth_etu/src/traces_ref.h
index 814d3d157d10627fa2e0718452b19b9597559b10..710b34ffbe8382a95e90b376af0c20dd3037b5ae 100644
--- a/G3_TP1_labyrinth_etu/src/traces_ref.h
+++ b/G3_TP1_labyrinth_etu/src/traces_ref.h
@@ -19,9 +19,11 @@
  *              if interrupts are enabled.
  * Parameters: baudrate: valid UART baudrate [bit/s]
  *             timer_id: 0 to 3 to identify the timer used as a free running counter
+ *             short_traces: if true, enables TX short traces (only 5 bytes instead of 8). The time tick is 5 us.
+ *                           if false, long traces are enabled with a tick of 40 ns. See format description below.
  *             interrupt_enabled: enable UART0 interrupt if true
  */
-void init_traces(uint32_t baudrate, int timer_id, bool interrupt_enabled);
+void init_traces(uint32_t baudrate, int timer_id, bool short_traces, bool interrupt_enabled);
 
 /* Description: store a trace in a memory buffer
  *
@@ -35,11 +37,17 @@ void write_trace_ref(uint8_t trace_id, short val);
 void send_traces_to_uart0(void);
 
 // trace structure
+/* if long traces are enabled, time is a 32 bits field containing the number of time ticks elapsed at 40 ns
+ * if short traces enabled, the 'time' field is coded as follows:
+ *  - bit 0 gives signal activation (0 or 1),
+ *  - bits 5:1 signal ID,
+ *  - bits 31:6 time ticks of 5 us
+ *  'sig_idx' and 'val' are ignored */
 typedef struct {
 	uint8_t synchro;
 	uint8_t sig_idx;	/* bit 8 indicates other traces than VCD */
 	short val;
-	uint32_t time;
+	uint32_t time;		/* see comment above */
 } trace_t;
 
 #endif
diff --git a/G3_TP1_labyrinth_etu/src/uart.h b/G3_TP1_labyrinth_etu/src/uart.h
index ccd49ea0b9d00e460ae60ef185d8f1e6842380ad..540b265140442e79a0c94f37056b67ee168acfb4 100644
--- a/G3_TP1_labyrinth_etu/src/uart.h
+++ b/G3_TP1_labyrinth_etu/src/uart.h
@@ -12,7 +12,7 @@
 #define IIR_TX			0x2				// interrupt identification flags
 #define IIR_RX			0x4
 #define IS_TX_EMPTY 	(1<<5)			// status flags on LSR register
-#define IS_RX_NOT_EMPTY (1<<2)
+#define IS_RX_NOT_EMPTY (1<<0)
 
 /* Callback function prototype for UART interrupt */
 typedef void (*uart_callback_t)(int int_status);
@@ -44,6 +44,10 @@ void uart0_init_ref(uint32_t baudrate, uart_callback_t tx_callback, uart_callbac
  */
 void uart0_send_ref(uint8_t *data, uint32_t length);
 
+/* Description:		Block until receiving one byte (polling)
+*  Return:		    byte read */
+char uart0_rec_byte_ref();
+
 /* Description: stop UART0 interrupts. The switch off is only managed by the VIC. */
 void uart0_stop_interrupt();
 
diff --git a/G3_TP1_labyrinth_slave_etu/src/labyrinth_slave.c b/G3_TP1_labyrinth_slave_etu/src/labyrinth_slave.c
index ac49ec0041de70ee25585a5b32e0f5a38dd8afa3..72cb713f56cf3383d2721ff35b87a213d35d3946 100644
--- a/G3_TP1_labyrinth_slave_etu/src/labyrinth_slave.c
+++ b/G3_TP1_labyrinth_slave_etu/src/labyrinth_slave.c
@@ -47,6 +47,10 @@ static coord_fx_t labyrinth_points[]={
 };
 
 
+master_tx_t *mstr_now;
+master_tx_t *mstr_prev;
+bool flag = false;
+
 /* Description: Callback of ethernet module. This function is called when a message is received.
  * Each ball of the master send its own coordinates that are saved here.
  * Parameters: data: pointer on data received
@@ -54,9 +58,20 @@ static coord_fx_t labyrinth_points[]={
  */
 void master_info_rx(void *data, int len)
 {
-	// receive master_tx structure
+	if(len == sizeof(master_tx_t)){
+		if (mstr_now != NULL){
+			mstr_prev = mstr_now;
+		}
+		mstr_now = (master_tx_t*)data;
+		/*if(mstr_prev == NULL){
+			mstr_now = mstr_prev;
+		}*/
+		flag = true;
+	}
 }
 
+
+
 int main(void)
 {
 	init_lcd();
@@ -65,12 +80,22 @@ int main(void)
 		printf("Accelerometer initialisation failed!\n");
 		return 1;
 	}
-	//ethernet_init(..., master_info_rx);
+	master_tx_t double_buf_rx;
+	master_tx_t double_buf_tx;
+	int len_rx = sizeof(master_tx_t)*2;
+	int len_tx = 1;
+
+	ethernet_init(NULL, 0, &double_buf_rx, len_rx, master_info_rx);
 
 	draw_labyrinth(labyrinth_points);
 
 	while(1)
 	{
+		if(flag){
+			lcd_filled_circle(mstr_prev->ball_coord.x, mstr_prev->ball_coord.y, mstr_prev->radius, LCD_BLACK);
+			lcd_filled_circle(mstr_now->ball_coord.x, mstr_now->ball_coord.y, mstr_now->radius, mstr_now->color);
+			flag = false;
+		}
 
 	}
 }