Hello,
I have been facing problems while erasing , writing and reading data from flash memory on the DA14531MOD.
The problem might be in the configurations made by me in the following fuction.
static const spi_flash_cfg_t spi_flash_cfg = { .dev_index = (uint8_t)P25Q11U_MAN_DEV_ID, .jedec_id = P25Q11U_JEDEC_ID, .chip_size = SPI_FLASH_DEV_SIZE,};
by running the example code i could identify the flash chip to be P25Q11U.
The dev_indix for P25Q11U couldn't be found in spi_flash.h.
what can be the better way of configuring the spi flash?
Thank you.
Hi Sumo,Thank you for the reply.Yes, the address 0xBD90 was a typo from my side.Please find attached a demo I created to see read/write/erase the P25Q11U.I used SDK v6.0.18, Dev Kit Pro and DA14531MOD…
Hi Sumo,Thank you for posting your question online.I understand your issue and I was able to replicate it.I worked on the empty_peripheral_template example and I followed the DA14531 SDK6 Peripheral Drivers Tutorial:5. DA14531 SPI Flash — DA145XX Tutorial SDK peripherals (renesas.com)On the user_periph_setup.h file I set the SPI pins as shown below:
/****************************************************************************************/ /* SPI configuration */ /****************************************************************************************/ // Define SPI Pads #if defined (__DA14531__) #define SPI_EN_PORT GPIO_PORT_0 #define SPI_EN_PIN GPIO_PIN_1 #define SPI_CLK_PORT GPIO_PORT_0 #define SPI_CLK_PIN GPIO_PIN_4 #define SPI_DO_PORT GPIO_PORT_0 #define SPI_DO_PIN GPIO_PIN_0 #define SPI_DI_PORT GPIO_PORT_0 #define SPI_DI_PIN GPIO_PIN_3 #elif !defined (__DA14586__) #define SPI_EN_PORT GPIO_PORT_0 #define SPI_EN_PIN GPIO_PIN_3 #define SPI_CLK_PORT GPIO_PORT_0 #define SPI_CLK_PIN GPIO_PIN_0 #define SPI_DO_PORT GPIO_PORT_0 #define SPI_DO_PIN GPIO_PIN_6 #define SPI_DI_PORT GPIO_PORT_0 #define SPI_DI_PIN GPIO_PIN_5 #endif
void GPIO_reservations(void) { /* i.e. to reserve P0_1 as Generic Purpose I/O: RESERVE_GPIO(DESCRIPTIVE_NAME, GPIO_PORT_0, GPIO_PIN_1, PID_GPIO); */ #if defined (CFG_PRINTF_UART2) RESERVE_GPIO(UART2_TX, UART2_TX_PORT, UART2_TX_PIN, PID_UART2_TX); #endif #if !defined (__DA14586__) // RESERVE_GPIO(SPI_EN, SPI_EN_PORT, SPI_EN_PIN, PID_SPI_EN); #endif RESERVE_GPIO(SPI_FLASH_CS, SPI_EN_PORT, SPI_EN_PIN, PID_SPI_EN); RESERVE_GPIO(SPI_FLASH_CLK, SPI_CLK_PORT, SPI_CLK_PIN, PID_SPI_CLK); RESERVE_GPIO(SPI_FLASH_DO, SPI_DO_PORT, SPI_DO_PIN, PID_SPI_DO); RESERVE_GPIO(SPI_FLASH_DI, SPI_DI_PORT, SPI_DI_PIN, PID_SPI_DI); }
void set_pad_functions(void) { /* i.e. to set P0_1 as Generic purpose Output: GPIO_ConfigurePin(GPIO_PORT_0, GPIO_PIN_1, OUTPUT, PID_GPIO, false); */ #if defined (__DA14586__) // Disallow spontaneous DA14586 SPI Flash wake-up GPIO_ConfigurePin(GPIO_PORT_2, GPIO_PIN_3, OUTPUT, PID_GPIO, true); #else // Disallow spontaneous SPI Flash wake-up GPIO_ConfigurePin(SPI_EN_PORT, SPI_EN_PIN, OUTPUT, PID_SPI_EN, true); #endif #if defined (CFG_PRINTF_UART2) // Configure UART2 TX Pad GPIO_ConfigurePin(UART2_TX_PORT, UART2_TX_PIN, OUTPUT, PID_UART2_TX, false); #endif GPIO_ConfigurePin(SPI_EN_PORT, SPI_EN_PIN, OUTPUT, PID_SPI_EN, true); GPIO_ConfigurePin(SPI_CLK_PORT, SPI_CLK_PIN, OUTPUT, PID_SPI_CLK, false); GPIO_ConfigurePin(SPI_DO_PORT, SPI_DO_PIN, OUTPUT, PID_SPI_DO, false); GPIO_ConfigurePin(SPI_DI_PORT, SPI_DI_PIN, INPUT, PID_SPI_DI, false); }
void periph_init(void) { #if defined (__DA14531__) // In Boost mode enable the DCDC converter to supply VBAT_HIGH for the used GPIOs syscntl_dcdc_turn_on_in_boost(SYSCNTL_DCDC_LEVEL_3V0); #else // Power up peripherals' power domain SetBits16(PMU_CTRL_REG, PERIPH_SLEEP, 0); while (!(GetWord16(SYS_STAT_REG) & PER_IS_UP)); SetBits16(CLK_16M_REG, XTAL16_BIAS_SH_ENABLE, 1); #endif // ROM patch patch_func(); // Initialize peripherals #if defined (CFG_PRINTF_UART2) // Initialize UART2 uart_initialize(UART2, &uart_cfg); #endif spi_cfg_t spi_flash_cfg = { .spi_ms = SPI_MS_MODE_MASTER, .spi_cp = SPI_CP_MODE_0, .spi_speed = SPI_SPEED_MODE_4MHz, .spi_wsz = SPI_MODE_8BIT, .spi_cs = SPI_CS_0, .cs_pad.port = SPI_EN_PORT, .cs_pad.pin = SPI_EN_PIN, #if defined (__DA14531__) .spi_capture = SPI_MASTER_EDGE_CAPTURE #endif }; spi_initialize(&spi_flash_cfg); // Set pad functionality set_pad_functions(); // Enable the pads GPIO_set_pad_latch_en(true); }
void user_on_init(void) { arch_printf("\n\r%s", __FUNCTION__); default_app_on_init(); // Disable HW RST on P0_0 so it can be used as SPI MOSI. GPIO_Disable_HW_Reset(); int8_t ret; ret = spi_flash_block_erase(0x20000, SPI_FLASH_OP_SE); arch_printf("\n\rErase Status: %d", ret); uint16_t bytes_written; uint8_t data[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5 }; ret = spi_flash_write_data(&data[0], 0x20000, sizeof(data), &bytes_written); arch_printf("\n\rWrite Status: %d", ret); arch_printf("\n\rBytes Written: %d", bytes_written); uint16_t bytes_read; uint8_t data_read[16] = { 0 }; ret = spi_flash_read_data(&data_read[0], 0x20000, sizeof(data_read), &bytes_read); arch_printf("\n\rRead Status: %d", ret); arch_printf("\n\rBytes Read:"); while (bytes_read) { arch_printf(" %d", data_read[sizeof(data_read) - bytes_read]); bytes_read--; } // Reduce power consumption by putting flash into sleep mode */ spi_flash_power_down(); // Re-enable HW reset input (must be disabled if/when further operation on // external flash are performed) - must set as input first! GPIO_ConfigurePin(SPI_DO_PORT, SPI_DO_PIN, INPUT_PULLDOWN, PID_GPIO, false); GPIO_Enable_HW_Reset(); }
I could successfully write in the flash memory, at memory location 0x2A000.
I am getting an error while reading the memory location.
where can I get list of readable and writable flash memory locations?
Hi Sumo,Thank you for the reply.Are you working with one of your Development Kits? If yes, which one?If you are working with our Development Kit Pro your board configuration should look like this:With this configuration you should be able to Write/Read on the SPI Flash of the DA14531MOD (P25Q11U).If your configuration looks like this: With this configuration you are should be able to Write/Read on the SPI Flash integrated on the Development Kit Pro (MX25R2035).You stated you successfully wrote in the flash memory, at memory location 0x2A000.The memory location 0x2A000 exceeds the size of the SPI Flash on DA14531MOD. The maximum value for the SPI Flash on the DA14531MOD is 0x1F000As you can see on the SDK6 Peripheral Drivers Tutorial:5. DA14531 SPI Flash — DA145XX Tutorial SDK peripherals (renesas.com)On 5.1 you can find the SPI Flash Memory Layout for the Development Kit:Exactly the same SPI Flash Memory Layout applies for the SPI Flash of the DA14531MOD but you do not have the last 128kB available for user data storage.If you want to implement SUOTA on your project, you should refer on the SUOTA tutorial here:22. SUOTA Overview — DA145XX Tutorial SDK Getting started (renesas.com)For DA14531MOD SPI Flash you should check chapter 27. If you have any further questions, feel free to ask.Kind Regards,OV_Renesas
Thank you!
So while using the DA14531MOD,
If I want to store about 30-40 bytes of data in the flash, I will not be able to do that. as the 128kB is not available for user data storage.
I will have to have an external flash for storing the user application data.
I misread 1Mb as 1MB, and hence was confused for long period of time.
Hi Sumo,Thank you for the reply. No, you will not have to use an external flash to store your user application data.As you can see on the screenshot I shared on my previous answer, with DA14531MOD SPI Flash you can use:You can have up to 74kB for User data storage. The DA14531MOD SPI Flash does not have the last 128kB available.Kind Regards,OV_Renesas
hello,
I have written successfully @ memory location 0xBD80 and further, but the i am unable to read the same.
The application stops execution whenever I include spi_flash read command.
Hi Sumo,Thank you for the reply.Could you please call the following function before trying to read the contents of the Flash: spi_flash_release_from_power_down();If this does not work, could you please share all your code Snippet so I can try to reproduce this?Kind Regards,OV_Renesas
I added the release from power down function, but i could not read data from flash.
Is there any other way to read data from flash memory?
now since I know the flash location, i.e. 0x0000BD80 , can I use memcpy(); ?
If possible what is the address that can be used?
Hi Sumo,Thank you for the reply.Could you kindly share your code snippet for handling the SPI Flash?Could you also clarify if you are trying to read/write/erase the P25Q11U SPI Flash which is integrated on the DA14531MOD or if you are working with the SPI Flash on the Development Kits?After you have read the values from the SPi Flash, you can use memcpy to copy the values to a different variable.Kind Regards,OV_Renesas
I am using P25Q11U which is integrated on the DA14531MOD.
I am attaching the snip of the code,
I have accepted 2 bytes from one of the services. I wanted to save these 2 bytes. and read them upon power on every time.
Hi There,Thank you for the reply.From the code snippet you have shared you are not writing on the 0xBD80 address of the SPI Flash but on the address: 0x2BD80. As mentioned before the P25Q11U SPI Flash size is: 0x20000, so the address 0x2BD80 exceeds the size of the Flash.However, I am confused on why you are able to see the values being written (via SmartSnippets Toolbox) on the address: 0xBD80.Could you please run the spi_flash example and see what the JEDEC ID of your SPI Flash is?You can find the spi_flash example on the following path:DA14531\6.0.18.1182.1\projects\target_apps\peripheral_examples\spi\spi_flashIf you are working with P25Q11U you should see:Kind Regards,OV_Renesas
I have already done that, it matched the JEDEC ID of P25Q11U.
I will try and enter 0xBD80 and let you what happens.
Thank you very much for helping me this far.
I tried entering 0xBD80 as address in the function. It did not work.
another doubt that i had was, whenever I call the read function it doesn't return any error code, the application just stops responding? if the address was wrong , It should have return an error code, right?
Hi Sumo,Thank you for the reply.I am able to write and read data on the P25Q11U SPI Flash on the address: 0xBD80.In order to write:
spi_flash_release_from_power_down(); /* Write data on address 0xBD80 */ uint8_t sizes = sizeof(data); arch_printf("\n\r Size of data is: %d", sizes); ret = spi_flash_write_data(&data[0], 0xBD90, sizeof(data), &pc_bytes_written);
ret = spi_flash_read_data(&data_read[0],0xBD90 , sizeof(data_read), &bytes_read); arch_printf("\n\rRead Status for 0xBD90: %d \n\r", ret); arch_printf("Bytes read:"); for(int i=0;i<7;i++) { arch_printf(" %d", data_read[i]); }
/* * SPI Flash Read functions **************************************************************************************** */ int8_t spi_flash_read_data(uint8_t *rd_data_ptr, uint32_t address, uint32_t size, uint32_t *actual_size) { SPI_FLASH_ENABLE_POWER_PIN(); // Check if SPI Flash is ready int8_t status = spi_flash_is_busy(); if (status != SPI_FLASH_ERR_OK) { return status; } // Check that all bytes to be read are located in a valid Flash memory address space if (size + address > spi_flash_cfg_env.chip_size) { *actual_size = spi_flash_cfg_env.chip_size - address; /*Add this line */ return SPI_FLASH_ERR_READ_ERROR; } else { *actual_size = size; } // Send Command spi_set_bitmode(SPI_MODE_32BIT); spi_cs_low(); // Send sequencial read from memory Command spi_access((SPI_FLASH_OP_READ << 24) | address); spi_set_bitmode(SPI_MODE_8BIT); // Read data for (uint32_t i = 0; i < *actual_size; i++) { *rd_data_ptr++ = (uint8_t) spi_access(0x0000); } spi_cs_high(); return SPI_FLASH_ERR_OK; }