diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3695cb6d85a68baced219cc0d63dc3ad4d888c7f..34e746e3b969f318213433bd683d6b9fc3097b73 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -290,6 +290,9 @@ sbs_target(test-i2c-f7 stm32f767zi_nucleo)
 add_executable(test-wiz5500 src/tests/drivers/test-wiz5500.cpp)
 sbs_target(test-wiz5500 stm32f767zi_gemini_gs)
 
+add_executable(test-Qflash src/tests/drivers/QuadSpi-Flash/test-Qflash.cpp)
+sbs_target(test-Qflash stm32f767zi_compute_unit)
+
 #-----------------------------------------------------------------------------#
 #                               Tests - Events                                #
 #-----------------------------------------------------------------------------#
diff --git a/cmake/boardcore.cmake b/cmake/boardcore.cmake
index 309394fcfbd8a65727d0878fc11c102e9f6906cc..0de9353381847617ad5ac8c019146b2c44847c15 100644
--- a/cmake/boardcore.cmake
+++ b/cmake/boardcore.cmake
@@ -65,6 +65,7 @@ set(BOARDCORE_SRC
     ${BOARDCORE_PATH}/src/shared/drivers/i2c/I2CDriver-f7.cpp
     ${BOARDCORE_PATH}/src/shared/drivers/i2c/I2C.cpp
     ${BOARDCORE_PATH}/src/shared/drivers/WIZ5500/WIZ5500.cpp
+    ${SBS_BASE}/src/tests/drivers/QuadSpi-flash/qspi-flash.cpp
 
     # Events
     ${BOARDCORE_PATH}/src/shared/events/EventBroker.cpp
diff --git a/src/tests/boards/test-qspi-flash.cpp b/src/tests/boards/test-qspi-flash.cpp
index 293ed82149aec98b1a017ddaafcad681225191fa..ca2255a98e60929141f016a2aac4d43c7a7e69e6 100644
--- a/src/tests/boards/test-qspi-flash.cpp
+++ b/src/tests/boards/test-qspi-flash.cpp
@@ -25,6 +25,16 @@
  * proper driver for the flash will need to be developed!
  */
 
+/**
+ * A tiny look at the protocol
+ * QUADSPI is a protocol to manage the communication between MCU and a flash memory. 
+ * The peripheral takes care of all the pins involved, so you don't even need to toggle
+ * the slave-select pin. In indirect mode every communication is handled by the firmware  
+ * and registers, also every communication is triggered as soon as the peripheral has  
+ * enough information to perform a command. 
+ * Other two modes are available: polling mode and mapped mode.   
+*/
+
 #include <miosix.h>
 #include <utils/ClockUtils.h>
 
@@ -49,10 +59,6 @@ GpioPin flash_io1(GPIOF_BASE, 9);
 GpioPin flash_io2(GPIOF_BASE, 7);
 GpioPin flash_io3(GPIOF_BASE, 6);
 
-#include <miosix.h>
-
-using namespace miosix;
-
 int main()
 {
     flash_ncs.mode(Mode::ALTERNATE);
@@ -79,7 +85,7 @@ int main()
     RCC_SYNC();
 
     delayMs(2 * 1000);
-    printf("Starting\n");
+    printf("Starting!\n");
 
     QUADSPI->CR |= QUADSPI_CR_ABORT;  // Abort ongoing commands
 
@@ -91,18 +97,16 @@ int main()
     QUADSPI->CR  = 0;
     QUADSPI->DCR = 0;
     QUADSPI->CCR = 0;
+    QUADSPI->DLR = 0;
 
     // QSPI peripheral initialization
     QUADSPI->CR |=
         QUADSPI_CR_SSHIFT |             // Wait a full cycle to read
-        3 << QUADSPI_CR_PRESCALER_Pos;  // QSPI clock = 216MHz / 3 = 72MHz
+        3 << QUADSPI_CR_PRESCALER_Pos;  // QSPI clock = 216MHz / 4 = 54MHz
     // QUADSPI->DCR |=
     //     21 << QUADSPI_DCR_FSIZE_Pos;  // Flash size 32Mb = 4MB = 2^(21+1)
     //     bytes
 
-    // Enable the peripheral
-    QUADSPI->CR |= QUADSPI_CR_EN;
-
     // Send read ID command - 0x9Fcl
     {
         QUADSPI->CCR |= 1 << QUADSPI_CCR_FMODE_Pos |   // Indirect read mode
@@ -111,22 +115,32 @@ int main()
                         0 << QUADSPI_CCR_ADMODE_Pos |  // No address
                         1 << QUADSPI_CCR_IMODE_Pos;    // Instruction on 1-wire
 
-        QUADSPI->DLR = 23;  // Expect to receive 24 bytes
+        // Enable the peripheral (IT HAS TO BE DONE AFTER SETTING CCR REGISTER)
+        QUADSPI->CR |= QUADSPI_CR_EN;
 
-        printf("CCR: %lx\n", QUADSPI->CCR);
+        QUADSPI->DLR = 2;  // Expect to receive 3 bytes regarding ID of the flash 
 
         // Trigger communication start by writing the instruction
         QUADSPI->CCR |= 0x9F << QUADSPI_CCR_INSTRUCTION_Pos;
 
-        // Wait for the transaction to complete, and disable the peripheral.
-        int count = 0;
-        while (QUADSPI->SR & QUADSPI_SR_BUSY)
-            count++;
+        // wait till the end of the communication
+        while (!(QUADSPI->SR & (1 << QUADSPI_SR_TCF_Pos)))
+            ;
+
+        // reset transfer complete flag (TCF)
+        QUADSPI->FCR &= ~(1 << QUADSPI_FCR_CTCF_Pos); 
+
+        // until there are some bytes in the quadspi buffer (FIFO) keep reading them
+        while (QUADSPI->SR & (63 << QUADSPI_SR_FLEVEL_Pos))
+        {
+            printf("Data: 0x%lx\n", QUADSPI->DR);
+        }
 
         // Disable the peripheral
         QUADSPI->CR &= ~QUADSPI_CR_EN;
 
-        printf("Data: 0x%lx %d\n", QUADSPI->DR, count);
+        printf("QUADSPI disabled.\n");
+        printf("end!\n"); 
     }
 
     while (true)
diff --git a/src/tests/drivers/QuadSpi-Flash/qspi-flash.cpp b/src/tests/drivers/QuadSpi-Flash/qspi-flash.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..da25f93452f4a24e2c4527638bb34bf6db557deb
--- /dev/null
+++ b/src/tests/drivers/QuadSpi-Flash/qspi-flash.cpp
@@ -0,0 +1,217 @@
+#include "qspi-flash.h"
+
+using namespace miosix;
+using namespace Boardcore;
+using namespace FlashMemory;
+
+
+/**
+ * QSPI Flash pins
+ *
+ * FLASH_NSS - PB10 - AF9  - QUADSPI_BK1_NCS
+ * FLASH_CLK - PF10 - AF9  - QUADSPI_CLK
+ * FLASH_IO0 - PF8  - AF10 - QUADSPI_BK1_IO0
+ * FLASH_IO1 - PF9  - AF10 - QUADSPI_BK1_IO1
+ * FLASH_IO2 - PF7  - AF9  - QUADSPI_BK1_IO2
+ * FLASH_IO3 - PF6  - AF9  - QUADSPI_BK1_IO3
+ */
+
+GpioPin flash_ncs(GPIOB_BASE, 10);
+GpioPin flash_sck(GPIOF_BASE, 10);
+GpioPin flash_io0(GPIOF_BASE, 8);
+GpioPin flash_io1(GPIOF_BASE, 9);
+GpioPin flash_io2(GPIOF_BASE, 7);
+GpioPin flash_io3(GPIOF_BASE, 6);
+
+
+void QSPI::enable() { QUADSPI->CR |= QUADSPI_CR_EN; }
+
+
+void QSPI::disable() { QUADSPI->CR &= ~QUADSPI_CR_EN; }
+
+
+void QSPI::init() {
+
+    // init GPIO peripheral pins
+    flash_ncs.mode(Mode::ALTERNATE);
+    flash_ncs.alternateFunction(9);
+    flash_ncs.speed(Speed::_100MHz);
+    flash_sck.mode(Mode::ALTERNATE);
+    flash_sck.alternateFunction(9);
+    flash_sck.speed(Speed::_100MHz);
+    flash_io0.mode(Mode::ALTERNATE);
+    flash_io0.alternateFunction(10);
+    flash_io0.speed(Speed::_100MHz);
+    flash_io1.mode(Mode::ALTERNATE);
+    flash_io1.alternateFunction(10);
+    flash_io1.speed(Speed::_100MHz);
+    flash_io2.mode(Mode::ALTERNATE);
+    flash_io2.alternateFunction(9);
+    flash_io2.speed(Speed::_100MHz);
+    flash_io3.mode(Mode::ALTERNATE);
+    flash_io3.alternateFunction(9);
+    flash_io3.speed(Speed::_100MHz);
+
+    // init peripheral clock 
+    ClockUtils::enablePeripheralClock((QUADSPI_TypeDef*)QSPI_BASE);
+
+    RCC_SYNC();
+
+    Thread::sleep(200); 
+
+    // abort possible ongoing command 
+    QUADSPI->CR |= QUADSPI_CR_ABORT;
+    
+    // Wait while aborted
+    while (QUADSPI->CR & QUADSPI_CR_ABORT) {;}  
+    
+    // disable peripheral 
+    QSPI::disable(); 
+
+    // reset configuration registers 
+    QUADSPI->CR  = 0;
+    QUADSPI->DCR = 0;
+    QUADSPI->CCR = 0;
+    QUADSPI->DLR = 0;
+    
+    // reset transfer complete flag (TCF)
+    QUADSPI->FCR &= ~(1 << QUADSPI_FCR_CTCF_Pos); 
+
+    // peripheral default initialization
+    QUADSPI->CR |= QUADSPI_CR_SSHIFT |  // Wait a full cycle to read
+        3 << QUADSPI_CR_PRESCALER_Pos;  // QSPI clock = 216MHz / 4 = 54MHz
+    // QUADSPI->DCR |=
+    //     21 << QUADSPI_DCR_FSIZE_Pos;  // Flash size 32Mb = 4MB = 2^(21+1)
+    //     bytes
+
+}
+
+
+void QSPI::waitBusy() {
+    while(!(QUADSPI->SR & (1 << QUADSPI_SR_BUSY_Pos))) {;}
+}
+
+
+void QSPI::waitTransfer() {
+
+    // wait till the end of the communication
+    while (!(QUADSPI->SR & (1 << QUADSPI_SR_TCF_Pos))) {;}
+
+    // reset transfer complete flag (TCF)
+    QUADSPI->FCR &= ~(1 << QUADSPI_FCR_CTCF_Pos); 
+
+}
+
+
+// constructor class qspi_flash
+qspi_flash::qspi_flash() {;}
+
+
+uint8_t qspi_flash::read_status_reg() {
+     
+    // indirect read mode, la comunicazione comincia dopo aver scritto l'istruzione 
+    // nel CCR register. 
+    // 1 invio Read status register command
+    // ricevo un byte di dati con il valore dello status register. 
+
+    QSPI::disable(); 
+
+    QSPI::init();  
+
+    QUADSPI->CCR |= 1 << QUADSPI_CCR_FMODE_Pos |   // Indirect read mode
+                        1 << QUADSPI_CCR_DMODE_Pos |   // Data on 1-wire
+                        0 << QUADSPI_CCR_ABMODE_Pos |  // No alternate bytes
+                        0 << QUADSPI_CCR_ADMODE_Pos |  // No address
+                        1 << QUADSPI_CCR_IMODE_Pos;    // Instruction on 1-wire
+    
+    // Expect to receive 1 byte (flash status register)
+    QUADSPI->DLR = 0;   
+
+    // DEVE ESSERE FATTO PRIMA DI SCRIVERE L'ISTRUZIONE NEL REGISTRO, 
+    // PERCHè IN QUESTO CASO LA COMUNICAZIONE COMINCIA SCIVENDO L'ISTRUZIONE IN CCR 
+    QSPI::enable();
+    
+    // Trigger communication start by writing the instruction
+    QUADSPI->CCR |= Commands::READ_STATUS_REG << QUADSPI_CCR_INSTRUCTION_Pos; 
+
+    // wait till data trasfer is complete
+    QSPI::waitTransfer();
+
+    return QUADSPI->DR; 
+}
+
+
+void qspi_flash::write_enable() {
+    
+    // in indirect write mode with no data or address phase (DMODE = 0, ADMODE = 0) the 
+    // communication starts whenever the CCR register is written. 
+    // 1 send wren command
+    // 2 read status register 
+    // 3 wait for bit WEL = 1
+    // poi program/erase commands 
+    
+    QSPI::disable(); 
+    
+    QSPI::init(); // reset previous configurations and init clock and gpio
+
+    // indirect write mode, istruction on 1 wire, no data, no address, no alternate bytes 
+    QUADSPI->CCR |= 1 << QUADSPI_CCR_IMODE_Pos; 
+
+    QSPI::enable(); 
+
+    // start communication writing the instruction to CCR register busy bit = 1
+    QUADSPI->CCR |= Commands::WRITE_ENABLE; 
+
+    QSPI::waitBusy(); 
+
+    QSPI::disable();
+
+    printf("prima del whileeee\n"); 
+
+    // read status register until WEL is set (write enable latch)
+    uint8_t status = read_status_reg(); 
+    do {
+        Thread::sleep(1); 
+        status = read_status_reg();
+    }
+    while(!(status & 1 << 1)); // WEL_pos = 1 è il secondo bit
+}
+
+
+
+uint32_t qspi_flash::readID() {
+
+    QSPI::disable(); 
+
+    QSPI::init(); 
+
+    QUADSPI->CCR |= 1 << QUADSPI_CCR_FMODE_Pos |   // Indirect read mode
+                        1 << QUADSPI_CCR_DMODE_Pos |   // Data on 1-wire
+                        0 << QUADSPI_CCR_ABMODE_Pos |  // No alternate bytes
+                        0 << QUADSPI_CCR_ADMODE_Pos |  // No address
+                        1 << QUADSPI_CCR_IMODE_Pos;    // Instruction on 1-wire
+    
+    // Expect to receive 3 bytes regarding ID of the flash
+    QUADSPI->DLR = 2;   
+
+    // DEVE ESSERE FATTO PRIMA DI SCRIVERE L'ISTRUZIONE NEL REGISTRO, 
+    // PERCHè IN QUESTO CASO LA COMUNICAZIONE COMINCIA SCIVENDO L'ISTRUZIONE IN CCR 
+    QSPI::enable();
+    
+    // Trigger communication start by writing the instruction
+    QUADSPI->CCR |= Commands::READ_ID << QUADSPI_CCR_INSTRUCTION_Pos; 
+
+    // wait till communication is ended
+    QSPI::waitTransfer(); 
+
+    // if there are some bytes in the quadspi buffer (FIFO), read them
+    if (QUADSPI->SR & (63 << QUADSPI_SR_FLEVEL_Pos)) {
+        uint32_t myID = QUADSPI->DR; 
+        QSPI::disable();
+        return myID;
+    }
+    else {
+        QSPI::disable();
+        return -1; 
+    }
+}
\ No newline at end of file
diff --git a/src/tests/drivers/QuadSpi-Flash/qspi-flash.h b/src/tests/drivers/QuadSpi-Flash/qspi-flash.h
new file mode 100644
index 0000000000000000000000000000000000000000..f710070ac0b9353d08c12e9b72ec6a9a6154f470
--- /dev/null
+++ b/src/tests/drivers/QuadSpi-Flash/qspi-flash.h
@@ -0,0 +1,128 @@
+#include <miosix.h>
+#include <utils/ClockUtils.h>
+
+#pragma once
+
+using namespace miosix;
+using namespace Boardcore;
+
+
+/*  model of flash memory on compute unit: MX25R3235FM1IL0 4MB
+ *   FLASH memory space organisation:
+ *   - number of byte in the memory: 4.194.304 >> about 4 MB
+ *   - "pages"   of 256 Byte each   - number of pages:   16.384
+ *   - "sector"  of about 4  KByte  - number of sector:   1.024
+ *   - "block32" of about 32 KByte  - number of block32:    128
+ *   - "block64" of about 64 KByte  - number of block64:     64
+*/
+
+namespace FlashMemory {
+
+static const uint32_t PAGES_PER_SECTOR    = 16;
+static const uint32_t SECTORS_PER_BLOCK32 = 8;
+
+static const uint32_t BLOCK32_NUM = 128;
+static const uint32_t BLOCK64_NUM = 64;
+static const uint32_t SECTORS_NUM = 1024;
+static const uint32_t PAGES_NUM   = 16384;
+static const uint32_t BYTES_NUM   = 4194304;
+
+// sizes of each area in byte
+static const uint32_t PAGE_SIZE    = 256;
+static const uint32_t SECTOR_SIZE  = PAGE_SIZE * PAGES_PER_SECTOR;
+static const uint32_t BLOCK32_SIZE = SECTOR_SIZE * SECTORS_PER_BLOCK32;
+static const uint32_t BLOCK64_SIZE = BLOCK32_SIZE * 2;
+
+// memory size in byte
+static const uint32_t MEMORY_SIZE = BLOCK64_SIZE * BLOCK64_NUM;  // about 4 MB
+
+};
+
+
+// QUADSPI peripheral utility-stuff
+namespace QSPI {
+
+    // enable/ disbale quadspi
+    void enable(); 
+    void disable(); 
+    
+    // init peripheral clock and GPIO 
+    void init(); 
+
+    // wait till the current operation is ended
+    void waitBusy(); 
+    
+    // wait till all the expected bytes have been transferred 
+    void waitTransfer(); 
+
+}
+
+
+class qspi_flash {
+
+public:
+
+    // constructor 
+    qspi_flash();
+
+    // enable writing on memory 
+    void write_enable(); 
+
+    // read unique device ID
+    uint32_t readID();
+
+private:  
+    
+    // disable writing on memory 
+    void write_disable(); 
+
+    // read status register of the flash memory 
+    uint8_t read_status_reg();  
+    
+    // most important flash memory commands 
+    enum Commands
+    {
+        // read unique ID of the memory 
+        READ_ID = 0x9F,
+
+        // write enable, needs to be executed before modify any data 
+        WRITE_ENABLE  = 0x06,
+        
+        // write disable
+        WRITE_DISABLE = 0x04,
+
+        // read status register 
+        READ_STATUS_REG = 0x05,
+
+        // write status register 
+		WRITE_STATUS_REG = 0x01,
+
+        // read configuration register 
+        READ_CONFIG_REGISTER = 0x15,
+
+        // read data from memory  
+        READ = 0x03,
+
+        // write a page on memory.
+        PROGRAM_PAGE = 0x02,
+
+        // erase a specific sector of the memory 
+        SECTOR_ERASE = 0x20, 
+
+        // erase all data on the chip - THIS COULD TAKE A LONG TIME !
+        ERASE_CHIP = 0xC7,
+
+        // reset enable command
+        RESET_ENABLE = 0x66,
+
+        // reset memory, reset enable command should be executed first
+        RESET_MEMORY = 0x99
+    };
+
+    // important bits to be checked in the memory status register 
+    enum bits_status_reg {
+        WEL_POS = 1, 
+        WIP_POS = 0
+    };
+
+};
\ No newline at end of file
diff --git a/src/tests/drivers/QuadSpi-Flash/test-Qflash.cpp b/src/tests/drivers/QuadSpi-Flash/test-Qflash.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..eab9af8248eabfa8194ab91d4409877e3e353625
--- /dev/null
+++ b/src/tests/drivers/QuadSpi-Flash/test-Qflash.cpp
@@ -0,0 +1,33 @@
+// qspi-flash driver TEST, aggiunto l' eseguibile in cmakelist
+// dipendenze: aggiunto qspi-flash.cpp in cmake.boardcore 
+// il test viene eseguito ma non sembra leggere l'ID
+
+#include "qspi-flash.h"
+
+qspi_flash mymemory;
+
+int main() {
+
+
+    // test readID() 
+    printf("starting!\n"); 
+
+    uint32_t ID = mymemory.readID();
+
+    printf("ID: %x\n", ID);
+
+    printf("end ID test\n");
+
+    
+    // test write enable command
+    printf("start write_enable command\n"); 
+    // TODO: COMMITTTTT E POI FARE BENE FUNZIONE INIT QUADSPI E SOPRATTUTTO CHIAMARE INIT 
+    // QUADSPI AL MOMENTO DELLA CREAZIONE DI UN' ISTASNZA DELLA CLASSE QUADSPI-FLASH NEL
+    // DENTRO IL COSTRUTTORE. MI RACCOMANDO FARE ABORT PRIMA DI FARE ALTRE OPERAZIONI. 
+    mymemory.write_enable();
+
+    printf("end write_enable command\n");     
+
+    while (true)
+        Thread::sleep(1000);
+}
\ No newline at end of file