 Hello and welcome to the STM32L4 MOOC online training. My name is André Barata and this is the dedicated session for the Quad SPI peripheral. In order to manage a wide range of multimedia, rich graphics and other data intensive content, embedded applications evolve to offer more sophisticated features. These sophisticated features require extra demands on the often limited MCU on chip memory. Several parallel memories are used to extend the MCU on chip memory and solve the memory size limitation. The Quad SPI is a specialized communication interface targeting single, dual or Quad SPI flash memories. It means that the Quad SPI is a serial interface allowing communication on four lines between a host, in this case the STM32 MCU and an external Quad SPI memory. The Quad SPI supports the traditional SPI serial peripheral interface as well as the dual SPI mode, which allows to communicate on two lines. Quad SPI uses up to six lines in Quad mode, one line for chip select, one line for clock and four lines for data in and data out. In our case we will communicate with the onboard Quad SPI Nord flash memory N25K 128A via Quad SPI interface in single SPI mode for a simple city of this example. So we will use one data line in each direction, however all mandatory steps will be demonstrated. The main goal of this hands-on is to read the manufacturer ID and device ID from the external flash memory. You can find documents, presentation and slides on how to communicate in genuine Quad SPI protocol in the hands-on description down below. Let's start by explaining the physical connection of the external flash on our L4 Discovery board. It is connected by six wires, Quad SPI chip select and Quad SPI clock. Those are respectively P11 and P10 pins. The rest four pins are dedicated for that signal. These are mapped on P12 to P15. Let's briefly describe how the frame of Quad SPI looks like. It can be divided into command phase and data phase. In command phase, the Ios are set as output. This phase initializes all parameters which are required for successfully reading or programming data. All parameters are managed by the following command. Introduction which specifies the type of operation to be preformed. This phase specifies the address of the data to be read or written. Alternate byte. This is an extra phase offering more flexibility. It is generally used for controlling the mode of operation. For instance, one byte can be sent constantly to keep the Quad SPI device in operating mode. Dummy cycles. The dummy cycle phase is needed in some cases when operating at high clock frequencies. This phase allows to ensure enough turnaround time for changing the data signal from output mode to input mode. The phase which handles content of memory is called data phase. In this phase, the data is sent or received from or to the Quad SPI memory. The data phase is fully configurable allowing to send, receive, or both, any number of bytes to or for the Quad SPI memory device. As it can be seen, transferring one byte is preformed within two clock cycles. One byte is preformed among four data lines. The first four bits are transmitted in the first clock cycle and the last four bits are transmitted in the second clock cycle. As described on previous slides, we need to configure the command parameters. In our case, it is the command 9E in hexadecimal, which preforms the request of the memory ID information. Then the command will be transmitted and we expect to receive the manufacturer and device ID. As a first step, we will click on new project. On the new open window, we will type our part number, stm32l476vg, and we will double click on the desired part. So by going to the prefere 3, we go to Quad SPI and we will select Quad SPI line mode. As we can see, all six required signals are assigned to pins. signals dedicated to clock and chip select are mapped on P10 and P11 respectively. This configuration is correct. However, as you remember, data lines are connected to pins P12 to P15 on L4 discovery board. So all four data lines must be remapped to P12, P13, P13 and P15, one by one pressing control plus the pin that you wish to remap. So all the four data lines that needs reassignment, we will drag and drop them to the right location. On the clock configuration tab, by default we have 4 MHz MSI clock selected. Let's change it to HSI 16 MHz. Let's go now to the biggest part of the configuration in the configuration tab. On the connectivity section, we are going to select the Quad SPI icon. The first parameter is the Quad SPI clock. It is calculated by dividing a HB clock by the clock prescalar plus 1. To obtain 16 MHz, the same as the core clock, we need to set clock prescalar to 0. Next, 5-fold threshold which will be set to 4. This parameter specifies when the FTF flag is set. In this case, the flag is set as soon as there are 5 or more free bytes available to be written on the FIFO. Let's keep sample shifting as default, no sample shifting. Using this feature highly depends on the PCB. It allows the data to be sampled later in order to account for the external signal delays. Flash size specifies the size of the external memory in bytes. It is calculated as 2 power of N, where N is flash size parameter plus 1. The external memory has 128 MB size. In this case, the N is equal to 24 as the flash size parameter is 23. The rest two parameters should be kept by default. One cycle for ship select, high time and low clock mode. We press OK and now we just finish the configuration of the Quad SPI peripheral for this specific application. As everything is set, we just need to save the project, choose System Workbench for STM32 as our IDE and generate our code. After the code is generated by STM32 Cubemix and our project is loaded on System Workbench for STM32, we will open our main.c file stored inside the source folder. On main.c file, you are supposed to see the initialization of all peripherals defined on STM32 Cubemix. In this specific case, we can see the system clock configuration and the Quad SPI in it, which will be in focus in this session. As a first step, we will define a command for reading the manufacturer and device ID. All commands are listed in the datasheet of the external memory. So we type define read id cmd 0x90. Then we will initialize the structure for command configuration, where we will set all parameters required for data transfer. We type it as Quad SPI cmd fs cmd. And then we define a 3 bytes buffer, id and the score reg. We expect one byte as manufacturer ID and two bytes dedicated to the device ID. To send the command configuration and receive the response we will use hl quad SPI cmd and hl quad SPI receive respectively. However, before that, we need to fill the command structure. The command configuration consists of several parameters. Let's set the most significant of them. We type s cmd. Instruction mode equal to. Quad SPI instruction one line. Instruction is transmitted via one data line. Instruction equal read id cmd. In our case, we want to receive the ID information. Address mode equal quad SPI address none, no address. Alternate byte mode equal quad SPI alternate bytes none, don't use any. Data mode quad SPI data one line. Data will be transmitted via one data line. That is cycles equals to zero according to the instruction description in memory data sheet. Address we must set it to zero according to the instruction description in memory data sheet. DDR equals to quad SPI DDR mode disable. As IOO mode equal to quad SPI as IOO instruct every command. NB data we expect three bytes according to the instruction description in memory data sheet. At this point, we will call the hl quad SPI command with the following parameters. Quad SPI handler pointer to the structure s cmd that contains the command configuration and timeout 100 milliseconds which prevents the program from an expected behavior. And then the function hl quad SPI receive with the following parameters. The same quad SPI handler pointer to the buffer id reg that stores the received manufacturer and device ID and timeout 100 milliseconds that prevents the program from an expected behavior. For debugging purpose, let's put a NOPE instruction asm NOPE. Now we will proceed to compile and start the debug session. In debug mode we will add to monitor our buffer. Click on window show view expression. In expression window add id reg to see the received data. Put a breakpoint on the line asm NOPE. Now we can press run to start the execution. Program stops on the breakpoint and we can see the response from the external memory. The expected values are id reg 0, manufacturer id 0x20 or 32 in decimal, id reg 1, memory type 0xba186 in decimal, id reg 2, memory capacity 0x20 or 24 in decimal. This will be all in this hands-on. Thank you for watching.