diff --git a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/assembleur.s b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/assembleur.s
index 51901bd8804c8e30693ce2a21203d718aeebdf5b..9a9a679d20d417863abe3dc3f1147adae349060c 100644
--- a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/assembleur.s
+++ b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/assembleur.s
@@ -9,18 +9,24 @@
 .global switch_to_user_mode
 .extern user_stack DATA				// this adress can be read like: ldr Rx, =user_stack
 
+switch_to_user_mode:
+    // Charge la valeur 3 dans r0 pour configurer le registre CONTROL
+    mov r0, #3
 
+    // Charge l'adresse du tableau user_stack dans r1
+    ldr r1, =user_stack
 
-switch_to_user_mode:
-	mov r0, #3
-	mov r3, USER_STACK_SIZE
-	lsl r3, #2   // r3 = USER_STACK_SIZE * 4
-	ldr r1, =user_stack
-	add r1, r1, r3
-	msr psp, r1
-    msr control, r0
+    // Déplace l'adresse de user_stack dans le registre PSP (Process Stack Pointer)
+    msr psp, r1
+
+    // Configure le registre CONTROL pour passer en mode utilisateur
+    msr control, r0                    // Bits [0:1] pour le mode utilisateur (p.721)
+
+    // Instruction de synchronisation entre les pipelines d'instructions
     isb
-	bx  lr
+
+    // Saut indirect vers l'adresse contenue dans le registre lr (return address)
+    bx  lr
 
 
 .equ bad_addr,0x90000
diff --git a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/mpu_user_console_etu.c b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/mpu_user_console_etu.c
index 5a9af5e541551c1b8bc96f5e57bcbca0d4ce81f7..dbb76fcc652c7cacf6a320f9ec1c039aa2d2c185 100644
--- a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/mpu_user_console_etu.c
+++ b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/mpu_user_console_etu.c
@@ -23,7 +23,7 @@
 #include "user_cmd.h"
 #include "uart.h"
 
-
+// Definition du registre MMFAR
 #define MMFAR *(unsigned *)0xE000ED34
 
 unsigned user_stack[USER_STACK_SIZE];
@@ -33,17 +33,34 @@ int *p_sram2=(int *)0x2007c000, a, *p_out_of_mem=(int *)0x80000;
 void switch_to_user_mode();
 void asm_test_fault();
 
+// Tableau global contenant les adresses provoquant une erreur
 uint32_t error_adresses[100];
 uint32_t error_count = 0;
 uint32_t error_codes[100];
 
 void MemManage_Handler()
 {
+	// Sauvegarde de l'adresse de l'erreur
 	error_adresses[error_count] = MMFAR;
+
+	// Sauvegarde du code de l'erreur dans le registre CFSR
 	error_codes[error_count] = SCB->CFSR;
-	SCB->CFSR = 0xFFFF;
+
+	// Affichage du code d'erreur en binaire sur les LEDs
 	LPC_GPIO2->FIOPIN = error_count;
+
+	// Incrémente l'index de l'erreur
 	error_count++;
+
+	// Acknowledge du registre CFSR
+	SCB->CFSR = 0xFFFF;
+
+	__asm volatile(
+			"mrs r0, psp\n"
+			"ldr r1, =user_starting_address\n" // recup le pointeur vers l'adresse de retour souhaitée
+			"ldr r1, [r1]\n"			// deref le pointeur pour recup l'adresse de retour
+			"str r1, [r0, #24]\n"
+	);
 }
 
 
@@ -61,10 +78,10 @@ void test_user_mode()
 	int n;
 
 	for (n=0; n<3; n++);	// OK
-	LPC_GPIO2->FIOPIN=0xaa;	// not OK (read only)
+//	LPC_GPIO2->FIOPIN=0xaa;	// not OK (read only)
 	a=LPC_GPIO2->FIOPIN;	// OK
 	a=*p_sram2;				// OK (unprivileged read only)
