Controlling GPIO within nrfjprog

Hello,

I have a product with QSPI flash that I would like to use nrfjprog to program the flash part. However, the QSPI flash's VCC is controlled (via a FET) from a GPIO line. I am looking for a way to have nrfjprog enable the GPIO line before attempting to access the QSPI flash (so that the flash is powered up). Is there a way from qspiinit.ini to do this?

Thanks,

Jon

Parents
  • Hello Jon,

    Unfortunately, nrfjprog currently does not have a setting to let you define the IO state for a particular GPIO during QSPI programming. I will make a feature request for it internally. In the meantime, maybe you can use pynrfjprog instead. Here is an example script proposed by one of the developers:

    from pynrfjprog import LowLevel
    from pathlib import Path
    import logging
    # Uncomment to enable verbose log output
    # logging.basicConfig(level=logging.DEBUG)
    target_cp = LowLevel.CoProcessor.CP_APPLICATION
    debugger_snr = 960158306 # Update with your snr here
    hex_to_flash = Path('qspi_hex.hex')
    if not hex_to_flash.exists():
        raise AssertionError(f"Selected hex {hex_to_flash} file does not exist")
    with LowLevel.API("NRF53", log=True) as api:
        # Connect and halt target core
        print("Connect to target")
        api.connect_to_emu_with_snr(debugger_snr)
        api.enable_coprocessor(target_cp)
        api.select_coprocessor(target_cp)
        api.connect_to_device()
        api.halt()
        # Disable MPU/SPU if enabled. Behaviour is device spesific.
        # For nRF53 it will issue a system reset w/halt
        print("Disable bprot")
        api.disable_bprot()
        
        # Example set GPIO P0.31 low (will light up LED4 on nRF53 DK)
        # Refer to device datasheet for addresses and values
        print("Set pin low")
        pin = 31
        gpio_base = 0x50842500
        gpio_dirset = gpio_base + 0x018
        gpio_outclr = gpio_base + 0x00C
        val = (1 << pin)
        api.write_u32(gpio_dirset, val, False)
        api.write_u32(gpio_outclr, val, False)
        # Enable qspi module
        api.qspi_init()
        
        # Do the programming yourself using QSPI functions
        addr = 0 # Address 0 is start of QSPI 
        data_len = 100
        data = list(range(0, data_len)) # data = [0,1,2,3 ... , 99]
        api.qspi_erase(addr, LowLevel.QSPIEraseLen.ERASE4KB) # Erase first page
        api.qspi_write(addr, data) # Write data
        # Read and verify
        device_data = api.qspi_read(addr, data_len) 
        assert data == list(device_data)
        # Optionally reset programmed device
        print("Applying pin reset")
        api.pin_reset()
        print("Done")

    Optionally you can try to use the program_file function. But we do not guarantee that there will not be a reset during programming (which will result in the GPIO being reset

    from pynrfjprog import LowLevel
    from pathlib import Path
    import logging
    # Uncomment to enable verbose log output
    # logging.basicConfig(level=logging.DEBUG)
    target_cp = LowLevel.CoProcessor.CP_APPLICATION
    debugger_snr = 960158306 # Update with your snr here
    hex_to_flash = Path('qspi_hex.hex')
    if not hex_to_flash.exists():
        raise AssertionError(f"Selected hex {hex_to_flash} file does not exist")
    with LowLevel.API("NRF53", log=True) as api:
        # Connect and halt target core
        print("Connect to target")
        api.connect_to_emu_with_snr(debugger_snr)
        api.enable_coprocessor(target_cp)
        api.select_coprocessor(target_cp)
        api.connect_to_device()
        api.halt()
        # Disable MPU/SPU if enabled. Behaviour is device spesific.
        # For nRF53 it will issue a system reset w/halt
        print("Disable bprot")
        api.disable_bprot()
        
        # Example set GPIO P0.31 low (will light up LED4 on nRF53 DK)
        # Refer to device datasheet for addresses and values
        print("Set pin low")
        pin = 31
        gpio_base = 0x50842500
        gpio_dirset = gpio_base + 0x018
        gpio_outclr = gpio_base + 0x00C
        val = (1 << pin)
        api.write_u32(gpio_dirset, val, False)
        api.write_u32(gpio_outclr, val, False)
        # Program your hex file
        print("Programming device")
        api.erase_file(hex_to_flash) # Optional: erase memory before writing
        api.program_file(hex_to_flash)
        api.verify_file(hex_to_flash) # Optional: verify after write
        # Optionally reset programmed device
        print("Applying pin reset")
        api.pin_reset()
        print("done")

    Best regards,

    Vidar

Reply
  • Hello Jon,

    Unfortunately, nrfjprog currently does not have a setting to let you define the IO state for a particular GPIO during QSPI programming. I will make a feature request for it internally. In the meantime, maybe you can use pynrfjprog instead. Here is an example script proposed by one of the developers:

    from pynrfjprog import LowLevel
    from pathlib import Path
    import logging
    # Uncomment to enable verbose log output
    # logging.basicConfig(level=logging.DEBUG)
    target_cp = LowLevel.CoProcessor.CP_APPLICATION
    debugger_snr = 960158306 # Update with your snr here
    hex_to_flash = Path('qspi_hex.hex')
    if not hex_to_flash.exists():
        raise AssertionError(f"Selected hex {hex_to_flash} file does not exist")
    with LowLevel.API("NRF53", log=True) as api:
        # Connect and halt target core
        print("Connect to target")
        api.connect_to_emu_with_snr(debugger_snr)
        api.enable_coprocessor(target_cp)
        api.select_coprocessor(target_cp)
        api.connect_to_device()
        api.halt()
        # Disable MPU/SPU if enabled. Behaviour is device spesific.
        # For nRF53 it will issue a system reset w/halt
        print("Disable bprot")
        api.disable_bprot()
        
        # Example set GPIO P0.31 low (will light up LED4 on nRF53 DK)
        # Refer to device datasheet for addresses and values
        print("Set pin low")
        pin = 31
        gpio_base = 0x50842500
        gpio_dirset = gpio_base + 0x018
        gpio_outclr = gpio_base + 0x00C
        val = (1 << pin)
        api.write_u32(gpio_dirset, val, False)
        api.write_u32(gpio_outclr, val, False)
        # Enable qspi module
        api.qspi_init()
        
        # Do the programming yourself using QSPI functions
        addr = 0 # Address 0 is start of QSPI 
        data_len = 100
        data = list(range(0, data_len)) # data = [0,1,2,3 ... , 99]
        api.qspi_erase(addr, LowLevel.QSPIEraseLen.ERASE4KB) # Erase first page
        api.qspi_write(addr, data) # Write data
        # Read and verify
        device_data = api.qspi_read(addr, data_len) 
        assert data == list(device_data)
        # Optionally reset programmed device
        print("Applying pin reset")
        api.pin_reset()
        print("Done")

    Optionally you can try to use the program_file function. But we do not guarantee that there will not be a reset during programming (which will result in the GPIO being reset

    from pynrfjprog import LowLevel
    from pathlib import Path
    import logging
    # Uncomment to enable verbose log output
    # logging.basicConfig(level=logging.DEBUG)
    target_cp = LowLevel.CoProcessor.CP_APPLICATION
    debugger_snr = 960158306 # Update with your snr here
    hex_to_flash = Path('qspi_hex.hex')
    if not hex_to_flash.exists():
        raise AssertionError(f"Selected hex {hex_to_flash} file does not exist")
    with LowLevel.API("NRF53", log=True) as api:
        # Connect and halt target core
        print("Connect to target")
        api.connect_to_emu_with_snr(debugger_snr)
        api.enable_coprocessor(target_cp)
        api.select_coprocessor(target_cp)
        api.connect_to_device()
        api.halt()
        # Disable MPU/SPU if enabled. Behaviour is device spesific.
        # For nRF53 it will issue a system reset w/halt
        print("Disable bprot")
        api.disable_bprot()
        
        # Example set GPIO P0.31 low (will light up LED4 on nRF53 DK)
        # Refer to device datasheet for addresses and values
        print("Set pin low")
        pin = 31
        gpio_base = 0x50842500
        gpio_dirset = gpio_base + 0x018
        gpio_outclr = gpio_base + 0x00C
        val = (1 << pin)
        api.write_u32(gpio_dirset, val, False)
        api.write_u32(gpio_outclr, val, False)
        # Program your hex file
        print("Programming device")
        api.erase_file(hex_to_flash) # Optional: erase memory before writing
        api.program_file(hex_to_flash)
        api.verify_file(hex_to_flash) # Optional: verify after write
        # Optionally reset programmed device
        print("Applying pin reset")
        api.pin_reset()
        print("done")

    Best regards,

    Vidar

Children
No Data
Related