2020-08-17 05:09 AM
Hello!
I can read any registers, but can't proramm it. This is my first attempt to work whith this flash in this KIT. Initialization - HAL, STMCube IDE.
Code in main function after Initialization (initialization - auto generate in IDE):
QSPI_Write_en_Command(ONE_LINE_MODE);
QSPI_Init_Command(ONE_LINE_MODE);
QSPI_Read_Register(FLAG_STATUS_REGISTER,qspi2rd,1,ONE_LINE_MODE);
QSPI_Read_Register(READ_STATUS,qspi2rd+1,1,ONE_LINE_MODE);
QSPI_Read_Volatile_Reg(qspi2rd+2, ONE_LINE_MODE);
where:
void QSPI_Write_en_Command(uint32_t Mode){
uint32_t InstructionMode;
if ((Mode==ONE_LINE_MODE)||(Mode==EXTENDED_MODE)){
InstructionMode=QSPI_INSTRUCTION_1_LINE;
}
else if (Mode==QUAD_MODE){
InstructionMode=QSPI_INSTRUCTION_4_LINES;
}
else{
InstructionMode=QSPI_INSTRUCTION_2_LINES;
}
QSPI_Command.Instruction=WRITE_ENABLE;
QSPI_Command.AddressSize=0x0;
QSPI_Command.AlternateBytesSize=0x0;
QSPI_Command.DummyCycles=0x0;
QSPI_Command.InstructionMode=InstructionMode;
QSPI_Command.AddressMode=QSPI_ADDRESS_NONE;
QSPI_Command.AlternateByteMode=QSPI_ALTERNATE_BYTES_NONE;
QSPI_Command.DataMode=QSPI_DATA_NONE;
QSPI_Command.NbData=0x0;
QSPI_Command.DdrMode=QSPI_DDR_MODE_DISABLE;
QSPI_Command.DdrHoldHalfCycle=QSPI_DDR_HHC_ANALOG_DELAY;
QSPI_Command.SIOOMode=QSPI_SIOO_INST_EVERY_CMD;
HAL_QSPI_Command(&hqspi,&QSPI_Command,2);
}
oid QSPI_Init_Command(uint32_t Mode){
static uint8_t volatile_conf_reg=0x1B;
static uint8_t enhanced_volatile_conf_reg=0xEF;
uint32_t InstructionMode;
uint32_t DataMode;
if (Mode==ONE_LINE_MODE){
InstructionMode=QSPI_INSTRUCTION_1_LINE;
DataMode=QSPI_DATA_1_LINE;
}
else if (Mode==QUAD_MODE){
InstructionMode=QSPI_INSTRUCTION_4_LINES;
DataMode=QSPI_DATA_4_LINES;
}
else if (Mode==DUAL_MODE){
InstructionMode=QSPI_INSTRUCTION_2_LINES;
DataMode=QSPI_DATA_2_LINES;
}
else{
InstructionMode=QSPI_INSTRUCTION_1_LINE;
DataMode=QSPI_DATA_4_LINES;
}
QSPI_Command.Instruction=VOLATILE_REG_COM;
QSPI_Command.AddressSize=0x0;
QSPI_Command.AlternateBytesSize=0x0;
QSPI_Command.DummyCycles=0x1;
QSPI_Command.InstructionMode=InstructionMode;
QSPI_Command.AddressMode=QSPI_ADDRESS_NONE;
QSPI_Command.AlternateByteMode=QSPI_ALTERNATE_BYTES_NONE;
QSPI_Command.DataMode=DataMode;
QSPI_Command.NbData=0x1;
QSPI_Command.DdrMode=QSPI_DDR_MODE_DISABLE;
QSPI_Command.DdrHoldHalfCycle=QSPI_DDR_HHC_ANALOG_DELAY;
QSPI_Command.SIOOMode=QSPI_SIOO_INST_EVERY_CMD;
HAL_QSPI_Command(&hqspi,&QSPI_Command,2);
HAL_QSPI_Transmit(&hqspi,&volatile_conf_reg,2);
QSPI_Command.Instruction=ENHANCED_VOLATILE_COM;
HAL_QSPI_Command(&hqspi,&QSPI_Command,2);
HAL_QSPI_Transmit(&hqspi,&enhanced_volatile_conf_reg,2);
}
void QSPI_Read_Register(uint32_t command, uint8_t *data, uint32_t length, uint32_t Mode){
uint32_t InstructionMode;
uint32_t DataMode;
if (Mode==ONE_LINE_MODE){
InstructionMode=QSPI_INSTRUCTION_1_LINE;
DataMode=QSPI_DATA_1_LINE;
}
else if (Mode==QUAD_MODE){
InstructionMode=QSPI_INSTRUCTION_4_LINES;
DataMode=QSPI_DATA_4_LINES;
}
else if (Mode==DUAL_MODE){
InstructionMode=QSPI_INSTRUCTION_2_LINES;
DataMode=QSPI_DATA_2_LINES;
}
else{
}
QSPI_Command.Instruction=command;
QSPI_Command.Address = 0;
QSPI_Command.AddressSize=QSPI_ADDRESS_24_BITS;
QSPI_Command.AlternateBytesSize=0x0;
QSPI_Command.DummyCycles=0x0;
QSPI_Command.InstructionMode=InstructionMode;
QSPI_Command.AddressMode=QSPI_ADDRESS_NONE;
QSPI_Command.AlternateByteMode=QSPI_ALTERNATE_BYTES_NONE;
QSPI_Command.DataMode=DataMode;
QSPI_Command.NbData=length;
QSPI_Command.DdrMode=QSPI_DDR_MODE_DISABLE;
QSPI_Command.DdrHoldHalfCycle=QSPI_DDR_HHC_ANALOG_DELAY;
QSPI_Command.SIOOMode=QSPI_SIOO_INST_EVERY_CMD;
HAL_QSPI_Command(&hqspi,&QSPI_Command,10);
HAL_QSPI_Receive(&hqspi,data,10);
}
void QSPI_Read_Volatile_Reg(uint8_t *data, uint32_t Mode){
uint32_t InstructionMode;
uint32_t DataMode;
if (Mode==ONE_LINE_MODE){
InstructionMode=QSPI_INSTRUCTION_1_LINE;
DataMode=QSPI_DATA_1_LINE;
}
else if (Mode==QUAD_MODE){
InstructionMode=QSPI_INSTRUCTION_4_LINES;
DataMode=QSPI_DATA_4_LINES;
}
else{
InstructionMode=QSPI_INSTRUCTION_2_LINES;
DataMode=QSPI_DATA_2_LINES;
}
QSPI_Command.Instruction=READ_VOL_REG;
QSPI_Command.Address = 0;
QSPI_Command.AddressSize=QSPI_ADDRESS_24_BITS;
QSPI_Command.AlternateBytesSize=0x0;
QSPI_Command.DummyCycles=0x0;
QSPI_Command.InstructionMode=InstructionMode;
QSPI_Command.AddressMode=QSPI_ADDRESS_NONE;
QSPI_Command.AlternateByteMode=QSPI_ALTERNATE_BYTES_NONE;
QSPI_Command.DataMode=DataMode;
QSPI_Command.NbData=1;
QSPI_Command.DdrMode=QSPI_DDR_MODE_DISABLE;
QSPI_Command.DdrHoldHalfCycle=QSPI_DDR_HHC_ANALOG_DELAY;
QSPI_Command.SIOOMode=QSPI_SIOO_INST_EVERY_CMD;
HAL_QSPI_Command(&hqspi,&QSPI_Command,2);
HAL_QSPI_Receive(&hqspi,data,2);
QSPI_Command.Instruction=READ_ENH_VOL_REG;
HAL_QSPI_Command(&hqspi,&QSPI_Command,2);
HAL_QSPI_Receive(&hqspi,data+1,2);
}
Defines in quadspi.h
#define NONVOLATILE_REG_COM 0xB1
#define VOLATILE_REG_COM 0x81
#define ENHANCED_VOLATILE_COM 0x61
#define WRITE_ENABLE 0x06
#define WRITE_DISABLE 0x04
#define BULK_ERASE 0xC7
#define PAGE_PROGRAMM 0x02
#define FAST_QUAD_PROGRAM 0x32
#define FAST_READ 0x0B
#define EXT_QUAD_INPUT_FAST_PROGRAM 0x38
#define QUAD_IO_MODE 0x35
#define RESET_MEMORY 0x99
#define RESET_ENABLE 0x66
#define READ_NONVOLATILE_REG 0xB5
#define READ_STATUS 0x05
#define QUAD_IOFAST_READ 0xEB
#define READ 0x03
#define READ_VOL_REG 0x85
#define READ_ENH_VOL_REG 0x65
#define READ_DEVICE_ID 0x9F
#define EARSE_NONVOLATILE_LOCK_BITS 0xE4
#define GLOBAL_FREEZE_BIT 0xA7
#define READ_VOLATILE_LOCK_BITS 0xE8
#define READ_NONVOLATILE_LOCK_BITS 0xE2
#define WRITE_GLOBAL_FREEZE_BIT 0xA6
#define FLAG_STATUS_REGISTER 0x70
#define RELEASE_FROM_DEEP_POWERDOWN 0xAB
#define MT_FLASH_SIZE 0x8000000
#define EXTENDED_MODE 0x3
#define QUAD_MODE 0x2
#define DUAL_MODE 0x1
#define ONE_LINE_MODE 0x0
There are no any warnings, or errors during compilation.
Then i sent data (qspi2rd[]) to USB. Result: flag status regiter = 0x80 (ready, no errors), status register = 0x02 (Write enable latch set). But in Volatile configuration register and Enhanced Volatile Configuration Register 0xFB and 0xFF respectively. Oscillogram accordingly Micron Serial NOR Flash Memory datasheet. Where my mistake? Mey be i must sent any other command? Nonvolatile Configuration Register = 0xFFFF (default state).
2020-08-17 09:03 AM
>>There are no any warnings, or errors during compilation.
Really just means the compiler didn't find any syntax errors, not that the code is free from logic or algorithm errors.
Would probably start with the BSP example code, rather than the auto-gen stuff.
The QSPI parts are double banked on the H747I-DISCO as I recall. If configured properly alternate bytes go to each device.
2020-08-20 11:44 PM
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "dac.h"
#include "dma.h"
#include "quadspi.h"
#include "tim.h"
#include "usart.h"
#include "usb_device.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "mt25tl01g.h"
#include "usb_cdc_user_init.h"
#include "stm32h747i_discovery_qspi.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#ifndef BSP_QSPI
#define BSP_QSPI
#endif
#define Destination_Address 0x30020000
#define HSEM_ID_0 (0U) /* HW semaphore 0*/
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
static void my_SRAM_init(void);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
//uint32_t dann_adc1[10];
uint32_t dan_adc3;
uint8_t counter_dann_adc=0, dann_adc_flag=0,flag=0;
uint32_t *dann_adc1 = (uint32_t *)Destination_Address;
BSP_QSPI_Init_t QSPI_Init;
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
int32_t timeout;
uint32_t stateDAC=0;
uint8_t qspi2wr[4] = {0x55,0xFF,0x55,0xFF};
uint8_t qspi2rd[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t device_ID[20];
uint8_t strEr[]="Error";
uint8_t flash_err_flag=0x0;
QSPI_Init.DualFlashMode = MT25TL01G_DUALFLASH_DISABLE;
QSPI_Init.InterfaceMode = MT25TL01G_SPI_MODE;
QSPI_Init.TransferRate = MT25TL01G_STR_TRANSFER;
// uint32_t nonreg = 0x00;
/* USER CODE END 1 */
/* USER CODE BEGIN Boot_Mode_Sequence_0 */
/* USER CODE END Boot_Mode_Sequence_0 */
/* USER CODE BEGIN Boot_Mode_Sequence_1 */
/* Wait until CPU2 boots and enters in stop mode or timeout*/
timeout = 0xFFFF;
while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) != RESET) && (timeout-- > 0));
if ( timeout < 0 )
{
Error_Handler();
}
/* USER CODE END Boot_Mode_Sequence_1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
*dann_adc1=0;
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN Boot_Mode_Sequence_2 */
/* When system initialization is finished, Cortex-M7 will release Cortex-M4 by means of
HSEM notification */
/*HW semaphore Clock enable*/
__HAL_RCC_HSEM_CLK_ENABLE();
/*Take HSEM */
HAL_HSEM_FastTake(HSEM_ID_0);
/*Release HSEM in order to notify the CPU2(CM4)*/
HAL_HSEM_Release(HSEM_ID_0,0);
/* wait until CPU2 wakes up from stop mode */
timeout = 0xFFFF;
while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) == RESET) && (timeout-- > 0));
if ( timeout < 0 )
{
Error_Handler();
}
/* USER CODE END Boot_Mode_Sequence_2 */
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
MX_ADC1_Init();
MX_ADC3_Init();
MX_USB_DEVICE_Init();
MX_TIM8_Init();
MX_DAC1_Init();
#ifndef BSP_QSPI
MX_QUADSPI_Init();
#else
if(BSP_QSPI_Init(0, &QSPI_Init)!=BSP_ERROR_NONE)
flash_err_flag=1;
#endif
/* USER CODE BEGIN 2 */
HAL_DAC_Start(&hdac1,DAC_CHANNEL_1);
my_SRAM_init();
DMA1_Stream0->M0AR = Destination_Address;
HAL_TIM_Base_Start_IT(&htim8);
HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_1,DAC_ALIGN_12B_R,0x960);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if (!HAL_GPIO_ReadPin(GPIOK,GPIO_PIN_3)){
HAL_Delay(10);
if (!HAL_GPIO_ReadPin(GPIOK,GPIO_PIN_3)){
HAL_Delay(100);
}
}
if (!HAL_GPIO_ReadPin(GPIOK,GPIO_PIN_5)){
HAL_Delay(10);
if (!HAL_GPIO_ReadPin(GPIOK,GPIO_PIN_5)){
HAL_ADC_Start_DMA(&hadc1,dann_adc1,4);
}
}
if (flag){
if (!flash_err_flag)
USB_Sent(&hUsbDeviceHS,qspi2rd,4);
else
USB_Sent(&hUsbDeviceHS,strEr,5);
if (BSP_QSPI_Write(0,qspi2wr,0x7000,4)!=BSP_ERROR_NONE) flash_err_flag=1;
HAL_Delay(10);
if (BSP_QSPI_Read(0,qspi2rd,0x7000,4)!=BSP_ERROR_NONE) flash_err_flag=1;
flag=0;
// USB_Sent(&hUsbDeviceHS,(uint8_t*)(dann_adc1),8);
if (stateDAC>4){
HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_1,DAC_ALIGN_12B_R,0x7D0);
stateDAC=0;
}
else{
HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_1,DAC_ALIGN_12B_R,0x7D0);
stateDAC++;
}
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
I try to use stm32h747i_discovery_qspi.c from BSP example code in my test project. But i can't programm registers or memory analogically. May be i don't take into account something? All stm32h747i_discovery_qspi functions returns BSP_ERROR_NONE. Code in lines 187-196. Flag event (line 186) happens once a second, when timer interrupt occurs. QSPI_Init declaration in line 63, QSPI_Init initialization in lines 82-84. QSPI init in line 149. When i try to use MT25TL01G_QPI_MODE flash doesn't work.