-	*p_sram2=5;				// not OK (privileged only for writing)
+//	*p_sram2=5;				// not OK (privileged only for writing)
 	n=LPC_TIM0->TC;			// not OK (privileged access only)
 }
 struct __FILE { int handle; /* Add whatever you need here */ };
@@ -76,65 +93,266 @@ unsigned simulated_memory_space[MAX_MEMORY_SIZE];
 
 int main(void)
 {
-
-		SCB->SHCSR |= (1 << 16);
 		// MPU configuration here...
-		// Region 0 (Flash)
-		MPU->RNR = 0;
-		MPU->RBAR = 0x00000000;
-		MPU->RASR = 0x5 << 24;
-		MPU->RASR = 0x01 << 19;
-		MPU->RASR = 9<<1; //car log2(512) = 9
-		MPU->RASR = 0x1;
-
-		// Region 1 (SRAM1)
-		MPU->RNR = 1;
-		MPU->RBAR = 0x10000000;
-		MPU->RASR = 0x3 << 24;
-		MPU->RASR = 0x01 << 19;
-		MPU->RASR = 5<<1; //car log2(32) = 5
-		MPU->RASR = 0x1;
-
-		// Region 2 (SRAM1)
-		MPU->RNR = 2;
-		MPU->RBAR = 0x2007C000;
-		MPU->RASR = 0x2 << 24;
-		MPU->RASR = 0x01 << 19;
-		MPU->RASR = 5<<1;
-		MPU->RASR = 0x1;
-
-
-		// Region 3 (GPIO)
-		MPU->RNR = 3;
-		MPU->RBAR = 0x2009C000;
-		MPU->RASR = 0x2 << 24;
-		MPU->RASR = 0x02 << 19;
-		MPU->RASR = 4<<1;
-		MPU->RASR = 0x1;
-
-
-		// Region 4 (périphériques dont timers)
-		MPU->RNR = 4;
-		MPU->RBAR = 0x40000000;
-		MPU->RASR = 0x1 << 24;
-		MPU->RASR = 0x02 << 19;
-		MPU->RASR = 5<<1;
-		MPU->RASR = 0x1;
-
-
-		// Region 5 (UART)
-		MPU->RNR = 5;
-		MPU->RBAR = 0x4000C000;
-		MPU->RASR = 0x3 << 24;
-		MPU->RASR = 0x02 << 19;
-		MPU->RASR = 9<<1;
-		MPU->RASR = 0x1;
-
-
-		MPU->CTRL |= 0x5;
+/*___________________________________________________________________________________________________*/
+		// Region 0 (flash) :
+		// Taille : 512 KB (524288 bytes)
+		// Type de mémoire : Non partagée, normal
+		// Type d'accès : Read
+
+		MPU->RNR = 0; // ID de la region
+
+		// N = Log2(Region size in bytes)
+		MPU->RBAR = (0x00000000);
+
+		// Reset des bits + enable
+		MPU->RASR = (1 << 0); // ENABLE
+
+		// Définition taille de région (Region size in bytes) = 2^(SIZE+1)
+		// 524288 = 2^(SIZE+1) --> SIZE = 18
+		MPU->RASR |= (18<<1); // SIZE
+
+		// Active toutes les sub-régions
+//		MPU->RASR &= (255 << 8); // SRD
+
+		// Mémoire non-partagée
+		// Outer and inner noncacheable
+//		MPU->RASR |= (0 << 16); // B
+//		MPU->RASR |= (0 << 17); // C
+//		MPU->RASR |= (0 << 18); // S
+		MPU->RASR |= (0b001 << 19); // TEX
+
+		// Read-only avec ou sans permissions
+		MPU->RASR |= (0b110 << 24); // AP
+
+		// Désactivation des instructions
+//		MPU->RASR |= (0b101 << 28); // XN
+
+/*___________________________________________________________________________________________________*/
+		// Region 1 (SRAM1) :
+		// Taille : 32 KB (32768 bytes)
+		// Type de mémoire : Non partagée, normal
+		// Type d'accès : Read / Write
+		MPU->RNR = 1; // ID de la region
+
+		// Registre RBAR à verifier
+//		MPU->RBAR = (0 << 4); // RNR modifié manuellement
+
+		// N = Log2(Region size in bytes)
+		MPU->RBAR = (0x10000000);
+
+		// Reset des bits + enable
+		MPU->RASR = (1 << 0); // ENABLE
+
+		// Définition taille de région (Region size in bytes) = 2^(SIZE+1)
+		// 32768 = 2^(SIZE+1) --> SIZlrE = 14
+		MPU->RASR |= (14<<1); // SIZE
+
+		// Active toutes les sub-régions
+//		MPU->RASR &= (255 << 8); // SRD
+
+		// Mémoire non-partagée
+		// Outer and inner noncacheable
+//		MPU->RASR |= (0 << 16); // B
+//		MPU->RASR |= (0 << 17); // C
+//		MPU->RASR |= (0 << 18); // S
+		MPU->RASR |= (0b001 << 19); // TEX
+
+		// Full access
+		MPU->RASR |= (0b011 << 24); // AP
+
+		// Désactivation des instructions
+//		MPU->RASR |= (0b101 << 28); // XN
+
+
+/*___________________________________________________________________________________________________*/
+		// Region 2 (SRAM2) :
+		// Taille : 16 KB (16384 bytes)
+		// Type de mémoire : Non partagée, normal
+		// Type d'accès : Read / Write en mode privilégié, Read	sinon
+		MPU->RNR = 2; // ID de la region
+
+		// Registre RBAR à verifier
+//		MPU->RBAR = (0 << 4); // RNR modifié manuellement
+
+		// N = Log2(Region size in bytes)
+		MPU->RBAR = (0x2007C000);
+
+		// Reset des bits + enable
+		MPU->RASR = (1 << 0); // ENABLE
+
+		// Définition taille de région (Region size in bytes) = 2^(SIZE+1)
+		// 16384 = 2^(SIZE+1) --> SIZE = 13
+		MPU->RASR |= (13<<1); // SIZE
+
+		// Active toutes les sub-régions
+//		MPU->RASR &= (255 << 8); // SRD
+
+		// Mémoire non-partagée
+		// Outer and inner noncacheable
+//		MPU->RASR |= (0 << 16); // B
+//		MPU->RASR |= (0 << 17); // C
+//		MPU->RASR |= (0 << 18); // S
+		MPU->RASR |= (0b001 << 19); // TEX
+
+		// Read-write avec permissions, read-only sans permissions
+		MPU->RASR |= (0b010 << 24); // AP
+
+		// Désactivation des instructions
+//		MPU->RASR |= (0b101 << 28); // XN
+
+/*___________________________________________________________________________________________________*/
+		// Region 3 (SRAM2) :
+		// Taille : 16 KB (16384 bytes)
+		// Type de mémoire : Non partagée, normal
+		// Type d'accès : Read / Write en mode privilégié, Read	sinon
+		MPU->RNR = 3; // ID de la region
+
+		// Registre RBAR à verifier
+//		MPU->RBAR = (0 << 4); // RNR modifié manuellement
+
+		// N = Log2(Region size in bytes)
+		MPU->RBAR = (0x20080000);
+
+		// Reset des bits + enable
+		MPU->RASR = (1 << 0); // ENABLE
+
+		// Définition taille de région (Region size in bytes) = 2^(SIZE+1)
+		// 16384 = 2^(SIZE+1) --> SIZE = 13
+		MPU->RASR |= (13<<1); // SIZE
+
+		// Active toutes les sub-régions
+//		MPU->RASR &= (255 << 8); // SRD
+
+		// Mémoire non-partagée
+		// Outer and inner noncacheable
+//		MPU->RASR |= (0 << 16); // B
+//		MPU->RASR |= (0 << 17); // C
+//		MPU->RASR |= (0 << 18); // S
+		MPU->RASR |= (0b001 << 19); // TEX
+
+		// Read-write avec permissions, read-only sans permissions
+		MPU->RASR |= (0b010 << 24); // AP
+
+		// Désactivation des instructions
+//		MPU->RASR |= (0b101 << 28); // XN
+
+/*___________________________________________________________________________________________________*/
+		// Region 4 (GPIO) :
+		// Taille : 16 KB (16384 bytes)
+		// Type de mémoire : Non partagée, device
+		// Type d'accès : Read / Write en mode privilégié, Read	sinon
+		MPU->RNR = 4; // ID de la region
+
+		// Registre RBAR à verifier
+//		MPU->RBAR = (0 << 4); // RNR modifié manuellement
+
+		// N = Log2(Region size in bytes)
+		MPU->RBAR = (0x2009C000);
+
+		// Reset des bits + enable
+		MPU->RASR = (1 << 0); // ENABLE
+
+		// Définition taille de région (Region size in bytes) = 2^(SIZE+1)
+		// 16384 = 2^(SIZE+1) --> SIZE = 13
+		MPU->RASR |= (13<<1); // SIZE
+
+		// Active toutes les sub-régions
+//		MPU->RASR &= (255 << 8); // SRD
+
+		// Mémoire non-partagée
+//		MPU->RASR |= (0 << 16); // B
+//		MPU->RASR |= (0 << 17); // C
+//		MPU->RASR |= (0 << 18); // S
+		MPU->RASR |= (0b010 << 19); // TEX
+
+		// Read-write avec permissions, read-only sans permissions
+		MPU->RASR |= (0b010 << 24); // AP
+
+		// Désactivation des instructions
+//		MPU->RASR |= (0b101 << 28); // XN
+
+/*___________________________________________________________________________________________________*/
+		// Region 5 (périphériques dont timers) :
+		// Taille : 32 KB (32768 bytes)
+		// Type de mémoire : Non partagée, device
+		// Type d'accès : Read / Write en mode privilégié uniquement
+		MPU->RNR = 5; // ID de la region
+
+		// Registre RBAR à verifier
+//		MPU->RBAR = (0 << 4); // RNR modifié manuellement
+
+		// N = Log2(Region size in bytes)
+		MPU->RBAR = (0x40000000);
+
+		// Reset des bits + enable
+		MPU->RASR = (1 << 0); // ENABLE
+
+		// Définition taille de région (Region size in bytes) = 2^(SIZE+1)
+		// 32768 = 2^(SIZE+1) --> SIZE = 14
+		MPU->RASR |= (14<<1); // SIZE
+
+		// Active toutes les sub-régions
+//		MPU->RASR &= (255 << 8); // SRD
+
+		// Mémoire non-partagée, device
+//		MPU->RASR |= (0 << 16); // B
+//		MPU->RASR |= (0 << 17); // C
+//		MPU->RASR |= (0 << 18); // S
+		MPU->RASR |= (0b010 << 19); // TEX
+
+		// Read-write avec permissions uniquement
+		MPU->RASR |= (0b001 << 24); // AP
+
+		// Désactivation des instructions
+//		MPU->RASR |= (0b101 << 28); // XN
+
+
+/*___________________________________________________________________________________________________*/
+		// Region 6 (UART) :
+		// Taille : 16 KB (16384 bytes)
+		// Type de mémoire : Non partagée, device
+		// Type d'accès : Read / Write
+		MPU->RNR = 6; // ID de la region
+
+		// Registre RBAR à verifier
+//		MPU->RBAR = (0 << 4); // RNR modifié manuellement
+
+		// N = Log2(Region size in bytes)
+		MPU->RBAR = (0x4000C000);
+
+		// Reset des bits + enable
+		MPU->RASR = (1 << 0); // ENABLE
+
+		// Définition taille de région (Region size in bytes) = 2^(SIZE+1)
+		// 16384 = 2^(SIZE+1) --> SIZE = 13
+		MPU->RASR |= (13<<1); // SIZE
+
+		// Active toutes les sub-régions
+//		MPU->RASR &= (255 << 8); // SRD
+
+		// Mémoire non-partagée
+//		MPU->RASR |= (0 << 16); // B
+//		MPU->RASR |= (0 << 17); // C
+//		MPU->RASR |= (0 << 18); // S
+		MPU->RASR |= (0b010 << 19); // TEX
+
+		// Full access
+		MPU->RASR |= (0b011 << 24); // AP
+
+		// Désactivation des instructions
+//		MPU->RASR |= (0b101 << 28); // XN
+
+
+		// Activation de l’exception de gestion d’erreur mémoire MemManage_Handler()
+		SCB->SHCSR |= (1 << 16); // MEMFAULTENA
+		MPU->CTRL |= (1<<0); // Enables MPU
+
+		LPC_GPIO2->FIODIR = 0xff;
+		LPC_GPIO2->FIOPIN = 0xf;
 
 	// testing memory accesses in supervisor mode:
-	//test_supervisor_mode();	// to be removed after checking
+//	test_supervisor_mode();	// to be removed after checking
 
 	user_start:
 	user_starting_address=&&user_start;		// save the address of the label 'user_start' (for exercise 2)
@@ -142,7 +360,7 @@ int main(void)
 	switch_to_user_mode();					// to be implemented
 
 	// testing memory accesses in user mode:
-	//test_user_mode();		// to be removed after checking
+//	test_user_mode();		// to be removed after checking
 
 	for (unsigned i = 0; i < MAX_MEMORY_SIZE; ++i) {
 	        simulated_memory_space[i] = i; // Remplissage avec des données factices
diff --git a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/user_cmd.c b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/user_cmd.c
index 83b5467337435ed2f9c88833cab4da722fbc5aa4..5b03c92f35a0117bb7fdb53ad678031a6296c4e1 100644
--- a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/user_cmd.c
+++ b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/user_cmd.c
@@ -1,23 +1,21 @@
+/*
+ * user_interpreter.c
+ *
+ *  Created on: 12 nov. 2023
+ *      Author: Vincent
+ */
+
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
 #include <stdbool.h>
+#include <stdarg.h>
+#include "uart.h"
+#include "user_cmd.h"
 
-#define MAX_INPUT_LENGTH 200
-#define MAX_ERRORS 20
-
-// Fausse mémoire et compteur d'erreur pour la simulation
-unsigned simulated_memory_space[1024] = {0};
-unsigned fault_address_buffer[MAX_ERRORS] = {0};
-unsigned fault_code_buffer[MAX_ERRORS] = {0};
-unsigned fault_count = 0;
-bool is_supervisor_mode = false; // false pour le mode utilisateur, true pour le mode superviseur
-
-// Prototypes de fonctions pour la commutation de mode et l'affichage des erreurs
-void switch_mode();
-void display_status();
-unsigned read_memory(unsigned addr);
-void write_memory(unsigned addr, unsigned value);
+#define PRINT_SYNTAX_ERROR() PRINT("Syntax error! Expected syntax is either <8 characters hexadecimal address> for reading\n or " \
+									"<8 characters hexadecimal address>=<8 characters hexadecimal value> for writing\n");
+bool is_supervisor_mode=false;
 
 void SVC_Handler()
 {
@@ -25,72 +23,53 @@ void SVC_Handler()
 }
 
 
-// Fonction pour basculer entre les modes utilisateur et superviseur
-void switch_mode() {
-    is_supervisor_mode = !is_supervisor_mode;
-    printf("Switched to %s mode.\n", is_supervisor_mode ? "Supervisor" : "User");
-}
-
-// Fonction pour afficher les erreurs d'accès mémoire
-void display_status() {
-    if (fault_count == 0) {
-        printf("No access errors recorded.\n");
-    } else {
-        printf("Access errors recorded:\n");
-        for (unsigned i = 0; i < fault_count; ++i) {
-            printf("Error %u: Address: 0x%08X, Code: 0x%08X\n", i, fault_address_buffer[i], fault_code_buffer[i]);
-        }
-    }
-}
-
-// Modifiez les fonctions read_memory et write_memory pour inclure la validation de la MPU
-unsigned read_memory(unsigned addr) {
-    if (!validate_mpu_address(addr)) {
-        printf("MPU violation: Read access denied for address 0x%08X.\n", addr);
-        return 0; // Retourne 0 pour indiquer un échec de lecture
-    }
-    return simulated_memory_space[addr]; // Lecture réussie
-}
+void exec_user_read_write()
+{
+	char str[200];
+	int i=0, coma_nb=0, value_idx;
+	unsigned addr, value;
 
-void write_memory(unsigned addr, unsigned value) {
-    if (!validate_mpu_address(addr)) {
-        printf("MPU violation: Write access denied for address 0x%08X.\n", addr);
-        return; // Échec de l'écriture, sortie anticipée
-    }
-    simulated_memory_space[addr] = value; // Écriture réussie
-}void exec_user_read_write() {
-    char input[MAX_INPUT_LENGTH];
-    unsigned addr, value;
+	PRINT("Write an hexadecimal address for reading <addr> or <addr>,<value> for writing (%s):\n", is_supervisor_mode?"Supervisor":"User");
 
-    printf("Enter command (%s mode): ", is_supervisor_mode ? "Supervisor" : "User");
-    if (fgets(input, sizeof(input), stdin) == NULL) {
-        printf("Error reading input.\n");
-        return;
-    }
+	fflush(stdin);
+	fscanf(stdin, "%s",str);
 
-    // Enlever le caractère de nouvelle ligne si présent
-    input[strcspn(input, "\n")] = '\0';
+	for (i=0; i<strlen(str); i++)
+	{
+		if (str[i] == ',')
+		{
+			if (i==0 || ++coma_nb>1)
+			{
+				PRINT_SYNTAX_ERROR();
+				return;
+			}
+			str[i]=0;
+			value_idx=i+1;
+		} else if (!isxdigit(str[i]))
+		{
+			PRINT_SYNTAX_ERROR();
+			return;
+		}
+	}
+	if ((coma_nb&(i<2)) || i>17)
+	{
+		PRINT_SYNTAX_ERROR();
+		PRINT("(Bad length!)");
+		return;
+	}
 
-    // Traitement des commandes "switch" et "status"
-    if (strcmp(input, "switch") == 0) {
-        switch_mode();
-    } else if (strcmp(input, "status") == 0) {
-        display_status();
-    } else {
-        char *comma = strchr(input, ',');
-        if (comma) {
-            *comma = '\0'; // Séparer la chaîne en deux parties
-            addr = strtoul(input, NULL, 16);
-            value = strtoul(comma + 1, NULL, 16);
-            write_memory(addr, value);
-            printf("Written 0x%08X to address 0x%08X\n", value, addr);
-        } else if (isxdigit(input[0])) {
-            addr = strtoul(input, NULL, 16);
-            value = read_memory(addr);
-            printf("Value at address 0x%08X: 0x%08X\n", addr, value);
-        } else {
-            printf("Syntax error! Please check your input format.\n");
-        }
-    }
+	sscanf(str, "%x", &addr);
+	if (!coma_nb)					// if read
+	{
+		PRINT("reading address: 0x%08x\n", addr);
+		PRINT("value read: 0x%08x\n", *(unsigned *)addr);
+	}
+	else							// write
+	{
+		sscanf(str+value_idx, "%x", &value);
+		PRINT("writing address: 0x%08x with 0x%08x\n", addr, value);
+		*(unsigned *)addr=value;
+	}
 }
 
+