/ args point to the first variable parameter /
va_start(args, format);
printf("SFUD ", file, line);
/ must use vprintf to print /
vsnprintf(log_buf, sizeof(log_buf), format, args);
printf("%s\n", log_buf);
va_end(args);
}
/ args point to the first variable parameter /
va_start(args, format);
printf("[SFUD]");
/ must use vprintf to print /
vsnprintf(log_buf, sizeof(log_buf), format, args);
printf("%s\n", log_buf);
va_end(args);
}
/**
This function can send or send then receive QSPI data.
/
sfud_err qspi_send_then_recv(const sfud_spi spi,const void send_buf, size_t send_length, void recv_buf, size_t recv_length)
{
assert_param(send_buf);
assert_param(recv_buf);
assert_param(send_length != 0);
我是用STM32H723+GD25Q256的方式,使用OSPI的4线或者1线模式可以读取sfdp信息,但是进行读写测试不能成功,读回来的数据都是0xff。请问这里大概会是什么原因呢?下面是我的port部分代码: /*
include
include
include
include
include "main.h"
include "cmsis_os.h"
static char log_buf[256];
void sfud_log_debug(const char file, const long line, const char format, ...);
void sfud_log_info(const char format, ...); sfud_err qspi_send_then_recv(const sfud_spi spi,const void send_buf, size_t send_length, void recv_buf, size_t recv_length); extern OSPI_HandleTypeDef hospi1;
typedef struct { OSPI_HandleTypeDef spix; GPIO_TypeDef cs_gpiox; uint16_t cs_gpio_pin; } spi_user_data, *spi_user_data_t;
static void spi_lock(const sfud_spi *spi) { //__disable_irq(); }
static void spi_unlock(const sfud_spi spi) { //__enable_irq(); } void cmdhandler_default(OSPI_RegularCmdTypeDef Cmdhandler) { Cmdhandler->OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; Cmdhandler->FlashId = HAL_OSPI_FLASH_ID_1; Cmdhandler->Instruction = 0; Cmdhandler->InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; Cmdhandler->InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; Cmdhandler->InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
}
/**
SPI write data then read data / static sfud_err spi_write_read(const sfud_spi spi, const uint8_t write_buf, size_t write_size, uint8_t read_buf, size_t read_size) { sfud_err result = SFUD_SUCCESS;
spi_user_data_t spi_dev = (spi_user_data_t) spi->user_data;
if (write_size) { SFUD_ASSERT(write_buf); } if (read_size) { SFUD_ASSERT(read_buf); }
/ reset cs pin / if (spi_dev->cs_gpiox != NULL) HAL_GPIO_WritePin(spi_dev->cs_gpiox, spi_dev->cs_gpio_pin, GPIO_PIN_RESET);
if (write_size && read_size) { / read data / qspi_send_then_recv(spi,write_buf, write_size, read_buf, read_size); } else if (write_size) { / send data / qspi_send_then_recv(spi,write_buf, write_size, NULL, NULL); }
/ set cs pin / if (spi_dev->cs_gpiox != NULL) HAL_GPIO_WritePin(spi_dev->cs_gpiox, spi_dev->cs_gpio_pin, GPIO_PIN_SET);
return result; }
ifdef SFUD_USING_QSPI
/**
read flash data by QSPI / static sfud_err qspi_read(const struct __sfud_spi spi, uint32_t addr, sfud_qspi_read_cmd_format qspi_read_cmd_format, uint8_t read_buf, size_t read_size) {
sfud_err result = SFUD_SUCCESS; OSPI_RegularCmdTypeDef Cmdhandler; spi_user_data hqspi; //QSPI_CommandTypeDef Cmdhandler; //extern QSPI_HandleTypeDef hqspi; hqspi = (spi_user_data )spi->user_data;
cmdhandler_default(&Cmdhandler);
/ set cmd struct / Cmdhandler.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; Cmdhandler.FlashId = HAL_OSPI_FLASH_ID_1; Cmdhandler.Instruction = qspi_read_cmd_format->instruction;
if(qspi_read_cmd_format->instruction_lines == 0) { Cmdhandler.InstructionMode = HAL_OSPI_INSTRUCTION_NONE; }else if(qspi_read_cmd_format->instruction_lines == 1) { Cmdhandler.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; }else if(qspi_read_cmd_format->instruction_lines == 2) { Cmdhandler.InstructionMode = HAL_OSPI_INSTRUCTION_2_LINES; }else if(qspi_read_cmd_format->instruction_lines == 4) { Cmdhandler.InstructionMode = HAL_OSPI_INSTRUCTION_4_LINES; }
Cmdhandler.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; Cmdhandler.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
Cmdhandler.Address = addr; Cmdhandler.AddressSize = HAL_OSPI_ADDRESS_24_BITS; Cmdhandler.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; if(qspi_read_cmd_format->address_lines == 0) { Cmdhandler.AddressMode = HAL_OSPI_ADDRESS_NONE; }else if(qspi_read_cmd_format->address_lines == 1) { Cmdhandler.AddressMode = HAL_OSPI_ADDRESS_1_LINE; }else if(qspi_read_cmd_format->address_lines == 2) { Cmdhandler.AddressMode = HAL_OSPI_ADDRESS_2_LINES; }else if(qspi_read_cmd_format->address_lines == 4) { Cmdhandler.AddressMode = HAL_OSPI_ADDRESS_4_LINES; }
Cmdhandler.AlternateBytes = 0; Cmdhandler.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; Cmdhandler.AlternateBytesSize = 0; Cmdhandler.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE;
Cmdhandler.DummyCycles = qspi_read_cmd_format->dummy_cycles;
Cmdhandler.NbData = read_size; Cmdhandler.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; if(qspi_read_cmd_format->data_lines == 0) { Cmdhandler.DataMode = HAL_OSPI_DATA_NONE; }else if(qspi_read_cmd_format->data_lines == 1) { Cmdhandler.DataMode = HAL_OSPI_DATA_1_LINE; }else if(qspi_read_cmd_format->data_lines == 2) { Cmdhandler.DataMode = HAL_OSPI_DATA_2_LINES; }else if(qspi_read_cmd_format->data_lines == 4) { Cmdhandler.DataMode = HAL_OSPI_DATA_4_LINES; }
Cmdhandler.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; Cmdhandler.DQSMode = HAL_OSPI_DQS_DISABLE;
HAL_OSPI_Command(hqspi->spix, &Cmdhandler, 5000);
if (HAL_OSPI_Receive(hqspi->spix, read_buf, 5000) != HAL_OK) { sfud_log_info("qspi recv data failed(%d)!", hqspi->spix->ErrorCode); hqspi->spix->State = HAL_OSPI_STATE_READY; result = SFUD_ERR_READ; }
return result; }
endif / SFUD_USING_QSPI /
/ about 100 microsecond delay / static void retry_delay_100us(void) { uint32_t delay = 2400; while (delay--); }
static spi_user_data spi1 = { .spix = &hospi1, .cs_gpiox = NULL, .cs_gpio_pin = NULL }; sfud_err sfud_spi_port_init(sfud_flash *flash) { sfud_err result = SFUD_SUCCESS;
}
/**
@param ... args / void sfud_log_debug(const char file, const long line, const char *format, ...) { va_list args;
/ args point to the first variable parameter / va_start(args, format); printf("SFUD ", file, line); / must use vprintf to print / vsnprintf(log_buf, sizeof(log_buf), format, args); printf("%s\n", log_buf); va_end(args); }
/**
@param ... args / void sfud_log_info(const char format, ...) { va_list args;
/ args point to the first variable parameter / va_start(args, format); printf("[SFUD]"); / must use vprintf to print / vsnprintf(log_buf, sizeof(log_buf), format, args); printf("%s\n", log_buf); va_end(args); } /**
This function can send or send then receive QSPI data. / sfud_err qspi_send_then_recv(const sfud_spi spi,const void send_buf, size_t send_length, void recv_buf, size_t recv_length) { assert_param(send_buf); assert_param(recv_buf); assert_param(send_length != 0);
OSPI_RegularCmdTypeDef Cmdhandler; spi_user_data hqspi; hqspi = (spi_user_data )spi->user_data;
unsigned char ptr = (unsigned char )send_buf; size_t count = 0; sfud_err result = SFUD_SUCCESS;
cmdhandler_default(&Cmdhandler);
/ get instruction / Cmdhandler.Instruction = ptr[0]; Cmdhandler.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; count++;
/ get address / if (send_length > 1) { if (send_length >= 4) { / address size is 3 Byte / Cmdhandler.Address = (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]); Cmdhandler.AddressSize = HAL_OSPI_ADDRESS_24_BITS; count += 3; } else { return SFUD_ERR_READ; } Cmdhandler.AddressMode = HAL_OSPI_ADDRESS_1_LINE; } else { / no address stage / Cmdhandler.Address = 0 ; Cmdhandler.AddressMode = HAL_OSPI_ADDRESS_NONE; Cmdhandler.AddressSize = 0; }
Cmdhandler.AlternateBytes = 0; Cmdhandler.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; Cmdhandler.AlternateBytesSize = 0;
Cmdhandler.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
if (send_buf && recv_buf) { / recv data / / set dummy cycles / if (count != send_length) { Cmdhandler.DummyCycles = (send_length - count) * 8; } else { Cmdhandler.DummyCycles = 0; }
} else { / send data / / set dummy cycles / Cmdhandler.DummyCycles = 0;
} }