DA14531 - Writing & Reading Flash-Data

Hello, 

I am coding based on the ble_app_peripheral example from SDK6.0.16.1144 trying to write and read data from flash. For example I have a char with the value "00000" and would like to write into flash. I also would like to read the value of the respective ragister from flash and compare to my variable. The function I created to perform the write & read looks as follows: 

uint32_t PC_FLASH_ADR = 0x20000;
char default_passcode[] = "00000";

void check_nvs_available()
{
	// Disable HW RST on P0_0 so it can be used as SPI MOSI.
	GPIO_Disable_HW_Reset();
	
	// Read PC Flash --> IF PC Flash was not written in advance rewrite with default PC | ELSE do nothing 
	int8_t ret;
	uint32_t bytes_read;
	char buffer_pc;
	uint8_t data_read[5] = { 0 };
	ret = spi_flash_read_data(&data_read[0],PC_FLASH_ADR , sizeof(data_read), &bytes_read);
	while (bytes_read) {
		buffer_pc = (buffer_pc + bytes_read);
		bytes_read--;
	}
	if (buffer_pc == 0){
		uint32_t pc_bytes_written;
		uint8_t data[5] = { default_passcode[0], default_passcode[1], default_passcode[2], default_passcode[3], default_passcode[4]};
		ret = spi_flash_write_data(&data[0], PC_FLASH_ADR, sizeof(data), &pc_bytes_written);
	}
	
	// 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();
    
}

The functions should check the Flash if data was already written to PC_FLASH_ADR. IF this is the case nothting should be done. If no data was written to PC_FLASH_ADR the values of default_passcode should be written into flash starting at PC_FLASH_ADR. 
Are there any issues with my code? 

Parents
  • Hi patipat3110,

    Thank you for posting your question online.
    I can see that you have followed the SDK6 Peripheral Drivers Tutorial: 5. DA14531 SPI Flash — DA145XX Tutorial SDK peripherals (renesas.com)
    Have you tested this from your side and it is not working?
    From what you have shared, I believe the read operation has been implemented correctly. I would personally not use a while function since you already know the size of the data you have just read from the SPI Flash. You could just use a for statement and at the end compare the read data with the default_passcode you have set to see if you need to write your passcode into the SPI Flash.
    Your approach seems correct to me, but are you facing any issues?

    Kind Regards,
    OV_Renesas

  • Hi OV_Renesas, 

    Indeed I have followed the linked Tutorial. I have tested it and it does not seem to work. First of all when I add the GPIO_Disable_HW_Reset as well as the spi_flash_power_down & GPIO_ConfigurePin & GPIO_Enable_HW_Reset functions I am running into a strange phenomenon. After building and starting a debug session I need to click three times on run and get three different interruption points as shown in the screencaptures I added to this comment. When I click a fourth time on "run" the debug session runs as desired. 

    First click on "run"

    Second click on "run" 

    Third click on "run"

    This phenomenon disappears when removing the functions named above. 
    Anyway it seems that the data is not read or written correctly. I set my default_passcode to "11111" and checked that if the passcode is not corresponding to "11111" it should be written accordingly. I have added a few printf-statements so that I know if data is written. I was expecting the data to be written at the first try, because the data in the NVS was not exual to "11111", but at the second try I would not expect to again perform a write. But it seems that I read "00000" from flash even if I write "11111". Here is the code: 

    char default_passcode[] = "11111";
    void check_nvs_available()
    {
    	// Disable HW RST on P0_0 so it can be used as SPI MOSI.
    	GPIO_Disable_HW_Reset();
    	arch_printf("GPIO Disabled \n\r");
    	
    	// Read PC Flash --> IF PC Flash was not written in advance rewrite with default PC | ELSE do nothing 
    	int8_t ret;
    	uint32_t bytes_read;
    	char buffer_pc[5];
    	uint8_t data_read[5] = { 0 };
    	ret = spi_flash_read_data(&data_read[0],PC_FLASH_ADR , sizeof(data_read), &bytes_read);
    	arch_printf("Read PC from Flash! \n\r");
    	arch_printf("read Status: %d \n\r", ret);
    	arch_printf("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]);
    		buffer_pc[data_read[sizeof(data_read) - bytes_read]] = bytes_read + '0';
    		bytes_read--;
    	}
    	arch_printf(" \n\r buffer_pc = %c \n\r", buffer_pc);
    	bool data_read_empty;
    	if (strncmp(buffer_pc, default_passcode,5)){		
    		arch_printf("equal \n\r");
    	}
    	else{
    		uint32_t pc_bytes_written;
    		arch_printf("Not equal -> WRITE PC to Flash! \n\r");
    		uint8_t data[5] = { default_passcode[0], default_passcode[1], default_passcode[2], default_passcode[3], default_passcode[4]};
    		ret = spi_flash_write_data(&data[0], PC_FLASH_ADR, sizeof(data), &pc_bytes_written);
    	}
    	// 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();
    }
     

    everytime I run the code in the debug session I get the following output in TeraTerm: 

    GPIO Disabled
    
    Read PC from Flash!
    
    read Status: 0
    
    bytes read:00000
    
     buffer_pc = À
    
    equal
    
    Read UID from Flash!

    Therefore my guess is that the bytes I read are "00000" as printed and there seems to be something wrong with the write statement or the compare statement as I get always an "equal" printed independently from my "default_passcode". 

    Thanks for your support. 

  • As an addition I verified that I have some issue with the write process, as I get as writing status a "-12" as an output. Meaning that the following code snippet results in ret = -12: 

    uint32_t pc_bytes_written;
    		arch_printf("Not equal -> WRITE PC to Flash! \n\r");
    		uint8_t data[5] = { default_passcode[0], default_passcode[1], default_passcode[2], default_passcode[3], default_passcode[4]};
    		ret = spi_flash_write_data(&data[0], PC_FLASH_ADR, sizeof(data), &pc_bytes_written);
    		arch_printf("Write Status: %d\n\r", ret);
    		arch_printf("Bytes Written: %d\n\r", pc_bytes_written);

    As I have followed the setup for the SPI-Flash handling and I have no issues with the read process I think I have misunderstood the write function. 

Reply
  • As an addition I verified that I have some issue with the write process, as I get as writing status a "-12" as an output. Meaning that the following code snippet results in ret = -12: 

    uint32_t pc_bytes_written;
    		arch_printf("Not equal -> WRITE PC to Flash! \n\r");
    		uint8_t data[5] = { default_passcode[0], default_passcode[1], default_passcode[2], default_passcode[3], default_passcode[4]};
    		ret = spi_flash_write_data(&data[0], PC_FLASH_ADR, sizeof(data), &pc_bytes_written);
    		arch_printf("Write Status: %d\n\r", ret);
    		arch_printf("Bytes Written: %d\n\r", pc_bytes_written);

    As I have followed the setup for the SPI-Flash handling and I have no issues with the read process I think I have misunderstood the write function. 

Children
  • Hi patipat3110,

    Thank you for the reply.
    I worked based on your code and did some modifications.
    I believe the error you are facing is occurring from the user_periph_setup.c file.
    In the empty_peripheral_example there is a reserveration and GPIO configuration for the for SPI_EN_PIN, if you comment it out since we are reserving and configuring the GPIOs for SPI ourselves you are not going to face this error:

    On user_app_init I call your check_nvs_available function. I modified it like this:

    char default_passcode[] = "11221";
    uint8_t default_pass[] = { 1, 1, 2, 2, 1};
    int counter =0;
    void check_nvs_available()
    {
    	// Disable HW RST on P0_0 so it can be used as SPI MOSI.
    	GPIO_Disable_HW_Reset();
    	arch_printf("\n\r GPIO Disabled \n\r");
    	
    	// Read PC Flash --> IF PC Flash was not written in advance rewrite with default PC | ELSE do nothing 
    	int8_t ret;
    	uint32_t bytes_read;
    	char buffer_pc[5];
    	uint8_t buffer_spi[5];
    	uint8_t data_read[5] = { 0 };
    	ret = spi_flash_read_data(&data_read[0],0x2000 , sizeof(data_read), &bytes_read);
    	arch_printf("Read PC from Flash! \n\r");
    	arch_printf("read Status: %d \n\r", ret);
    	arch_printf("bytes read:");
    
    	for(int i=0;i<5;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	bool data_read_empty=false;
    
    	for(int j=0;j<6;j++)
    	{
    		if(data_read[j] == default_pass[j])
    		{
    			counter++;
    		}
    	}
    	if(counter ==5)
    	{
    		data_read_empty = true;
    	}
    	else
    	{
    		data_read_empty = false;
    	}
    	
    	if(!data_read_empty)
    	{
    		uint32_t pc_bytes_written;
    		arch_printf("\n\r Not equal -> WRITE PC to Flash! \n\r");
    		uint8_t data[5] = { default_pass[0], default_pass[1], default_pass[2], default_pass[3], default_pass[4]};
    		ret = spi_flash_write_data(&data[0], 0x2000, sizeof(data), &pc_bytes_written);
    		arch_printf("\n\rWrite Status: %d", ret);
    	  arch_printf("\n\rBytes Written: %d", pc_bytes_written);
    	}
    	// 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();
    }
    
    
    void user_on_init(void)
    {
      arch_printf("\n\r%s", __FUNCTION__);
    
        default_app_on_init();
    	check_nvs_available();
    
    }

    I have connected to DA14531 Dev Kit SPI Flash via SmartSnippets Toolbox and I erased the Flash.
    Then I start the empty_peripheral_example project and I get:

    Which is expected, since we read at the start the bytes at location 0x2000 (their value is 0xFF=255 since they have been erased) and after that we check that these do not match with the default_pass we had set, so we write the default_pass value into this address location (0x2000). 
    After that I connect again via SmartSnippets Toolbox and I can see the default_pass values have been written on the specific address. 
    Then I run the project again and I get:

    This time, the read function finds the values of the default_pass written on the specific location and then does not go into the write function since we do not need to overwrite them.
    If you have any further questions, feel free to ask.

    Kind Regards,
    OV_Renesas

  • Hi OV_Renesas, 


    I changed the parts you proposed. I commented the defiens in user_periph_setup.c but still face the issue that I need to press 3x on run with some stopping points and at the fourth time I press "run" the code starts to run. 

    Regarding the check_nvs_available function I changed it according to your proposal but I am still failing on writing to flash. Here is what I did: 

    1. I changed the code following your changes 
    2. I Buiild the project in µKeil5 
    3. I connected to SmartSnippets Toolbox - selected FlashCode and clicked on "Erase" --> The contents read from the flash sections are all FF 
    4. I started the debug session within µKeil5 and clicked on run. at the 4th click on run I was able to start the code. I get the following output. 

    As you can see I am still failing in the read and write, as I am not reading the FF values and I am not getting a "0" as value for "ret" but "-12". 

    You have written that you coded based on empty_peripheral_example. I am using the example project ble_app_peripheral and have added the check_nvs_available function within user_peripheral.c . Could this be the root-cause of the issue that I am not able to correctly read or write to flash? Beside from that I have followed the instructions from here (http://lpccs-docs.renesas.com/da145xx_tutorial_sdk6_peripherals/da14531_spi_flash.html=) and followed your instructions. 

    Thanks in advance. 

  • Hi again, 

    I found the root-cause for my errors. Let me describe it: 

    1. 3x breakpoints before starting to run debug session: -> The root cause was that the GPIO were not reserved and configured in user_periph_setup.c as I was using the ble_app_peripheral example and followed chapter 5 of http://lpccs-docs.renesas.com/da145xx_tutorial_sdk6_peripherals/da14531_spi_flash.html= documentation. As the reservation and configuration is done in chapter 3 I must have missed it. 

    2. not being able to read / write the correct values: -> As I was also not able to erase the flash within my code with the same "ret" value my guess was that I had an error in the initialization. I added spi_flash_release_from_power_down(); before trying to erase/read/write and everything worked perfectly fine. I was able to read and write the data. 

    But a question occurred to me with respect to build-in SPI Flash of the DA14531MOD-00F01002. As in the documentation for the SPI-Flash (http://lpccs-docs.renesas.com/da145xx_tutorial_sdk6_peripherals/da14531_spi_flash.html) is stated that the PRo and USB Dev Kit use the Macronix MX25R2035 SPI flash the setting is made accordingly. Do I need to change something in the setting of the SPI-flash when switchin from the USB Dev Kit to the Module DA14531MOD-00F01002? 

    Thanks in advance. 
    patipat3110

  • Hi Patipat3110,

    Thank you for the reply.
    Glad you were able to figure out what was causing your BKPT issues. 
    1.Yes you should reserve and configure the PINs you want to use. If you have disabled the CFG_DEVELOPMENT_DEBUG macro then you can just Configure them. 
    2. Yes your approach to add spi_flash_release_from_power_down() function before reading the SPI Flash is correct.

    Regarding the P25Q11U Flash which is integrated inside the DA14531MOD:
    Both the Development Kit Pro and the USB Dev Kit have integrated the MX25R2035. 
    If you want to use the P25Q11U Flash you should go on spi_flash.h file and add the following:

    // P25Q11U
    #define P25Q11U_MAN_DEV_ID                      0x8510
    #define P25Q11U_JEDEC_ID                        0x854011
    #define P25Q11U_CHIP_SIZE                       0x20000
    #define P25Q11U_MEM_PROT_UPPER_HALF             4
    #define P25Q11U_MEM_PROT_LOWER_HALF             36
    #define P25Q11U_MEM_PROT_ALL                    8

    /// Device index of supported SPI flash memories
    typedef enum
    {
        /// W25x10CL device index
        W25X10CL_DEV_INDEX = 1,
    
        /// W25x20CL device index
        W25X20CL_DEV_INDEX,
    
        /// AT25DN011/AT25DF011 device index
        AT25DX011_DEV_INDEX,
    
        /// MX25V1006E device index
        MX25V1006E_DEV_INDEX,
    
        /// MX25R1035F device index
        MX25R1035F_DEV_INDEX,
    
        /// MX25R2035F device index
        MX25R2035F_DEV_INDEX,
    
        /// MX25R4035F device index
        MX25R4035F_DEV_INDEX,
    
        /// MX25R8035F device index
        MX25R8035F_DEV_INDEX,
    
        /// MX25R1635F device index
        MX25R1635F_DEV_INDEX,
    
        /// MX25V1035F device index
        MX25V1035F_DEV_INDEX,
    
        /// MX25V2035F device index
        MX25V2035F_DEV_INDEX,
    
        /// MX25V4035F device index
        MX25V4035F_DEV_INDEX,
    
        /// MX25V8035F device index
        MX25V8035F_DEV_INDEX,
    
        /// MX25V1635F device index
        MX25V1635F_DEV_INDEX,
    
        /// P25Q10U device index
        P25Q10U_DEV_INDEX,
    
        P25Q11U_DEV_INDEX,
    
        /// P25Q40U device index
        P25Q40U_DEV_INDEX,
    
        /// GD25WD10 device index
        GD25WD10_DEV_INDEX,
    
        /// GD25WD20 device index
        GD25WD20_DEV_INDEX,
    
        /// AT25DF021A device index
        AT25DF021A_DEV_INDEX,
    
        /// AT25EU0021A device index
        AT25EU0021A_DEV_INDEX,
    
        /// AT25XE041D device index
        AT25XE041D_DEV_INDEX,
    
        /// AT45DB081E device index
        AT45DB081E_DEV_INDEX,
    } spi_flash_dev_index_t;
    

    On spi_flash.c file:
    int8_t spi_flash_auto_detect(uint8_t *dev_id)
    {
        int8_t status;
        // List of known SPI Flash devices
        const spi_flash_cfg_t known_spi_devs_list[] =
        {
            {W25X10CL_DEV_INDEX,    W25X10CL_JEDEC_ID,    W25X10CL_CHIP_SIZE},
            {W25X20CL_DEV_INDEX,    W25X20CL_JEDEC_ID,    W25X20CL_CHIP_SIZE},
            {AT25DX011_DEV_INDEX,   AT25DX011_JEDEC_ID,   AT25DX011_CHIP_SIZE},
            {MX25V1006E_DEV_INDEX,  MX25V1006E_JEDEC_ID,  MX25V1006E_CHIP_SIZE},
            {MX25R1035F_DEV_INDEX,  MX25R1035F_JEDEC_ID,  MX25R1035F_CHIP_SIZE},
            {MX25R2035F_DEV_INDEX,  MX25R2035F_JEDEC_ID,  MX25R2035F_CHIP_SIZE},
            {P25Q10U_DEV_INDEX,     P25Q10U_JEDEC_ID,     P25Q10U_CHIP_SIZE},
            {P25Q11U_DEV_INDEX,     P25Q11U_JEDEC_ID,       P25Q11U_CHIP_SIZE},
            {GD25WD20_DEV_INDEX,    GD25WD20_JEDEC_ID,    GD25WD20_CHIP_SIZE},
            {AT25DF021A_DEV_INDEX,  AT25DF021A_JEDEC_ID,  AT25DF021A_CHIP_SIZE},
            {AT25EU0021A_DEV_INDEX, AT25EU0021A_JEDEC_ID, AT25EU0021A_CHIP_SIZE},
            {AT25XE041D_DEV_INDEX,  AT25XE041D_JEDEC_ID,  AT25XE041D_CHIP_SIZE},
    #if defined (__FPGA__)
            {MX25R8035F_DEV_INDEX,  MX25R8035F_JEDEC_ID,  MX25R8035F_CHIP_SIZE},
            {AT45DB081E_DEV_INDEX,  AT45DB081E_JEDEC_ID,  AT45DB081E_CHIP_SIZE},
    #endif
        };

    Note: These changes are already implemented on the Codeless SDK. So you can go on the following path:
    Codeless\6.380.16.55\sdk6\sdk\platform\driver\spi_flash
    And copy the spi_flash.c/h files into the SDK 6.0.18 on the following path:
    DA145xx\6.0.18.1182.1\sdk\platform\driver\spi_flash
    After that, on user_periph_setup.h use this declarations:
    /****************************************************************************************/
    /* SPI configuration                                                                    */
    /****************************************************************************************/
    // Define SPI Pads
    #if defined (__DA14531__)
    #if !defined (__FPGA__)
        #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
    #else
        #define SPI_EN_PORT             GPIO_PORT_0
        #define SPI_EN_PIN              GPIO_PIN_11
    
        #define SPI_CLK_PORT            GPIO_PORT_0
        #define SPI_CLK_PIN             GPIO_PIN_7
    
        #define SPI_DO_PORT             GPIO_PORT_0
        #define SPI_DO_PIN              GPIO_PIN_9
    
        #define SPI_DI_PORT             GPIO_PORT_0
        #define SPI_DI_PIN              GPIO_PIN_10
    #endif
    
    #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
    
    // Define SPI Configuration
        #define SPI_MS_MODE             SPI_MS_MODE_MASTER
        #define SPI_CP_MODE             SPI_CP_MODE_0
        #define SPI_WSZ                 SPI_MODE_8BIT
        #define SPI_CS                  SPI_CS_0
    
    #if defined(__DA14531__)
        #define SPI_SPEED_MODE          SPI_SPEED_MODE_4MHz
        #define SPI_EDGE_CAPTURE        SPI_MASTER_EDGE_CAPTURE
    #else // (DA14585, DA14586)
        #define SPI_SPEED_MODE          SPI_SPEED_MODE_4MHz
    #endif
    
    #if !defined (__DA14586__)
    #define SPI_FLASH_DEV_SIZE          (128 * 1024)
    #endif

    And on user_periph_setup.c file:
    /**
     ****************************************************************************************
     *
     * @file user_periph_setup.c
     *
     * @brief Peripherals setup and initialization.
     *
     * Copyright (C) 2015-2019 Dialog Semiconductor.
     * This computer program includes Confidential, Proprietary Information
     * of Dialog Semiconductor. All Rights Reserved.
     *
     ****************************************************************************************
     */
    
    /*
     * INCLUDE FILES
     ****************************************************************************************
     */
    
    #include "user_periph_setup.h"
    #include "datasheet.h"
    #include "system_library.h"
    #include "rwip_config.h"
    #include "gpio.h"
    #include "uart.h"
    #include "syscntl.h"
    #include "spi.h"
    #include "spi_flash.h"
    /*
     * GLOBAL VARIABLE DEFINITIONS
     ****************************************************************************************
     */
    
    #if DEVELOPMENT_DEBUG
    
    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_SPI_FLASH_ENABLE)	
    	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);
    #endif
    	
    #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
    }
    
    #endif
    
    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 (CFG_SPI_FLASH_ENABLE)
        // Configure SPI pins
        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);
        
       
    #endif
    #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
    
    }
    
    #if defined (CFG_PRINTF_UART2)
    // Configuration struct for UART2
    static const uart_cfg_t uart_cfg = {
        .baud_rate = UART2_BAUDRATE,
        .data_bits = UART2_DATABITS,
        .parity = UART2_PARITY,
        .stop_bits = UART2_STOPBITS,
        .auto_flow_control = UART2_AFCE,
        .use_fifo = UART2_FIFO,
        .tx_fifo_tr_lvl = UART2_TX_FIFO_LEVEL,
        .rx_fifo_tr_lvl = UART2_RX_FIFO_LEVEL,
        .intr_priority = 2,
    };
    #endif
    
    
    /* SPI flash configuration - assumes use of a Macronix MXR2035F as this is
       present on the DA145xx PRO development kit */
    //static const spi_flash_cfg_t spi_flash_cfg = {
    //    .dev_index = MX25R2035F_DEV_INDEX,
    //    .jedec_id  = MX25V2035F_JEDEC_ID,
    //    .chip_size = MX25V2035F_CHIP_SIZE,
    //};
    // Configuration struct for SPI
    static const spi_cfg_t spi_cfg = {
        .spi_ms = SPI_MS_MODE,
        .spi_cp = SPI_CP_MODE,
        .spi_speed = SPI_SPEED_MODE,
        .spi_wsz = SPI_WSZ,
        .spi_cs = SPI_CS,
        .cs_pad.port = SPI_EN_PORT,
        .cs_pad.pin = SPI_EN_PIN,
    #if defined (__DA14531__)
        .spi_capture = SPI_EDGE_CAPTURE,
    #endif
    #if defined (CFG_SPI_DMA_SUPPORT)
        .spi_dma_channel = SPI_DMA_CHANNEL_01,
        .spi_dma_priority = DMA_PRIO_0,
    #endif
    };
    
    // Configuration struct for SPI FLASH
    static const spi_flash_cfg_t spi_flash_cfg = {
        .chip_size = SPI_FLASH_DEV_SIZE,
    };
    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
    
        // Configure SPI Flash environment
         spi_flash_configure_env(&spi_flash_cfg);
    
        // Initialize SPI
        spi_initialize(&spi_cfg);
    
        // Set pad functionality
        set_pad_functions();
    
        // Enable the pads
        GPIO_set_pad_latch_en(true);
    }
    


    With these configurations I am able to read/write/erase the P25Q11U SPI Flash which is integrated on the DA14531MOD.
    This configuration is based on the spi_flash example. You can find this example on the following path:
    DA14531\6.0.18.1182.1\projects\target_apps\peripheral_examples\spi\spi_flash

    Kind Regards,
    OV_Renesas

  • Hi again, 

    thanks for the answer. As soon as I have finalized the SW development I will change the SPI Flash settings to the P25Q11U and try whether it is working properly. 

    I am facing again an issue with the SPI flash as I am not able to erase the using the erase commands. 
    I have tried all of the following : 

    - spi_flash_page_erase(0x2000);
    - spi_flash_block_erase(0x2000, SPI_FLASH_OP_SE); also tried SPI_FLASH_OP_BE32 and SPI_FLASH_OP_BE64
    - spi_flash_block_erase_no_wait(0x2000, SPI_FLASH_OP_SE);
    - spi_flash_chip_erase();
    - spi_flash_chip_erase_forced();

    My expection would be that when calling erase function and reading afterwards, the result of the read function would be "FF". For example reading 0x2000 after erase using 

    ret = spi_flash_read_data(&data_read[0],0x2000 , sizeof(data_read), &bytes_read);

    should result in the output for data_read as "255 255 255 255 255". Unfortunately after any erase command I am still reading "1 1 2 2 1" as shown from your code. I also checked the documenation http://lpccs-docs.renesas.com/da145xx_tutorial_sdk6_peripherals/da14531_spi_flash.html= but can't find a solution. 
    Am I missing something? 

    Thanks for the help, 
    patipat3110

  • Hi Patipat3110,

    Thank you for the reply.
    I am still working on the empty_peripheral_example and I am able to read/write/erase the SPI Flash.
    Please share the code snippet you have created so we could take a look.
    Based on your previous code snippet I write data on 4 different addresses, then I read the data I just wrote, then I use the spi_flash_chip_erase_forced() function to erase the SPI Flash. At the end I read again the addresses to see the values (0xFF=255) after erasing. The same applies for spi_flash_block_erase which I have commented out in my code. Both those approaches worked on my side:
    So, the code snippet looks like this:

    uint8_t default_pass[] = { 1, 1, 2, 2, 1, 9, 7, 3};
    int counter =0;
    void check_nvs_available()
    {
    	// Disable HW RST on P0_0 so it can be used as SPI MOSI.
    	GPIO_Disable_HW_Reset();
    	arch_printf("\n\r GPIO Disabled \n\r");
    	
    	// Read PC Flash --> IF PC Flash was not written in advance rewrite with default PC | ELSE do nothing 
    	int8_t ret;
    	uint32_t bytes_read;
    	char buffer_pc[7];
    	uint8_t buffer_spi[7];
    	uint8_t data_read[7] = { 0 };
    	spi_flash_release_from_power_down();
    	ret = spi_flash_read_data(&data_read[0],0x0000 , sizeof(data_read), &bytes_read);
    	arch_printf("Read Passcode from Flash! \n\r");
    	arch_printf("Read Status: %d \n\r", ret);
    	arch_printf("Bytes read:");
    
    	for(int i=0;i<7;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	bool data_read_empty=false;
    
    	for(int j=0;j<7;j++)
    	{
    		if(data_read[j] == default_pass[j])
    		{
    			counter++;
    		}
    	}
    	if(counter ==7)
    	{
    		data_read_empty = true;
    //		arch_printf("\r\n Equal \r\n");
    	}
    	else
    	{
    		data_read_empty = false;
    //		arch_printf("\r\n Not Equal \r\n");
    	}
    	
    	if(!data_read_empty)
    	{
    		uint32_t pc_bytes_written;
    	//	arch_printf("\n\r WRITE Passcode to Flash! \n\r");
    		uint8_t data[8] = { default_pass[0], default_pass[1], default_pass[2], default_pass[3], default_pass[4], default_pass[5], default_pass[6], default_pass[7]};
    		uint8_t data2[8] = { default_pass[2], default_pass[1], default_pass[1], default_pass[1], default_pass[3], default_pass[6], default_pass[7], default_pass[7]};
    		uint8_t data3[8] = { default_pass[5], default_pass[5], default_pass[2], default_pass[5], default_pass[4], default_pass[5], default_pass[7], default_pass[1]};
    		uint8_t data4[8] = { default_pass[3], default_pass[4], default_pass[2], default_pass[2], default_pass[6], default_pass[6], default_pass[6], default_pass[6]};
    		spi_flash_release_from_power_down();
    		/* Write data on address 0x0000 */
    		ret = spi_flash_write_data(&data[0], 0x0000, sizeof(data), &pc_bytes_written);
    		arch_printf("\n\rWrite Status for 0x0000: %d", ret);
    		/* Write data on address 0x1000 */
    		ret = spi_flash_write_data(&data2[0], 0x1000, sizeof(data), &pc_bytes_written);
    		arch_printf("\n\rWrite Status for 0x1000: %d", ret);
    		/* Write data on address 0x2000 */
    		ret = spi_flash_write_data(&data3[0], 0x2000, sizeof(data), &pc_bytes_written);
    		arch_printf("\n\rWrite Status for 0x2000: %d", ret);
    		/* Write data on address 0x3000 */
    		ret = spi_flash_write_data(&data4[0], 0x3000, sizeof(data), &pc_bytes_written);
    		arch_printf("\n\rWrite Status for 0x3000: %d", ret);
    		/* Write data on address 0x4000 */
    		ret = spi_flash_write_data(&data[0], 0x4000, sizeof(data), &pc_bytes_written);
    		arch_printf("\n\rWrite Status for 0x4000: %d", ret);
    	 // arch_printf("\n\rBytes Written: %d", pc_bytes_written);
    	}
    	/*Read all the data before trying to erase */
    	/*Read the data stored on address 0x0000 */
    	arch_printf("\n\r ****************************** \n\r");
    	arch_printf("Read the data we wrote \n\r");
    	arch_printf("******************************\n\r");
    	ret = spi_flash_read_data(&data_read[0],0x0000 , sizeof(data_read), &bytes_read);
    	arch_printf("\n\rRead Status for 0x0000: %d \n\r", ret);
    	arch_printf("Bytes read:");
    
    	for(int i=0;i<7;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	arch_printf("\n\r");
    	/*Read the data stored on address 0x1000 */
    	ret = spi_flash_read_data(&data_read[0],0x1000 , sizeof(data_read), &bytes_read);
    	arch_printf("\n\rRead Status for 0x1000: %d \n\r", ret);
    	arch_printf("\n\rBytes read:");
    
    	for(int i=0;i<7;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	arch_printf("\n\r");
    	/*Read the data stored on address 0x2000 */
    	ret = spi_flash_read_data(&data_read[0],0x2000 , sizeof(data_read), &bytes_read);
    	arch_printf("\n\rRead Status for 0x2000: %d \n\r", ret);
    	arch_printf("Bytes read:");
    
    	for(int i=0;i<7;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	arch_printf("\n\r");
    	/*Read the data stored on address 0x3000 */
    	ret = spi_flash_read_data(&data_read[0],0x3000 , sizeof(data_read), &bytes_read);
    	arch_printf("\n\rRead Status for 0x3000: %d \n\r", ret);
    	arch_printf("Bytes read:");
    
    	for(int i=0;i<7;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	arch_printf("\n\r");
    	/*Read the data stored on address 0x4000 */
     	ret = spi_flash_read_data(&data_read[0],0x4000 , sizeof(data_read), &bytes_read);
    	arch_printf("\n\rRead Status for 0x4000: %d \n\r", ret);
    	arch_printf("Bytes read:");
    
    	for(int i=0;i<7;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	arch_printf("\n\r");
    //	/*Erase the Flash block on address 0x0000 */
    //    ret = spi_flash_block_erase(0x0000, SPI_FLASH_OP_SE);
    //    arch_printf("\n\rErase Status: %d", ret);
    	
    	/* Erase everything from Flash */
    	 ret = spi_flash_chip_erase_forced();
     	 arch_printf("\n\rErase Status Forced: %d", ret);
    	
    	/*Read again after erasing the addresses 0x0000, 0x1000, 0x2000, 0x3000, 0x4000 */
    	/*Read the data stored on address 0x0000 */
    	arch_printf("\n\r ****************************** \n\r");
    	arch_printf("Read the sectors we had data written \n\r");
    	arch_printf("******************************\n\r");
    	ret = spi_flash_read_data(&data_read[0],0x0000 , sizeof(data_read), &bytes_read);
    	arch_printf("\n\rRead Status for 0x0000: %d \n\r", ret);
    	arch_printf("Bytes read:");
    
    	for(int i=0;i<7;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	arch_printf("\n\r");
    	/*Read the data stored on address 0x1000 */
    	ret = spi_flash_read_data(&data_read[0],0x1000 , sizeof(data_read), &bytes_read);
    	arch_printf("\n\rRead Status for 0x1000: %d \n\r", ret);
    	arch_printf("Bytes read:");
    
    	for(int i=0;i<7;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	arch_printf("\n\r");
    	/*Read the data stored on address 0x2000 */
    	ret = spi_flash_read_data(&data_read[0],0x2000 , sizeof(data_read), &bytes_read);
    	arch_printf("\n\rRead Status for 0x2000: %d \n\r", ret);
    	arch_printf("Bytes read:");
    
    	for(int i=0;i<7;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	arch_printf("\n\r");
    	/*Read the data stored on address 0x3000 */
    	ret = spi_flash_read_data(&data_read[0],0x3000 , sizeof(data_read), &bytes_read);
    	arch_printf("\n\rRead Status for 0x3000: %d \n\r", ret);
    	arch_printf("Bytes read:");
    
    	for(int i=0;i<7;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	arch_printf("\n\r");
    	/*Read the data stored on address 0x4000 */
     	ret = spi_flash_read_data(&data_read[0],0x4000 , sizeof(data_read), &bytes_read);
    	arch_printf("\n\rRead Status for 0x4000: %d \n\r", ret);
    	arch_printf("Bytes read:");
    
    	for(int i=0;i<7;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	arch_printf("\n\r");
    	
    	// 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();
    }

    And on Tera Term I can see:


    Kind Regards,
    OV_Renesas

  • Hi OV_Renesas, 

    thanks for the clarification. Here is the code snippet I am working with in user_peripheral_c. 

    #include "rwip_config.h"             // SW configuration
    #include "gap.h"
    #include "app_easy_timer.h"
    #include "user_peripheral.h"
    #include "user_custs1_impl.h"
    #include "user_custs1_def.h"
    #include "co_bt.h"
    #include "spi_flash.h"
    #include "user_periph_setup.h"
    #include <stdlib.h>
    #include "arch_console.h"
    
    uint32_t PC_FLASH_ADR = 0x2000;
    uint8_t default_pass[] = { 1, 2, 3, 4, 5};
    uint8_t no_pass_written[] = {255, 255, 255, 255, 255};
    
    void read_pc()
    {
    	arch_printf("\n\r----- %s -----\n\r", __FUNCTION__);
    	// Disable HW RST on P0_0 so it can be used as SPI MOSI.
    	GPIO_Disable_HW_Reset();
    	GPIO_ConfigurePin(SPI_DO_PORT, SPI_DO_PIN, OUTPUT, PID_SPI_DO, false);
    	arch_printf("GPIO Disabled \n\r");
    	// Wakeup flash from sleep mode to interact with it 
    	int8_t err;
    	err = spi_flash_release_from_power_down();
    	arch_printf("SPI wakeup status: %d \n\r", err);
    	err = spi_flash_is_busy();
    	arch_printf("SPI busy status: %d \n\r", err);
    		
    	int8_t ret;
    	uint32_t bytes_read;
    	uint8_t data_read[5] = { 0 };
    	//int counter; 
    	ret = spi_flash_read_data(&data_read[0],PC_FLASH_ADR , sizeof(data_read), &bytes_read);
    	arch_printf("Read PC from Flash! \n\r");
    	arch_printf("read Status: %d \n\r", ret);
    	arch_printf("PC bytes read:");
    	
    	// Print the PC read from flash --> DEBUG 
    	for(int i=0;i<5;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	arch_printf("\n\r");
    	
    	// Reduce power consumption by putting flash into sleep mode 
    	err = spi_flash_power_down();
    	arch_printf("SPI goto sleep status: %d\n\r",err);
    	// 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();
    	
    }
    
    
    void check_nvs_available()
    {
    	arch_printf("\n\r----- %s -----\n\r", __FUNCTION__);
    	// Disable HW RST on P0_0 so it can be used as SPI MOSI.
    	GPIO_Disable_HW_Reset();
    	GPIO_ConfigurePin(SPI_DO_PORT, SPI_DO_PIN, OUTPUT, PID_SPI_DO, false);
    	arch_printf("GPIO Disabled \n\r");
    	// Wakeup flash from sleep mode to interact with it 
    	spi_flash_release_from_power_down();
    
    	
    	//int8_t rets;
    	//rets = spi_flash_block_erase(PC_FLASH_ADR, SPI_FLASH_OP_SE);
    	//arch_printf("\n\rErase Status: %d \n\r", rets);
    	
    	// Read PC Flash --> IF PC Flash was not written in advance rewrite with default PC | ELSE do nothing 
    	int8_t ret;
    	uint32_t bytes_read;
    	uint8_t data_read[5] = { 0 };
    	int counter = 0; 
    	ret = spi_flash_read_data(&data_read[0],PC_FLASH_ADR , sizeof(data_read), &bytes_read);
    	arch_printf("Read PC from Flash! \n\r");
    	arch_printf("read Status: %d \n\r", ret);
    	arch_printf("PC bytes read:");
    	
    	// Print the PC read from flash --> DEBUG
    	for(int i=0;i<5;i++)
    	{
    		arch_printf(" %d", data_read[i]);
    	}
    	arch_printf("\n\r");
    	bool passcode_empty=false;
    	
    	for(int j=0;j<5;j++)
    	{
    		if(data_read[j] == no_pass_written[j])
    		{
    			counter++;
    		}
    	}
    	if(counter ==5)
    	{
    		passcode_empty = true;
    		arch_printf("PC Empty -> Write defualt PC to Flash! \n\r");
    	}
    	else
    	{
    		passcode_empty = false;
    		arch_printf("PC Not Empty \n\r");
    	}
    	
    	if(passcode_empty)
    	{
    		arch_printf("Writing PC!!!! \n\r");
    		uint32_t pc_bytes_written;
    		uint8_t data[5] = { default_pass[0], default_pass[1], default_pass[2], default_pass[3], default_pass[4]};
    		ret = spi_flash_write_data(&data[0], PC_FLASH_ADR, sizeof(data), &pc_bytes_written);
    		arch_printf("\n\rWrite Status: %d", ret);
    	  arch_printf("\n\rBytes Written: %d", pc_bytes_written);
    		arch_printf("\n\r Written: %d %d %d %d %d \n\r",default_pass[0], default_pass[1], default_pass[2], default_pass[3], default_pass[4]);
    	}
    	
    	// 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();
    	
    }
    
    void user_app_init(void)
    {
        app_param_update_request_timer_used = EASY_TIMER_INVALID_TIMER;
    
        // Initialize Manufacturer Specific Data
        mnf_data_init();
    	
        // Initialize Advertising and Scan Response Data
        memcpy(stored_adv_data, USER_ADVERTISE_DATA, USER_ADVERTISE_DATA_LEN);
        stored_adv_data_len = USER_ADVERTISE_DATA_LEN;
        memcpy(stored_scan_rsp_data, USER_ADVERTISE_SCAN_RESPONSE_DATA, USER_ADVERTISE_SCAN_RESPONSE_DATA_LEN);
        stored_scan_rsp_data_len = USER_ADVERTISE_SCAN_RESPONSE_DATA_LEN;
    		
    	
    	arch_printf("\n\r%s", __FUNCTION__);
        default_app_on_init();
    	
    	check_nvs_available();
    	read_pc();
    		
    }

    In TeraTerm I get the following output: 

    As can be seen from the TeraTerm outut the write and read commands are retuned with a value of "0" which indicates that no error occurred. Anyway the read command in read_pc()-function does not return the expected changed value but still the empty value. Am I messing something up in the initialiation of the flash or in the Pin Configuration? 

    I have the following code in user_periph_setup.h:

    /**
     ****************************************************************************************
     *
     * @file user_periph_setup.h
     *
     * @brief Peripherals setup header file.
     *
     * Copyright (C) 2015-2019 Dialog Semiconductor.
     * This computer program includes Confidential, Proprietary Information
     * of Dialog Semiconductor. All Rights Reserved.
     *
     ****************************************************************************************
     */
    
    #ifndef _USER_PERIPH_SETUP_H_
    #define _USER_PERIPH_SETUP_H_
    
    /*
     * INCLUDE FILES
     ****************************************************************************************
     */
    
    #include "gpio.h"
    #include "uart.h"
    #include "spi.h"
    #include "spi_flash.h"
    #include "i2c.h"
    #include "i2c_eeprom.h"
    
    
    
    /*
     * DEFINES
     ****************************************************************************************
     */
    
    /****************************************************************************************/
    /* UART2 configuration                                                                  */
    /****************************************************************************************/
    // Define UART2 Tx Pad
    #if defined (__DA14531__)
        #define UART2_TX_PORT           GPIO_PORT_0
        #define UART2_TX_PIN            GPIO_PIN_5
    #else
        #define UART2_TX_PORT           GPIO_PORT_0
        #define UART2_TX_PIN            GPIO_PIN_4
    #endif
    
    // Define UART2 Settings
    #define UART2_BAUDRATE              UART_BAUDRATE_115200
    #define UART2_DATABITS              UART_DATABITS_8
    #define UART2_PARITY                UART_PARITY_NONE
    #define UART2_STOPBITS              UART_STOPBITS_1
    #define UART2_AFCE                  UART_AFCE_DIS
    #define UART2_FIFO                  UART_FIFO_EN
    #define UART2_TX_FIFO_LEVEL         UART_TX_FIFO_LEVEL_0
    #define UART2_RX_FIFO_LEVEL         UART_RX_FIFO_LEVEL_0
    
    
    /****************************************************************************************/
    /* LED configuration                                                                    */
    /****************************************************************************************/
    #if defined (__DA14531__)
        #define LED_GPIO_PORT           GPIO_PORT_0
        #define LED_GPIO_PIN            GPIO_PIN_9
    		#define ERASE_FLASH_PORT					GPIO_PORT_0
    		#define ERASE_FLASH_PIN						GPIO_PIN_8
    #else
        #define BELL_GPIO_PORT           GPIO_PORT_1
        #define BELL_GPIO_PIN            GPIO_PIN_0
    #endif
    
    /****************************************************************************************/
    /* 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
    
    /***************************************************************************************/
    /* Production debug output configuration                                               */
    /***************************************************************************************/
    #if PRODUCTION_DEBUG_OUTPUT
    #if defined (__DA14531__)
        #define PRODUCTION_DEBUG_PORT   GPIO_PORT_0
        #define PRODUCTION_DEBUG_PIN    GPIO_PIN_11
    #else
        #define PRODUCTION_DEBUG_PORT   GPIO_PORT_2
        #define PRODUCTION_DEBUG_PIN    GPIO_PIN_5
    #endif
    #endif
    
    
    /*
     * FUNCTION DECLARATIONS
     ****************************************************************************************
     */
    
    #if DEVELOPMENT_DEBUG
    /**
     ****************************************************************************************
     * @brief   Reserves application's specific GPIOs
     * @details Used only in Development mode (#if DEVELOPMENT_DEBUG)
     *          i.e. to reserve P0_1 as Generic Purpose I/O:
     *          RESERVE_GPIO(DESCRIPTIVE_NAME, GPIO_PORT_0, GPIO_PIN_1, PID_GPIO);
     ****************************************************************************************
     */
    void GPIO_reservations(void);
    #endif
    
    /**
     ****************************************************************************************
     * @brief   Sets the functionality of application pads
     * @details i.e. to set P0_1 as Generic purpose Output:
     *          GPIO_ConfigurePin(GPIO_PORT_0, GPIO_PIN_1, OUTPUT, PID_GPIO, false);
     ****************************************************************************************
     */
    void set_pad_functions(void);
    
    /**
     ****************************************************************************************
     * @brief   Initializes application's peripherals and pins
     ****************************************************************************************
     */
    void periph_init(void);
    
    
    #endif // _USER_PERIPH_SETUP_H_

    And the following code in user_periph_setup.c:

    /**
     ****************************************************************************************
     *
     * @file user_periph_setup.c
     *
     * @brief Peripherals setup and initialization.
     *
     * Copyright (C) 2015-2019 Dialog Semiconductor.
     * This computer program includes Confidential, Proprietary Information
     * of Dialog Semiconductor. All Rights Reserved.
     *
     ****************************************************************************************
     */
    
    /*
     * INCLUDE FILES
     ****************************************************************************************
     */
    
    #include "user_periph_setup.h"
    #include "datasheet.h"
    #include "system_library.h"
    #include "rwip_config.h"
    #include "gpio.h"
    #include "uart.h"
    #include "syscntl.h"
    #include "spi.h"
    #include "spi_flash.h"
    #include "arch_console.h"
    
    /*
     * GLOBAL VARIABLE DEFINITIONS
     ****************************************************************************************
     */
    
    /**
     ****************************************************************************************
     * @brief Each application reserves its own GPIOs here.
     ****************************************************************************************
     */
    
    #if DEVELOPMENT_DEBUG
    
    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);
    */
    	
    	
    	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);
    	
    	#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(LED, LED_GPIO_PORT, LED_GPIO_PIN, PID_GPIO);
    	RESERVE_GPIO(ERASE_FLASH, ERASE_FLASH_PORT, ERASE_FLASH_PIN, PID_GPIO);
    }
    
    #endif
    
    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);
    */
    	
    	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);
    
    #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(LED_GPIO_PORT, LED_GPIO_PIN, OUTPUT, PID_GPIO, false);
    	GPIO_ConfigurePin(ERASE_FLASH_PORT, ERASE_FLASH_PIN, INPUT_PULLDOWN, PID_GPIO, false);
        
    }
    
    #if defined (CFG_PRINTF_UART2)
    // Configuration struct for UART2
    static const uart_cfg_t uart_cfg = {
        .baud_rate = UART2_BAUDRATE,
        .data_bits = UART2_DATABITS,
        .parity = UART2_PARITY,
        .stop_bits = UART2_STOPBITS,
        .auto_flow_control = UART2_AFCE,
        .use_fifo = UART2_FIFO,
        .tx_fifo_tr_lvl = UART2_TX_FIFO_LEVEL,
        .rx_fifo_tr_lvl = UART2_RX_FIFO_LEVEL,
        .intr_priority = 2,
    };
    
    #endif
    
    /* Default SPI configuration */
    static const spi_cfg_t spi_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 flash configuration - assumes use of a Macronix MXR2035F as this is
       present on the DA145xx PRO development kit */
    static const spi_flash_cfg_t spi_flash_cfg = {
        .dev_index = MX25R2035F_DEV_INDEX,
        .jedec_id  = MX25V2035F_JEDEC_ID,
        .chip_size = MX25V2035F_CHIP_SIZE,
    };
    
    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
    		// Initialize interface to SPI flash so we can use it from within the application
    		spi_flash_configure_env(&spi_flash_cfg);
    		spi_initialize(&spi_cfg);
    	
        // Set pad functionality
        set_pad_functions();
    
        // Enable the pads
        GPIO_set_pad_latch_en(true);
    }
    

    Thank you very much for the support. 

  • Hi Patipat3110,

    Thank you for the reply.
    I copied the code snippets you shared on the ble_app_peripheral example and on Tera Term I got the following results:

    I am able to read the contents of the SPI Flash from the read_PC function.
    Are you working with the USB Dev Kit? Have you made any other configurations on your project?

    Kind Regards,
    OV_Renesas

  • Hi, 

    thanks for the fast response and the verification that my code is working on your side. Yes, I am working with the USB Dev Kit with following Switch-Settings: 

    In the mean-time I have also copied my code I posted here for user_peripheral_c , user_periph_setup.h and user_periph_setup.c into a fresh, unchanged example project of ble_app_peripheral. To do so I unpacked the zip again and used the respective file. The additional change I did was to change

     

    #undef CFG_PRINTF

    to 

    #define CFG_PRINTF
     

    within da1458x_config_basic.h to enable the arch_printf function as described in the documentation. Beside from these changes I don't have changed anything else. Anyway I am not able to write correctly as I still get this output: 

    Could it be that I have messed with the Flash of the USB Dev Kit within SmartSnippets Toolbox or with some commant I sent for testing purpose? Can I reset the USB Dev Kit to factory settings using SmartSnippets Toolbox? It seems that the issue is coming from the USB Dev Kit as I have performed the same steps you did but I sitll could not write correctly. 

  • Hi Patipat3110,

    Thank you for the reply.
    Yes, you are correct, you should define the CFG_PRINTF macro, I forgot to mention it on my previous answer.

    Could it be that I have messed with the Flash of the USB Dev Kit within SmartSnippets Toolbox or with some commant I sent for testing purpose? Can I reset the USB Dev Kit to factory settings using SmartSnippets Toolbox?

    No, you could not have messed the Flash of the USB Dev Kit by this way.
    I believe the reason you are facing this issue is due to the multiplexing on the DIP switches of the USB Dev Kit. 
    As you can see from the UM-B-125, on 5.4 Default Configuration, page: 11

    You are using the default configuration as well. This is the reason you have set P0_5 as your UART_TX Pin.

    As you can see the DIP Switches have multiple functionalities for pins P0_0 up to P0_6.
    I will try to recreate your code with a USB Dev Kit as well and I will share my results.
    In the meantime can you add a BKPT after you have wrote or erased the SPI Flash and use the Smart Snippets Toolbox to see if you are able to see those changes on the Flash?

    Kind Regards,
    OV_Renesas