This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello TI support team.
I am writing SBL in UART Mode.
However, it stops with the following error.
I've tried several times, but I can't write successfully.
C:\ti\mcu_plus_sdk_am64x_08_06_00_45\tools\boot>python uart_uniflash.py -p COM3 --cfg=sbl_prebuilt\am64x-evm\default_sbl_ospi.cfg Parsing config file ... Parsing config file ... SUCCESS. Found 3 command(s) !!! Executing command 1 of 3 ... Found flash writer ... sending sbl_prebuilt/am64x-evm/sbl_uart_uniflash.release.tiimage Sending sbl_prebuilt/am64x-evm/sbl_uart_uniflash.release.tiimage: 29%|▊ | 85407/295727 [00:10<00:19, 11032.83bytes/s]send error: expected ACK; got b'\xf0' for block 83 Sending sbl_prebuilt/am64x-evm/sbl_uart_uniflash.release.tiimage: 53%|█ | 156408/295727 [00:16<00:12, 11197.85bytes/s]send error: expected ACK; got b'\x86' for block 151 Sending sbl_prebuilt/am64x-evm/sbl_uart_uniflash.release.tiimage: 94%|█▉| 277830/295727 [00:27<00:01, 11030.89bytes/s]send error: expected ACK; got b'&' for block 12 Sent flashwriter sbl_prebuilt/am64x-evm/sbl_uart_uniflash.release.tiimage of size 295727 bytes in 29.93s. Executing command 2 of 3 ... Command arguments : --operation=flash-phy-tuning-data Sending flash-phy-tuning-data_command: 0%| | 0/32 [00:00<?, ?bytes/s]send error: expected NAK, CRC, EOT or CAN; got b'\x82' send error: expected NAK, CRC, EOT or CAN; got b'\x82' send error: expected NAK, CRC, EOT or CAN; got b'\x82' send error: expected NAK, CRC, EOT or CAN; got b'\x82' send error: expected NAK, CRC, EOT or CAN; got b'\x82' send error: expected NAK, CRC, EOT or CAN; got b'\x82' send error: expected NAK, CRC, EOT or CAN; got b'\x82' send error: expected NAK, CRC, EOT or CAN; got b'\x82' send error: expected NAK, CRC, EOT or CAN; got b'\x82' send error: expected NAK, CRC, EOT or CAN; got b'\x82' send error: expected NAK, CRC, EOT or CAN; got b'\x82' send error: error_count reached 10, aborting. Sending flash-phy-tuning-data_command: 6%|██▌ | 2/32 [00:00<00:00, 45.92bytes/s] [ERROR] XMODEM send failed, no response OR incorrect response from EVM OR cancelled by user, Power cycle EVM and run this script again !!! C:\ti\mcu_plus_sdk_am64x_08_06_00_45\tools\boot>
I would like to know what is wrong.
Best regards,
Kiyomasa Imaizumi.
Hello Prashant Shivhare.
Thank you for your reply.
When I tried to check the device type, I got the following message.
C:\ti\test_code>python 7080.uart_boot_socid.py data3.txt ----------------------- SoC ID Header Info: ----------------------- NumBlocks : [2] ----------------------- SoC ID Public ROM Info: ----------------------- SubBlockId : SubBlockSize : DeviceName : am64x DeviceType : HSFS DMSC ROM Version : [0, 2, 0, 0] R5 ROM Version : [0, 2, 0, 0] ----------------------- SoC ID Secure ROM Info: ----------------------- Sec SubBlockId : 2 Sec SubBlockSize : 166 Sec Prime : 0 Sec Key Revision : 0 Sec Key Count : 0 Sec TI MPK Hash : b018658ad99dc903c8c9bfb27b12751099920a042ad1dfea7b7ba57369f15546de285edde6a7b39a8bdc40a27b237f8fb1e57f245e80b929c1e28b024aa2ecc6 Sec Cust MPK Hash : ad0bc40b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 Sec Unique ID : bfaccfa3107c37bf59fa743ae962b13947dbe52a0934c96132beb6a5944d801a C:\ti\test_code>
It is HS_FS type.
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
This explains why the procedure fails.
Since you are using HSFS device, please make sure you are using HSFS images only (.hs_fs.tiimage/.appimage.hs_fs). There is a hsfs configuration file (default_sbl_ospi_hsfs.cfg) available as well which by default uses hsfs images
~/ti/mcu_plus_sdk/am64x/08_06_00_45/tools/boot ❯ /usr/bin/cat sbl_prebuilt/am64x-evm/default_sbl_ospi_hsfs.cfg #-----------------------------------------------------------------------------# # # # DEFAULT CONFIGURATION FILE TO BE USED WITH THE FLASHWRITER SCRIPT # # # #-----------------------------------------------------------------------------# # # By default this config file, # - points to pre-built flash writer, bootloader for this EVM # - The application image points to relative path of the ipc echo application image for this EVM # - Make sure this application is built before running this script # - You can customized this config file to point to your own bootloader and/or application images # - You can use --operation=flashverify if you just want to verify the flash contents and not flash the file. # # First point to sbl_uart_uniflash binary, which function's as a server to flash one or more files --flash-writer=sbl_prebuilt/am64x-evm/sbl_uart_uniflash.release.hs_fs.tiimage # Now send one or more files to flash or flashverify as needed. The order of sending files does not matter # Program the OSPI PHY tuning attack vector --operation=flash-phy-tuning-data # When sending bootloader make sure to flash at offset 0x0. ROM expects bootloader at offset 0x0 --file=sbl_prebuilt/am64x-evm/sbl_ospi.release.hs_fs.tiimage --operation=flash --flash-offset=0x0 # When sending application image, make sure to flash at offset 0x80000 (default) or to whatever offset your bootloader is configured for --file=../../examples/drivers/ipc/ipc_rpmsg_echo/am64x-evm/system_freertos_nortos/ipc_rpmsg_echo_system.release.appimage.hs_fs --operation=flash --flash-offset=0x80000 # send the XIP image for this application, no need to specify flash offset since flash offset is specified within the image itself --file=../../examples/drivers/ipc/ipc_rpmsg_echo/am64x-evm/system_freertos_nortos/ipc_rpmsg_echo_system.release.appimage_xip --operation=flash-xip
Regards,
Prashant
Hello Prashant Shivhare.
Thank you for the fast reply.
The CPU on the board was AM6422.
It is not the TMDS64EVM CPU (AM6442).
I am using sbl_null.debug.hs_fs.tiimage located in the following directory.
C:\ti\mcu_plus_sdk_am64x_09_01_00_41\tools\boot\sbl_prebuilt\am64x-evm
Can this file be used with AM6422?
Best regards,
Kiyomasa Imaizumi.
Hello Prashant Shivhare.
I added hs_fs because the file name listed in the default_sbl_null.cfg file was missing.
However, the process stops at the following.
C:\ti\mcu_plus_sdk_am64x_08_06_00_45\tools\boot>python uart_uniflash.py -p COM3 --cfg=sbl_prebuilt/am64x-evm/default_sbl_null.cfg Parsing config file ... Parsing config file ... SUCCESS. Found 2 command(s) !!! Executing command 1 of 2 ... Found flash writer ... sending sbl_prebuilt/am64x-evm/sbl_uart_uniflash.release.hs_fs.tiimage Sent flashwriter sbl_prebuilt/am64x-evm/sbl_uart_uniflash.release.hs_fs.tiimage of size 297541 bytes in 26.77s. Executing command 2 of 2 ... Command arguments : --file=sbl_prebuilt/am64x-evm/sbl_null.release.hs_fs.tiimage --operation=flash --flash-offset=0x0 Sending sbl_prebuilt/am64x-evm/sbl_null.release.hs_fs.tiimage: 0%| | 0/273693 [00:00<?, ?bytes/s]
Can this sbl_null.release.hs_fs.tiimage file be used with AM6422?
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
The only diference between AM6422 and AM6442 is the number of R5F cores. The AM6422 has two R5F cores while AM6442 has four R5F cores. All the SBLs are coded to identify the number or cores at run time and accordingly initialize the SoC.
Also, the part numbers AM6422 and AM6442 alone do not identify whether the SoC is GP or HSFS. If the SoC ID parser python script tells it's HSFS device, you must use the HSFS images only.
So, you are using the right images but still the UART Uniflash procedure fails. I am guessing you are working with a custom board. Is that right?
Regards,
Prashant
Hello Prashant Shivhare.
Thank you for your reply.
I am working with custom board with AM6422.
Please tell me how to resulve this problem.
Best regards,
Kiyomasa Imaizumi..
Hello Kiyomasa,
The default `sbl_uart_uniflash` is supposed to work only on TI EVMs. Since you are using custom board, you would need to modify DDR, eMMC and OSPI settings in the `sbl_uart_uniflash` according to your board and use the modified image for flashing.
DDR
Change the default path to your DDR configuration file for your custom DDR
eMMC
In case your board doesn't have an eMMC, change the Card Type to NO_DEVICE
Flash
If you are using custom flash then please refer to the following documentation
AM64x MCU+ SDK: Adding Support For a Custom Flash Device (ti.com)
Regards,
Prashant
Hello Prashant Shivhare.
Thank you for your reply.
Regarding the custom board, the DDR is the same but the FLASH is different.
FLASH has been changed from S28HS512T to IS25LX256.
I configured FLASH using CCS's sysconfig.
I am creating a new *.hs_fs.tiimage for sbl_uart_uniflash and sbl_null.
However, when I run uart_uniflash.py, it stops at the following.
C:\ti\mcu_plus_sdk_am64x_09_01_00_41\tools\boot>python uart_uniflash.py -p COM3 --cfg=sbl_prebuilt/am64x-evm/default_sbl_null.cfg Parsing config file ... Parsing config file ... SUCCESS. Found 2 command(s) !!! Executing command 1 of 2 ... Found flash writer ... sending ../../for_am6422/sbl_uart_uniflash.Debug.hs_fs.tiimage Sending ../../for_am6422/sbl_uart_uniflash.Debug.hs_fs.tiimage: 73%|██▉ | 278859/381813 [00:25<00:09, 11258.62bytes/s]send error: expected ACK; got b'\x04' for block 15 Sent flashwriter ../../for_am6422/sbl_uart_uniflash.Debug.hs_fs.tiimage of size 381813 bytes in 35.0s. Executing command 2 of 2 ... Command arguments : --file=../../for_am6422/sbl_null.Debug.hs_fs.tiimage --operation=flash --flash-offset=0x0 Sending ../../for_am6422/sbl_null.Debug.hs_fs.tiimage: 0%| | 0/342029 [00:00<?, ?bytes/s]
What's wrong?
Are the FLASH settings incorrect?
Please tell me how to debug it.
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
Please tell me how to debug it.
After the flashing procedure ends even if failed, can you please connect to the R5F core via CCS and see the address at which the core is suspended at?
Regards,
Prashant
Hello Prashant Shivhare.
Thank you for your reply.
When I executed the following and stopped, I connected target R5_0_0.
C:\ti\mcu_plus_sdk_am64x_09_01_00_41\tools\boot> python uart_uniflash.py -p COM3 --cfg=sbl_prebuilt/am64x-evm/default_sbl_null.cfg Parsing config file ... Parsing config file ... SUCCESS. Found 2 command(s) !!! Executing command 1 of 2 ... Found flash writer ... sending ../../for_am6422/sbl_uart_uniflash.Debug.hs_fs.tiimage Sending ../../for_am6422/sbl_uart_uniflash.Debug.hs_fs.tiimage: 16%|▊ | 62769/381813 [00:07<00:28, 11380.55bytes/s]send error: expected ACK; got b'\x07' for block 61 Sending ../../for_am6422/sbl_uart_uniflash.Debug.hs_fs.tiimage: 23%|█▏ | 89523/381813 [00:09<00:25, 11277.57bytes/s]send error: expected ACK; got b'\x86' for block 86 Sending ../../for_am6422/sbl_uart_uniflash.Debug.hs_fs.tiimage: 26%|█ | 100842/381813 [00:10<00:24, 11344.61bytes/s]send error: expected ACK; got b'\x04' for block 96 Sending ../../for_am6422/sbl_uart_uniflash.Debug.hs_fs.tiimage: 98%|███▉| 375585/381813 [00:34<00:00, 11354.57bytes/s]send error: expected ACK; got b'\x0e' for block 106 Sent flashwriter ../../for_am6422/sbl_uart_uniflash.Debug.hs_fs.tiimage of size 381813 bytes in 36.08s. Executing command 2 of 2 ... Command arguments : --file=../../for_am6422/sbl_null.Debug.hs_fs.tiimage --operation=flash --flash-offset=0x0 Sending ../../for_am6422/sbl_null.Debug.hs_fs.tiimage: 0%| | 0/342029 [00:00<?, ?bytes/s]
R5_0_0 seems to be suspended at address 0x7001F19E.
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
From the address 0x7001F19E, it looks like the `sbl_uart_uniflash` images boots but gets stuck somewhere.
The next step would be to load the symbols of sbl_uart_uniflash using:
Run -> Load -> Load Symbols... -> Browse -> <MCU_PLUS_SDK_PATH>/examples/drivers/boot/sbl_uart_uniflash/am64x-evm/r5fss0-0_nortos/ti-arm-clang/sbl_uart_uniflash.debug.out
This should tell you where the control is stuck in the code.
Regards,
Prashan
Hello Prashant Shivhare.
Thank you for your reply.
It looks like below.
Best regards,
Kiyomasa Imaizumi.
Hello Prashant Shivhare.
When I step through with F5, it looks like below.
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
It looks like the flash configurations may not be correct.
If you continue the Step Through, does the control move forward in the code or just stuck there?
Regards,
Prashant
Hello Prashant Shivhare.
I did a step through.
The program seems to loop until timeOut reaches 0 using the code below for Flash_norOspiWaitReady.
while((status != SystemP_SUCCESS) || (timeOut > 0)) { status = Flash_norOspiCmdRead(config, cmd, cmdAddr, numAddrBytes, dummyBits, readStatus, numBytesToRead); if((status == SystemP_SUCCESS) && ((readStatus[0] & bitMask) == 0)) { break; } timeOut--; }
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
If the timeout reaches 0 then the status will become SystemP_FAILURE. Have you confirmed this?
Can you please share the ospi_flash_diag output for your custom board?
Regards,
Prashant
Hello Prashant Shivhare.
"timeOut" has not reached 0.
First, the following will appear on the command prompt and the transfer will stop.
[ERROR] XMODEM send failed, no response OR incorrect response from EVM OR cancelled by user, Power cycle EVM and run this script again !!!
I tried ospi_flash_diag.
When uart_unifhasl failed, I connected Target to CR5 and applied Reset.
And I loaded ospi_flash_diag_am64x-evm_r5fss0-0_nortos_ti-arm-clang.
It came out as below.
[OSPI Flash Diagnostic Test] Starting ... [OSPI Flash Diagnostic Test] Flash Manufacturer ID : 0xFF [OSPI Flash Diagnostic Test] Flash Device ID : 0xFFFF [OSPI Flash Diagnostic Test] Executing Flash Erase on first block... [OSPI Flash Diagnostic Test] Erase Failed !!! [OSPI Flash Diagnostic Test] Performing Write-Read Test... [OSPI Flash Diagnostic Test] Wtite Failed !!! ERROR: ospi_flash_diag_test_compare_buffers:181: OSPI read data mismatch !!! Some tests have failed!!
I haven't changed ospi_flash_diag_am64x-evm_r5fss0-0_nortos_ti-arm-clang.
Best regards,
Kiyomasa Imaizumi.
Hello Prashant Shivhare.
There was a hardware error in the FLASH reset.
So when I fixed it, the diagnostic program started working.
It appeared as below.
[OSPI Flash Diagnostic Test] Starting ... [OSPI Flash Diagnostic Test] Flash Manufacturer ID : 0x9D [OSPI Flash Diagnostic Test] Flash Device ID : 0x5A19 [OSPI Flash Diagnostic Test] Executing Flash Erase on first block... [OSPI Flash Diagnostic Test] Done !!! [OSPI Flash Diagnostic Test] Performing Write-Read Test... [OSPI Flash Diagnostic Test] Write-Read Test Passed! [QSPI Flash Diagnostic Test] SFDP Information : ================================================ SFDP ================================================ SFDP Major Revision : 0x1 SFDP Minor Revision : 0x9 Number of Parameter Headers in this Table : 3 Types of Additional Parameter Tables in this flash --------------------------------------------------- 4 BYTE ADDRESSING MODE INSTRUCTIONS TABLE NOR SPI PROFILE TABLE JSON Data for the flash : { "flashSize": 33554432, "flashPageSize": 256, "flashManfId": "0x9D", "flashDeviceId": "0x5A19", "flashBlockSize": 131072, "flashSectorSize": 4096, "cmdBlockErase3B": "0xD8", "cmdBlockErase4B": "0xDC", "cmdSectorErase3B": "0x20", "cmdSectorErase4B": "0x21",・ "protos": { "p111": { "isDtr": false, "cmdRd": "0x03", "cmdWr": "0x02", "modeClksCmd": 0, "modeClksRd": 0, "dummyClksCmd": 0, "dummyClksRd": 0, "enableType": "0", "enableSeq": "0x00", "dummyCfg": null, "protoCfg": null, "strDtrCfg": null }, "p112": null, "p114": null, "p118": { "isDtr": false, "cmdRd": "0x7C", "cmdWr": "0x84", "modeClksCmd": 0, "modeClksRd": 1, "dummyClksCmd": 0, "dummyClksRd": 7, "enableType": "0", "enableSeq": "0x00", "dummyCfg": null, "protoCfg": null, "strDtrCfg": null }, "p444s": null, "p444d": null, "p888s": null, "p888d": { "isDtr": false, "cmdRd": "0x0B", "cmdWr": "0x12", I "modeClksCmd": 0, "modeClksRd": 0, "dummyClksCmd": 8, "dummyClksRd": 32, "enableType": "0", "enableSeq": "0x00", "dummyCfg": { "isAddrReg": false, "cmdRegRd":"0x00", "cmdRegWr":"0x00", "cfgReg":"0x00000000", "shift":0, "mask":"0x00", "bitP":31 }, "protoCf"isAddrReg": false, "cmdRegRd": "0x00", "cmdRegWr": "0x00", "cfgReg": "0x00000000", "shift": 0, "mask": "0x00", "bitP": 0 }, "strDtrCfg": { "isAddrReg": false, "cmdRegRd": "0x00", "cmdRegWr": "0x00", "cfoReg": "0x00000000", "shift": 0, "mask": "0x00", "bitP": 0 } }, "pCustom": { "fxn":`null } }< "addrByteSupport": "1", "fourByteAddrEnSeq": "0x22", "cmdExtType": "REPEAT", "resetType": "0x30", "deviceBusyType": "0", "cmdWrenb: "0x06", "cmdRdsr": "0x05", "srWip": 0, "srWel": 0, "cmdChipErase": "0xC7", "rdIdSettings": { "cmd": "0x9F", "numBytes": 5, "dummy4": 0, "dummy8": 0 }, "xspiWipRdCmd": "0x00", "xspiWipRmg": "0x00000000", "xspiWipBit": 0, "flashDeviceBusyTimeout": 72000000, "flashPageProgTimeout": 120 } All tests have passed!!
I think I will configure FLASH in sysconfig based on these, but which items correspond to where in sysconfig?
Best regards,
Kiyomasa Imaizumi.
Hello Prashant Shivhare.
I made the diag output result into a json file and read it from sysconfig.
The following error occurred.
However,I made the FLASH settings one by one and created uart_uniflash.
I ran sbl_uart_uniflash.py from the command prompt.
When debugging with symbol loading, Board_driversOpen() returns -1.
I think Flash_open is failing.
Best regards,
Kiyomasa Imaizumi.
Hello Prashant Shivhare.
I stopped just before Boad_driversOpen and debugged with symbol loading.
I confirmed that the status becomes -1 in Flash_norOspiReadId(config) in the Flash_norOspiOpen function.
Best regards,
Kiyomasa Imaizumi.
Hello Prashant Shivhare.
additional information. I am debugging with symbol loading.
The status will be -1 below.
(flash_nor_ospi.c)
if (!((manfID == config->attrs->manufacturerId) && (devID == config->attrs->deviceId))) { /* Try the other 3 bytes */ manfID = (uint32_t)idCode[3]; devID = ((uint32_t)idCode[4] << 8) | ((uint32_t)idCode[5]); if (!((manfID == config->attrs->manufacturerId) && (devID == config->attrs->deviceId))) { status = SystemP_FAILURE; } }
When I checked the parameters, manufacturingId was 52 and deviceId was 23322, but manfId was 0 and devID was 0.
As a result, the status is SystemP_FAILURE.
Maybe Flash_norOspiCmdRead is failing?
But the function is returning 0.
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
From the shared logs of `ospi_flash_diag`, the Manufacturer ID is 0x9D and Device ID is 0x5A19. Have you checked these against the corresponding IDs mentioned in your flash datasheet?
Regards,
Prashant
Hello Prashant Shivhare.
I made a mistake in the description.
The following is correct.
---
When I checked the parameters, manufacturingId was 0x9D and deviceId was 23065, but manfId was 0 and devID was 0.
---
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
My question is: Have you checked if the IDs reported by `ospi_flash_diag` matches with the IDs mentioned in your flash datasheet?
Also, can you share correct JSON output of the `ospi_flash_diag`. The previous JSON output is not formatted correctly.
Regards,
Prashant
Hello Preshant Shivhare
Thank you for youre reply.
I checked Manufacturer ID and Device ID from data sheet.
These are correct.
I attach JSON file.
Best regards,
Kiyomasa Imaizumi.
{ "flashSize": 33554432, "flashPageSize": 256, "flashManfId": "0x9D", "flashDeviceId": "0x5A19", "flashBlockSize": 131072, "flashSectorSize": 4096, "cmdBlockErase3B": "0xD8", "cmdBlockErase4B": "0xDC", "cmdSectorErase3B": "0x20", "cmdSectorErase4B": "0x21",�E "protos": { "p111": { "isDtr": false, "cmdRd": "0x03", "cmdWr": "0x02", "modeClksCmd": 0, "modeClksRd": 0, "dummyClksCmd": 0, "dummyClksRd": 0, "enableType": "0", "enableSeq": "0x00", "dummyCfg": null, "protoCfg": null, "strDtrCfg": null }, "p112": null, "p114": null, "p118": { "isDtr": false, "cmdRd": "0x7C", "cmdWr": "0x84", "modeClksCmd": 0, "modeClksRd": 1, "dummyClksCmd": 0, "dummyClksRd": 7, "enableType": "0", "enableSeq": "0x00", "dummyCfg": null, "protoCfg": null, "strDtrCfg": null }, "p444s": null, "p444d": null, "p888s": null, "p888d": { "isDtr": false, "cmdRd": "0x0B", "cmdWr": "0x12", I "modeClksCmd": 0, "modeClksRd": 0, "dummyClksCmd": 8, "dummyClksRd": 32, "enableType": "0", "enableSeq": "0x00", "dummyCfg": { "isAddrReg": false, "cmdRegRd":"0x00", "cmdRegWr":"0x00", "cfgReg":"0x00000000", "shift":0, "mask":"0x00", "bitP":31 }, "protoCf"isAddrReg": false, "cmdRegRd": "0x00", "cmdRegWr": "0x00", "cfgReg": "0x00000000", "shift": 0, "mask": "0x00", "bitP": 0 }, "strDtrCfg": { "isAddrReg": false, "cmdRegRd": "0x00", "cmdRegWr": "0x00", "cfoReg": "0x00000000", "shift": 0, "mask": "0x00", "bitP": 0 } }, "pCustom": { "fxn":`null } }< "addrByteSupport": "1", "fourByteAddrEnSeq": "0x22", "cmdExtType": "REPEAT", "resetType": "0x30", "deviceBusyType": "0", "cmdWrenb: "0x06", "cmdRdsr": "0x05", "srWip": 0, "srWel": 0, "cmdChipErase": "0xC7", "rdIdSettings": { "cmd": "0x9F", "numBytes": 5, "dummy4": 0, "dummy8": 0 }, "xspiWipRdCmd": "0x00", "xspiWipRmg": "0x00000000", "xspiWipBit": 0, "flashDeviceBusyTimeout": 72000000, "flashPageProgTimeout": 120 }
Hello Kiyomasa,
Thank you for confirming.
I just realized that the SDK seems to already have the IS25LX256 flash configuration file at source/board/.meta/flash/IS25LX256.json
~/ti/mcu_plus_sdk/am64x/09_01_00_41 ❯ /usr/bin/cat source/board/.meta/flash/IS25LX256.json { "flashSize": 33554432, "flashPageSize": 256, "flashManfId": "0x9D", "flashDeviceId": "0x5A19", "flashBlockSize": 131072, "flashSectorSize": 4096, "cmdBlockErase3B": "0xD8", "cmdBlockErase4B": "0xDC", "cmdSectorErase3B": "0x20", "cmdSectorErase4B": "0x21", "protos": { "p111": { "isDtr": false, "cmdRd": "0x03", "cmdWr": "0x02", "modeClksCmd": 0, "modeClksRd": 0, "dummyClksCmd": 0, "dummyClksRd": 0, "enableType": "0", "enableSeq": "0x00", "dummyCfg": null, "protoCfg": null, "strDtrCfg": null }, "p112": null, "p114": null, "p118": { "isDtr": false, "cmdRd": "0x7C", "cmdWr": "0x84", "modeClksCmd": 0, "modeClksRd": 0, "dummyClksCmd": 0, "dummyClksRd": 7, "enableType": "0", "enableSeq": "0x00", "dummyCfg": null, "protoCfg": null, "strDtrCfg": null }, "p444s": null, "p444d": null, "p888s": null, "p888d": { "isDtr": false, "cmdRd": "0x7C", "cmdWr": "0x84", "modeClksCmd": 0, "modeClksRd": 0, "dummyClksCmd": 16, "dummyClksRd": 16, "enableType": "0", "enableSeq": "0x00", "dummyCfg": { "isAddrReg": true, "cmdRegRd":"0x85", "cmdRegWr":"0x81", "cfgReg": "1", "shift":0, "mask":"0xFF", "bitP":16 }, "protoCfg": { "isAddrReg": true, "cmdRegRd": "0x85", "cmdRegWr": "0x81", "cfgReg": "0", "shift": 0, "mask": "0xff", "bitP": 231 }, "strDtrCfg": { "isAddrReg": true, "cmdRegRd": "0x85", "cmdRegWr": "0x81", "cfgReg": "0x00000000", "shift": 255, "mask": 255, "bitP": 0 } }, "pCustom": { "fxn": null } }, "addrByteSupport": "1", "fourByteAddrEnSeq": "0xA1", "cmdExtType": "REPEAT", "resetType": "0x30", "deviceBusyType": "0", "cmdWren": "0x06", "cmdRdsr": "0x05", "srWip": 0, "srWel": 1, "cmdChipErase": "0xC7", "rdIdSettings": { "cmd": "0x9F", "numBytes": 5, "dummy4": 0, "dummy8": 8, "addressBytesSize": 0 }, "xspiWipRdCmd": "0x00", "xspiWipReg": "0x00000000", "xspiWipBit": 0, "flashDeviceBusyTimeout": 72000000, "flashPageProgTimeout": 120
Can you please do the following:
- Revert all the changes in the Flash module of Sysconfig of `sbl_uart_uniflash`.
- Replace the contents of the EVM flash configuration file (source/board/.meta/flash/S28HS512T.json) with the contents of IS25LX256.json.
~/ti/mcu_plus_sdk/am64x/09_01_00_41/source/board/.meta/flash ❯ cp IS25LX256.json S28HS512T.json
- The settings in the Flash module of the Sysconfig will be automatically changed to whatever there is in S28HS512T.json. So, you won't require any manual changes.
- Rebuild the `sbl_uart_uniflash`.
- Perform the flashing procedure.
Let me know if this works.
Regards,
Prashant
Hello Prashant Shivhare.
Thank you for your reply.
I made the copy according to your instructions.
I rebuild the "sbl_uart_uniflash" and run.
It seems that the following retries are repeated.
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
Can you please share the `sbl_uart_uniflash` example you have modified till now?
Regards,
Prashant
Hello Prashant Shivhare.
Thank you for your reply.
I attach project file and S28HS512T.json file.
Best regards,
Kiyomasa Imaizumi.
Hello Prashant Shivhare.
When I tried it next, it seems to be looping as below.
When I step with F5, readStatus[0] becomes 0x05 or 0xFF.
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
Can you please do the following:
- Replace the contents of source/board/flash/ospi/flash_nor_ospi.c with the following
/* * Copyright (C) 2021-23 Texas Instruments Incorporated * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <board/flash.h> #include <board/flash/ospi/flash_nor_ospi.h> #define FLASH_OSPI_JEDEC_ID_SIZE_MAX (8U) static int32_t Flash_norOspiErase(Flash_Config *config, uint32_t blkNum); static int32_t Flash_norOspiEraseSector(Flash_Config *config, uint32_t sectNum); static int32_t Flash_norOspiRead(Flash_Config *config, uint32_t offset, uint8_t *buf, uint32_t len); static int32_t Flash_norOspiWrite(Flash_Config *config, uint32_t offset, uint8_t *buf, uint32_t len); static int32_t Flash_norOspiOpen(Flash_Config *config, Flash_Params *params); static void Flash_norOspiClose(Flash_Config *config); static int32_t Flash_norOspiReset(Flash_Config *config); #ifdef __cplusplus extern "C" { #endif int32_t Flash_quirkSpansionUNHYSADisable(Flash_Config *config); #ifdef __cplusplus } #endif uint32_t gFlashToSpiProtocolMap[] = { [FLASH_CFG_PROTO_1S_1S_1S] = OSPI_NOR_PROTOCOL(1,1,1,0), [FLASH_CFG_PROTO_1S_1S_2S] = OSPI_NOR_PROTOCOL(1,1,2,0), [FLASH_CFG_PROTO_1S_1S_4S] = OSPI_NOR_PROTOCOL(1,1,4,0), [FLASH_CFG_PROTO_1S_1S_8S] = OSPI_NOR_PROTOCOL(1,1,8,0), [FLASH_CFG_PROTO_4S_4S_4S] = OSPI_NOR_PROTOCOL(4,4,4,0), [FLASH_CFG_PROTO_4S_4D_4D] = OSPI_NOR_PROTOCOL(4,4,4,1), [FLASH_CFG_PROTO_8S_8S_8S] = OSPI_NOR_PROTOCOL(8,8,8,0), [FLASH_CFG_PROTO_8D_8D_8D] = OSPI_NOR_PROTOCOL(8,8,8,1), }; Flash_Fxns gFlashNorOspiFxns = { .openFxn = Flash_norOspiOpen, .closeFxn = Flash_norOspiClose, .readFxn = Flash_norOspiRead, .writeFxn = Flash_norOspiWrite, .eraseFxn = Flash_norOspiErase, .eraseSectorFxn = Flash_norOspiEraseSector, .resetFxn = Flash_norOspiReset, }; static int32_t Flash_norOspiCmdWrite(Flash_Config *config, uint8_t cmd, uint32_t cmdAddr, uint8_t numAddrBytes, uint8_t *txBuf, uint32_t txLen) { int32_t status = SystemP_SUCCESS; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); OSPI_WriteCmdParams wrParams; OSPI_WriteCmdParams_init(&wrParams); wrParams.cmd = cmd; wrParams.cmdAddr = cmdAddr; wrParams.numAddrBytes = numAddrBytes; wrParams.txDataBuf = txBuf; wrParams.txDataLen = txLen; status = OSPI_writeCmd(obj->ospiHandle, &wrParams); return status; } static int32_t Flash_norOspiCmdRead(Flash_Config *config, uint8_t cmd, uint32_t cmdAddr, uint8_t numAddrBytes, uint8_t dummyBits, uint8_t *rxBuf, uint32_t rxLen) { int32_t status = SystemP_SUCCESS; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); OSPI_ReadCmdParams rdParams; OSPI_ReadCmdParams_init(&rdParams); rdParams.cmd = cmd; rdParams.cmdAddr = cmdAddr; rdParams.numAddrBytes = numAddrBytes; rdParams.rxDataBuf = rxBuf; rdParams.rxDataLen = rxLen; rdParams.dummyBits = dummyBits; status = OSPI_readCmd(obj->ospiHandle, &rdParams); return status; } static int32_t Flash_norOspiWaitReady(Flash_Config *config, uint32_t timeOut) { int32_t status = SystemP_SUCCESS; Flash_DevConfig *devCfg = config->devConfig; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); uint8_t readStatus[2] = { 0 }; uint8_t numAddrBytes = OSPI_CMD_INVALID_OPCODE; uint32_t cmdAddr = OSPI_CMD_INVALID_ADDR; uint8_t cmd = devCfg->cmdRdsr; uint8_t bitMask = devCfg->srWip; uint8_t numBytesToRead = 1; uint8_t dummyBits = 0; /* Do RDSR based on xspi WIP status */ if((devCfg->xspiWipRdCmd != 0x00) && (obj->currentProtocol == FLASH_CFG_PROTO_8D_8D_8D)) { /* Check XSPI WIP configuration */ cmd = devCfg->xspiWipRdCmd; cmdAddr = devCfg->xspiWipReg; numAddrBytes = obj->numAddrBytes; bitMask = devCfg->xspiWipBit; numBytesToRead = 2; /* Can't read odd bytes in Octal DDR mode */ dummyBits = devCfg->protocolCfg.dummyClksCmd; } while((status != SystemP_SUCCESS) || (timeOut > 0)) { status = Flash_norOspiCmdRead(config, cmd, cmdAddr, numAddrBytes, dummyBits, readStatus, numBytesToRead); if((status == SystemP_SUCCESS) && ((readStatus[0] & bitMask) == 0)) { break; } timeOut--; } if((readStatus[0] & bitMask)==0) { status = SystemP_SUCCESS; } else { status = SystemP_FAILURE; } return status; } static int32_t Flash_norOspiRegRead(Flash_Config *config, uint8_t cmd, uint32_t addr, uint8_t *data) { int32_t status = SystemP_SUCCESS; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); uint8_t reg[2] = { 0 }; uint8_t numBytes = 1; uint8_t dummyBits = OSPI_CMD_INVALID_DUMMY; if(obj->currentProtocol == FLASH_CFG_PROTO_8D_8D_8D) { if(config->attrs->deviceId != 0x5A19) { numBytes = 2; /* Octal DDR can't read odd number of bytes */ } dummyBits = config->devConfig->protocolCfg.dummyClksCmd; } status = Flash_norOspiCmdRead(config, cmd, addr, obj->numAddrBytes, dummyBits, reg, numBytes); *data = reg[0]; return status; } static int32_t Flash_norOspiRegWrite(Flash_Config *config, uint8_t cmd, uint32_t addr, uint8_t data) { int32_t status = SystemP_SUCCESS; uint8_t regData = data; Flash_DevConfig *devCfg = config->devConfig; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); status = Flash_norOspiCmdWrite(config, devCfg->cmdWren, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); /* Wait a finite interval after WREN */ if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } if(status == SystemP_SUCCESS) { status = Flash_norOspiCmdWrite(config, cmd, addr, obj->numAddrBytes, ®Data, 1); } return status; } static int32_t Flash_norOspiSetRegCfg(Flash_Config *config, FlashCfg_RegConfig *rCfg) { int32_t status = SystemP_SUCCESS; /* Check if parameter is configured with addressed registers */ if((rCfg->cmdRegRd != 0) || (rCfg->cmdRegWr != 0)) { uint8_t cfgReg = 0; if(rCfg->isAddrReg == TRUE) { status += Flash_norOspiRegRead(config, rCfg->cmdRegRd, rCfg->cfgReg, &cfgReg); } else { status += Flash_norOspiRegRead(config, rCfg->cmdRegRd, OSPI_CMD_INVALID_ADDR, &cfgReg); } if(SystemP_SUCCESS == status) { /* Clear the config bits in the register */ cfgReg &= ~(uint8_t)(rCfg->mask); /* Bitwise OR the bit pattern for setting the dummyCycle selected */ cfgReg |= (rCfg->cfgRegBitP << rCfg->shift); /* There is register config, address might not be needed */ if(rCfg->isAddrReg == TRUE) { status += Flash_norOspiRegWrite(config, rCfg->cmdRegWr, rCfg->cfgReg, cfgReg); } else { status += Flash_norOspiRegWrite(config, rCfg->cmdRegWr, OSPI_CMD_INVALID_ADDR, cfgReg); } } } else { /* Nothing to be done */ } return status; } static int32_t Flash_norOspiSet4ByteAddrMode(Flash_Config *config) { int32_t status = SystemP_SUCCESS; Flash_DevConfig *devCfg = config->devConfig; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); if(((devCfg->fourByteAddrEnSeq & (uint8_t)(1 << 0)) != 0) && (config->skipHwInit == FALSE)) { /* Issue instruction 0xB7 without WREN */ status = Flash_norOspiCmdWrite(config, 0xB7, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); } if(((devCfg->fourByteAddrEnSeq & (uint8_t)(1 << 1)) != 0) && (config->skipHwInit == FALSE)) { /* Issue instruction 0xB7 with WREN */ status = Flash_norOspiCmdWrite(config, devCfg->cmdWren, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } status = Flash_norOspiCmdWrite(config, 0xB7, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } } if((devCfg->fourByteAddrEnSeq & (uint8_t)(1 << 2)) != 0) { /* Extended Register read with instr 0xC8, write with instr 0xC5 to set * the MSByte of addr. To be taken care during read and write. */ obj->extAddrRegSupport = TRUE; } if((devCfg->fourByteAddrEnSeq & (uint8_t)(1 << 3)) != 0) { /* Volatile bank register used to define 4 byte mode. To be taken care * during read and write */ obj->vBankAddrRegSupport = TRUE; } if((devCfg->fourByteAddrEnSeq & (uint8_t)(1 << 4)) != 0) { /* Dedicated 4 byte address instruction set, consider 4 bytes always ON */ obj->ded4bInstrSupport = TRUE; } return status; } static int32_t Flash_norOspiSetAddressBytes(Flash_Config *config, void *ospiHandle) { int32_t status = SystemP_SUCCESS; Flash_DevConfig *devCfg = config->devConfig; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); switch (devCfg->addrByteSupport) { case 0: /* Only 3 byte addressing supported, nothing to do with flash. Set OSPI driver */ OSPI_setNumAddrBytes(ospiHandle, 3); break; case 1: /* Both 3 and 4 byte addressing supported. Configure flash to switch to * 4 byte addressing if that's selected * */ if(devCfg->enable4BAddr == TRUE) { Flash_norOspiSet4ByteAddrMode(config); obj->numAddrBytes = 4; OSPI_setNumAddrBytes(ospiHandle, 4); } else { OSPI_setNumAddrBytes(ospiHandle, 3); } break; case 2: /* Only 4 byte addressing supported. Configure flash to switch to 4 byte * addressing * */ Flash_norOspiSet4ByteAddrMode(config); obj->numAddrBytes = 4; OSPI_setNumAddrBytes(ospiHandle, 4); break; default: OSPI_setNumAddrBytes(ospiHandle, 3); break; } return status; } static int32_t Flash_setQeBit(Flash_Config *config, uint8_t qeType) { int32_t status = SystemP_SUCCESS; Flash_DevConfig *devCfg = config->devConfig; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); uint8_t sr1 = 0, sr2 = 0, bitPos = 0; uint32_t bFlashRegWr = 0U; if(SystemP_SUCCESS == status) { switch (qeType) { case 0: /* No QE bit, detects 1-1-4 based on instruction */ break; case 1: case 4: case 5: /* QE is bit 1 of SR2 */ bitPos = (uint8_t)(1 << 1); status = Flash_norOspiCmdRead(config, devCfg->cmdRdsr, OSPI_CMD_INVALID_ADDR, obj->numAddrBytes, OSPI_CMD_INVALID_DUMMY, &sr1, 1); status += Flash_norOspiCmdRead(config, 0x35, OSPI_CMD_INVALID_ADDR, obj->numAddrBytes, OSPI_CMD_INVALID_DUMMY, &sr2, 1); if((sr2 & bitPos) != 0) { /* QE bit already set */ } else { uint16_t sr = 0; sr2 |= bitPos; sr = ((sr2 << 8) | sr1); status = Flash_norOspiCmdWrite(config, devCfg->cmdWren, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } status += Flash_norOspiCmdWrite(config, 0x01, OSPI_CMD_INVALID_ADDR, obj->numAddrBytes, (uint8_t *)&sr, 2); bFlashRegWr = 1U; } break; case 2: /* QE is bit 6 of SR1 */ sr1 = 0; bitPos = (uint8_t)(1 << 6); status = Flash_norOspiCmdRead(config, devCfg->cmdRdsr, OSPI_CMD_INVALID_ADDR, obj->numAddrBytes, OSPI_CMD_INVALID_DUMMY, &sr1, 1); if((sr1 & bitPos) != 0) { /* QE is already set */ } else { sr1 |= bitPos; status = Flash_norOspiCmdWrite(config, devCfg->cmdWren, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } status += Flash_norOspiCmdWrite(config, 0x01, OSPI_CMD_INVALID_ADDR, obj->numAddrBytes, &sr1, 1); bFlashRegWr = 1U; } break; case 3: /* QE is bit 7 of SR2 */ sr2 = 0; bitPos = (uint8_t)(1 << 7); status = Flash_norOspiCmdRead(config, 0x3F, OSPI_CMD_INVALID_ADDR, obj->numAddrBytes, OSPI_CMD_INVALID_DUMMY, &sr2, 1); if((sr2 & bitPos) != 0) { /* QE is already set */ } else { sr2 |= bitPos; status = Flash_norOspiCmdWrite(config, devCfg->cmdWren, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } status += Flash_norOspiCmdWrite(config, 0x3E, OSPI_CMD_INVALID_ADDR, obj->numAddrBytes, &sr2, 1); bFlashRegWr = 1U; } break; case 6: /* QE is bit 1 of SR2, using different command */ bitPos = (uint8_t)(1 << 1); status = Flash_norOspiCmdRead(config, 0x35, OSPI_CMD_INVALID_ADDR, obj->numAddrBytes, OSPI_CMD_INVALID_DUMMY, &sr2, 1); if((sr2 & bitPos) != 0) { /* QE bit already set */ } else { sr2 |= bitPos; status = Flash_norOspiCmdWrite(config, devCfg->cmdWren, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } status += Flash_norOspiCmdWrite(config, 0x31, OSPI_CMD_INVALID_ADDR, obj->numAddrBytes, &sr2, 1); bFlashRegWr = 1U; } break; default: break; } if((status == SystemP_SUCCESS) && (1U == bFlashRegWr)) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } } return status; } static int32_t Flash_setOeBit(Flash_Config *config, uint8_t oeType) { int32_t status = SystemP_SUCCESS; Flash_DevConfig *devCfg = config->devConfig; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); uint8_t sr2 = 0, bitPos = 0; /* oeType 0 means no config, and all other values other 1 are reserved for now */ switch (oeType) { case 0: /* No octal enable bit */ break; case 1: /* Octal enable is the bit 3 of SR2 */ bitPos = (uint8_t)(1 << 3); status = Flash_norOspiCmdRead(config, 0x65, OSPI_CMD_INVALID_ADDR, 2, 1, &sr2, 1); if((sr2 & bitPos) != 0) { /* QE is already set */ } else { sr2 |= bitPos; status = Flash_norOspiCmdWrite(config, devCfg->cmdWren, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } status += Flash_norOspiCmdWrite(config, 0x3E, OSPI_CMD_INVALID_ADDR, obj->numAddrBytes, &sr2, 1); } break; default: break; } return status; } static int32_t Flash_norOspiSetModeDummy(Flash_Config *config, void *ospiHandle) { int32_t status = SystemP_SUCCESS; Flash_DevConfig *devCfg = config->devConfig; FlashCfg_ProtoEnConfig *pCfg = &(devCfg->protocolCfg); if(pCfg->modeClksCmd != 0) { OSPI_enableModeBitsCmd(ospiHandle); } if(pCfg->modeClksRd != 0) { OSPI_setModeBits(ospiHandle, pCfg->modeClksRd); OSPI_enableModeBitsRead(ospiHandle); } OSPI_setReadDummyCycles(ospiHandle, pCfg->dummyClksRd); OSPI_setCmdDummyCycles(ospiHandle, pCfg->dummyClksCmd); /* Don't do the flash configuration if SBL has already taken care of it */ if(config->skipHwInit == FALSE) { if((pCfg->dummyClksCmd != 0) || (pCfg->dummyClksRd != 0)) { FlashCfg_RegConfig *dCfg = &(pCfg->dummyCfg); status = Flash_norOspiSetRegCfg(config, dCfg); if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } } } else { /* Nothing to be done, flash configuration is already done by previous SW entity */ } return status; } static int32_t Flash_norOspiSetDTR(Flash_Config *config, void *ospiHandle) { int32_t status = SystemP_SUCCESS; if((config == NULL) || (NULL == ospiHandle)) { status = SystemP_FAILURE; } else { Flash_DevConfig *devCfg = config->devConfig; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); FlashCfg_RegConfig *dtrCfg = &(devCfg->protocolCfg.strDtrCfg); /* Check if STR/DTR is configured with addressed registers */ status = Flash_norOspiSetRegCfg(config, dtrCfg); if(devCfg->protocolCfg.protocol == FLASH_CFG_PROTO_8D_8D_8D) { obj->currentProtocol = FLASH_CFG_PROTO_8D_8D_8D; } status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } return status; } static int32_t Flash_set444mode(Flash_Config *config, uint8_t seq) { int32_t status = SystemP_SUCCESS; Flash_DevConfig *devCfg = config->devConfig; FlashCfg_ProtoEnConfig *pCfg = &(devCfg->protocolCfg); Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); uint32_t seqFound = 0U; if((seq & (uint8_t)(1 << 0)) != 0) { /* Issue instruction 0x38 */ status = Flash_norOspiCmdWrite(config, 0x38, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); seqFound = 1U; } if((seq & (uint8_t)(1 << 1)) != 0) { /* Issue instruction 0x38 */ status = Flash_norOspiCmdWrite(config, 0x38, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); seqFound = 1U; } if((seq & (uint8_t)(1 << 2)) != 0) { /* Issue instruction 0x35 */ status = Flash_norOspiCmdWrite(config, 0x35, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); seqFound = 1U; } if((seq & (uint8_t)(1 << 3)) != 0) { /* Read modify write of reg, set bit 6 */ uint8_t reg = 0; Flash_norOspiRegRead(config, 0x65, 0x800003, ®); if((reg & (1 << 6)) != 0) { /* 444 mode already set */ } else { reg |= (1 << 6); Flash_norOspiRegWrite(config, 0x71, 0x800003, reg); } seqFound = 1U; } if((seq & (uint8_t)(1 << 4)) != 0) { /* Read modify write of reg, clear bit 7 */ uint8_t reg = 0; Flash_norOspiRegRead(config, 0x65, OSPI_CMD_INVALID_ADDR, ®); if((reg >> 7) == 0) { /* 444 mode already set */ } else { reg &= ~(1 << 7); Flash_norOspiRegWrite(config, 0x61, OSPI_CMD_INVALID_ADDR, reg); } seqFound = 1U; } if(seqFound) { OSPI_setProtocol((OSPI_Handle)(obj->ospiHandle), gFlashToSpiProtocolMap[pCfg->protocol]); obj->currentProtocol = pCfg->protocol; } status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); return status; } static int32_t Flash_set888mode(Flash_Config *config, uint8_t seq) { int32_t status = SystemP_SUCCESS; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); Flash_DevConfig *devCfg = config->devConfig; FlashCfg_ProtoEnConfig *pCfg = &(devCfg->protocolCfg); if((seq & (1 << 1)) != 0) { status = Flash_norOspiCmdWrite(config, 0xE8, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); OSPI_setProtocol((OSPI_Handle)(obj->ospiHandle), gFlashToSpiProtocolMap[pCfg->protocol]); obj->currentProtocol = pCfg->protocol; if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } } if((seq & (1 << 2)) != 0) { status = Flash_norOspiCmdWrite(config, devCfg->cmdWren, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } status = Flash_norOspiCmdWrite(config, 0x72, 0, 0, NULL, 0); OSPI_setProtocol((OSPI_Handle)(obj->ospiHandle), gFlashToSpiProtocolMap[pCfg->protocol]); obj->currentProtocol = pCfg->protocol; if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } } /* Check for register addressed 8-8-8 mode */ FlashCfg_RegConfig *octCfg = &(devCfg->protocolCfg.protoCfg); FlashCfg_RegConfig *dCfg = &(devCfg->protocolCfg.strDtrCfg); if(octCfg->isAddrReg && dCfg->isAddrReg && (dCfg->cfgReg == octCfg->cfgReg)) { /* Do both the configs together */ uint8_t reg = 0U; status = Flash_norOspiRegRead(config, octCfg->cmdRegRd, octCfg->cfgReg, ®); if(SystemP_SUCCESS == status) { /* Octal DDR is special. Check if it is already enabled */ if((((reg >> octCfg->shift) & 0x01) == 1) && (((reg >> dCfg->shift) & 0x01) == 1)) { /* Already 8D */ } else { /* Clear the config bits in the register */ reg &= ~(uint8_t)(octCfg->mask | dCfg->mask); /* Bitwise OR the bit pattern for setting the dummyCycle selected */ reg |= (octCfg->cfgRegBitP << octCfg->shift); if(pCfg->protocol == FLASH_CFG_PROTO_8D_8D_8D) { reg |= (dCfg->cfgRegBitP << dCfg->shift); } status += Flash_norOspiRegWrite(config, octCfg->cmdRegWr, octCfg->cfgReg, reg); } } OSPI_setProtocol((OSPI_Handle)(obj->ospiHandle), gFlashToSpiProtocolMap[pCfg->protocol]); } else { Flash_norOspiSetRegCfg(config, octCfg); Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); Flash_norOspiSetRegCfg(config, dCfg); if(pCfg->protocol == FLASH_CFG_PROTO_8D_8D_8D) { obj->currentProtocol = pCfg->protocol; } Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } if(status == SystemP_SUCCESS) { obj->currentProtocol = pCfg->protocol; } return status; } static int32_t Flash_norOspiSetProtocol(Flash_Config *config, void *ospiHandle, Flash_Params *params) { int32_t status = SystemP_SUCCESS; if((config == NULL) || (NULL == ospiHandle)) { status = SystemP_FAILURE; } else { Flash_DevConfig *devCfg = config->devConfig; /* Configure the flash according to protocol */ uint32_t protocol = devCfg->protocolCfg.protocol; FlashCfg_ProtoEnConfig *pCfg = &(devCfg->protocolCfg); if(FLASH_CFG_PROTO_CUSTOM == protocol) { status += params->custProtoFxn(config); } else { /* OOB support available for: * 1S_1S_1S * 1S_1S_2S * 1S_1S_4S * 1S_1S_8S * 4S_4S_4S * 4S_4D_4D * 8S_8S_8S * 8D_8D_8D */ switch (protocol) { case FLASH_CFG_PROTO_1S_1S_1S: /* No config needed for flash driver, set commands */ OSPI_setXferOpCodes(ospiHandle, pCfg->cmdRd, pCfg->cmdWr); break; case FLASH_CFG_PROTO_1S_1S_2S: /* No config needed for flash driver. Set commands, mode and dummy cycle if needed */ /* Check for mode Bits for 1-1-2 mode */ break; case FLASH_CFG_PROTO_1S_1S_4S: /* Set Quad Enable Bit. Set commands, mode and dummy cycle if needed */ /* Set QE bit */ if(config->skipHwInit == FALSE) { status += Flash_setQeBit(config, pCfg->enableType); } else { /* Nothing to be done, flash configuration is already done by previous SW entity */ } break; case FLASH_CFG_PROTO_1S_1S_8S: /* Set Octal Enable Bit. Set commands, mode and dummy cycle if needed */ /* Set OE bit */ if(config->skipHwInit == FALSE) { status += Flash_setOeBit(config, pCfg->enableType); } else { /* Nothing to be done, flash configuration is already done by previous SW entity */ } break; case FLASH_CFG_PROTO_4S_4S_4S: case FLASH_CFG_PROTO_4S_4D_4D: /* Set Quad Enable Bit. Set 444 mode. Set commands, mode and dummy cycle if needed. * In case of DTR, enable that too*/ /* Set QE bit */ if(config->skipHwInit == FALSE) { status += Flash_setQeBit(config, pCfg->enableType); /* Set 444 mode */ status += Flash_set444mode(config, pCfg->enableSeq); } else { /* Nothing to be done, flash configuration is already done by previous SW entity */ } break; case FLASH_CFG_PROTO_8S_8S_8S: case FLASH_CFG_PROTO_8D_8D_8D: /* Set Octal Enable Bit. Set 444 mode. Set commands, mode and dummy cycle if needed */ /* Set OE bit */ if(config->skipHwInit == FALSE) { status = Flash_setOeBit(config, pCfg->enableType); /* Set 888 mode */ status += Flash_set888mode(config, pCfg->enableSeq); } else { /* Nothing to be done, flash configuration is already done by previous SW entity */ } break; default: status = SystemP_FAILURE; break; } if(SystemP_SUCCESS == status) { OSPI_setProtocol((OSPI_Handle)ospiHandle, gFlashToSpiProtocolMap[protocol]); } } } return status; } static int32_t Flash_norOspiReadId(Flash_Config *config) { int32_t status = SystemP_SUCCESS; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); Flash_DevConfig *devCfg = config->devConfig; FlashCfg_ReadIDConfig *idCfg = &(devCfg->idCfg); uint8_t idCode[FLASH_OSPI_JEDEC_ID_SIZE_MAX] = {0}; uint32_t cmdAddr = OSPI_CMD_INVALID_ADDR; uint32_t dummyBits = 0; uint32_t idNumBytes = 3; uint32_t numAddrBytes = idCfg->addrSize; if(obj->currentProtocol == FLASH_CFG_PROTO_8D_8D_8D) { dummyBits = idCfg->dummy8; cmdAddr = 0U; idNumBytes = 4; /* Can't read odd bytes in octal DDR */ } else { /* default config */ } status = Flash_norOspiCmdRead(config, idCfg->cmd, cmdAddr, numAddrBytes, dummyBits, idCode, idNumBytes); /* Verify ID with filled data */ if (status == SystemP_SUCCESS) { uint32_t manfID, devID; manfID = (uint32_t)idCode[0]; devID = ((uint32_t)idCode[1] << 8) | ((uint32_t)idCode[2]); if (!((manfID == config->attrs->manufacturerId) && (devID == config->attrs->deviceId))) { /* Try the other 3 bytes */ manfID = (uint32_t)idCode[3]; devID = ((uint32_t)idCode[4] << 8) | ((uint32_t)idCode[5]); if (!((manfID == config->attrs->manufacturerId) && (devID == config->attrs->deviceId))) { status = SystemP_FAILURE; } } else { /* Success, nothing to do */; } } return status; } static int32_t Flash_norOspiRead(Flash_Config *config, uint32_t offset, uint8_t *buf, uint32_t len) { int32_t status = SystemP_SUCCESS; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); Flash_Attrs *attrs = config->attrs; if(obj->phyEnable) { OSPI_enablePhy(obj->ospiHandle); } /* Validate address input */ if ((offset + len) > (attrs->flashSize)) { status = SystemP_FAILURE; } if (status == SystemP_SUCCESS) { OSPI_Transaction transaction; OSPI_Transaction_init(&transaction); transaction.addrOffset = offset; transaction.buf = (void *)buf; transaction.count = len; status = OSPI_readDirect(obj->ospiHandle, &transaction); } if(obj->phyEnable) { OSPI_disablePhy(obj->ospiHandle); } return status; } static int32_t Flash_norOspiWrite(Flash_Config *config, uint32_t offset, uint8_t *buf, uint32_t len) { int32_t status = SystemP_SUCCESS; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); Flash_DevConfig *devCfg = config->devConfig; Flash_Attrs *attrs = config->attrs; /* Validate address input */ if((offset + len) > (attrs->flashSize)) { status = SystemP_FAILURE; } /* Check if the offset is aligned to page */ if(0 != (offset % attrs->pageSize)) { status = SystemP_FAILURE; } if(SystemP_SUCCESS == status) { uint32_t pageSize, chunkLen, actual; OSPI_Transaction transaction; pageSize = attrs->pageSize; chunkLen = pageSize; for (actual = 0; actual < len; actual += chunkLen) { status = Flash_norOspiCmdWrite(config, devCfg->cmdWren, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } if(status == SystemP_SUCCESS) { /* Send Page Program command */ if((len - actual) < (pageSize)) { chunkLen = (len - actual); } else { chunkLen = pageSize; } OSPI_Transaction_init(&transaction); transaction.addrOffset = offset; transaction.buf = (void *)(buf + actual); transaction.count = chunkLen; status = OSPI_writeIndirect(obj->ospiHandle, &transaction); } if(status == SystemP_SUCCESS) { status = Flash_norOspiWaitReady(config, devCfg->flashWriteTimeout); } if(status == SystemP_SUCCESS) { offset += chunkLen; } else { break; } } } return status; } static int32_t Flash_norOspiErase(Flash_Config *config, uint32_t blkNum) { int32_t status = SystemP_SUCCESS; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); Flash_Attrs *attrs = config->attrs; Flash_DevConfig *devCfg = config->devConfig; uint8_t cmd = OSPI_CMD_INVALID_OPCODE; uint32_t cmdAddr = OSPI_CMD_INVALID_ADDR; uint32_t eraseTimeout = devCfg->flashBusyTimeout; if(blkNum == (uint32_t)(-1)) { cmd = devCfg->eraseCfg.cmdChipErase; /* Chip erase times can be several minutes and can vary from flash to * flash. Give UINT_MAX so that we wait for as much time it takes to * erase the flash completely. */ eraseTimeout = (uint32_t)(-1); } else { cmdAddr = blkNum * attrs->blockSize; if(obj->numAddrBytes == 3) { cmd = devCfg->eraseCfg.cmdBlockErase3B; } else { cmd = devCfg->eraseCfg.cmdBlockErase4B; } if(blkNum >= attrs->blockCount) { status = SystemP_FAILURE; } } if(SystemP_SUCCESS == status) { status = Flash_norOspiCmdWrite(config, devCfg->cmdWren, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); } if(SystemP_SUCCESS == status) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } if(SystemP_SUCCESS == status) { status = Flash_norOspiCmdWrite(config, cmd, cmdAddr, obj->numAddrBytes, NULL, 0); } if(SystemP_SUCCESS == status) { status = Flash_norOspiWaitReady(config, eraseTimeout); } return status; } static int32_t Flash_norOspiEraseSector(Flash_Config *config, uint32_t sectorNum) { int32_t status = SystemP_SUCCESS; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); Flash_Attrs *attrs = config->attrs; Flash_DevConfig *devCfg = config->devConfig; uint8_t cmd = OSPI_CMD_INVALID_OPCODE; uint32_t cmdAddr = OSPI_CMD_INVALID_ADDR; uint32_t eraseTimeout = devCfg->flashBusyTimeout; if(sectorNum == (uint32_t)(-1)) { cmd = devCfg->eraseCfg.cmdChipErase; /* Chip erase times can be several minutes and can vary from flash to * flash. Give UINT_MAX so that we wait for as much time it takes to * erase the flash completely. */ eraseTimeout = (uint32_t)(-1); } else { cmdAddr = sectorNum * attrs->sectorSize; if(obj->numAddrBytes == 3) { cmd = devCfg->eraseCfg.cmdSectorErase3B; } else { cmd = devCfg->eraseCfg.cmdSectorErase4B; } if(sectorNum >= attrs->sectorCount) { status = SystemP_FAILURE; } } if(SystemP_SUCCESS == status) { status = Flash_norOspiCmdWrite(config, devCfg->cmdWren, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); } if(SystemP_SUCCESS == status) { status = Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); } if(SystemP_SUCCESS == status) { status = Flash_norOspiCmdWrite(config, cmd, cmdAddr, obj->numAddrBytes, NULL, 0); } if(SystemP_SUCCESS == status) { status = Flash_norOspiWaitReady(config, eraseTimeout); } return status; } static int32_t Flash_norOspiReset(Flash_Config *config) { int32_t status = SystemP_SUCCESS; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); Flash_DevConfig *devCfg = config->devConfig; if((devCfg->resetType & (uint8_t)(0x07)) != 0) { uint32_t clocks = 0; if((devCfg->resetType & (uint8_t)(0x01)) != 0) { clocks = 8; } if((devCfg->resetType & (uint8_t)(0x02)) != 0) { clocks = 10; } if((devCfg->resetType & (uint8_t)(0x04)) != 0) { clocks = 16; } if(clocks == 0) { status = SystemP_FAILURE; } else { if((clocks == 10) && (obj->numAddrBytes != 4)) { clocks = 8; } while(clocks--) { Flash_norOspiCmdWrite(config, 0x0F, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); } } } if((devCfg->resetType & (uint8_t)(0x08)) != 0) { /* Issue instruction 0xF0 */ status = Flash_norOspiCmdWrite(config, 0xF0, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); } if((devCfg->resetType & (uint8_t)(0x10)) != 0) { /* Issue reset enable, and then reset command */ status = Flash_norOspiCmdWrite(config, 0x66, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); if(SystemP_SUCCESS == status) { status = Flash_norOspiCmdWrite(config, 0x99, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); } } Flash_norOspiWaitReady(config, devCfg->flashBusyTimeout); return status; } int32_t Flash_norOspiSet8D_ISSI(Flash_Config *config) { Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); uint8_t regData = 0xFF; int32_t status = SystemP_FAILURE; status = Flash_norOspiCmdWrite(config, 0x06, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); if (status == SystemP_SUCCESS) { /* Write 0xE7 to enable octal DDR */ regData = 0xE7; status = Flash_norOspiCmdWrite(config, 0x81, 0x00, 3, ®Data, 1); } /* Enable octal DDR in controller */ OSPI_setProtocol((OSPI_Handle)(obj->ospiHandle), OSPI_NOR_PROTOCOL(8,8,8,1)); /* Read back the register to check if the value is written correctly */ uint8_t rxBuf[2] = { 0, 0}; status = Flash_norOspiCmdRead(config, 0x85, 0x00, 3, 8, rxBuf, 2); /* Enable 4 byte address */ status = Flash_norOspiCmdWrite(config, 0x06, OSPI_CMD_INVALID_ADDR, 0, NULL, 0); if (status == SystemP_SUCCESS) { regData = 0xFE; status = Flash_norOspiCmdWrite(config, 0x81, 0x05, 3, ®Data, 1); } return status; } static int32_t Flash_norOspiOpen(Flash_Config *config, Flash_Params *params) { int32_t status = SystemP_SUCCESS; Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); Flash_Attrs *attrs = config->attrs; int32_t attackVectorStatus = SystemP_FAILURE; obj->ospiHandle = OSPI_getHandle(attrs->driverInstance); if(obj->ospiHandle == NULL) { status = SystemP_FAILURE; } if(SystemP_SUCCESS == status) { OSPI_configResetPin(obj->ospiHandle, OSPI_RESETPIN_DEDICATED); /* Set device size and addressing bytes */ OSPI_setDeviceSize(obj->ospiHandle, attrs->pageSize, attrs->blockSize); /* Set command opcode extension type */ OSPI_setCmdExtType(obj->ospiHandle, config->devConfig->cmdExtType); /* Set initial number of address bytes */ if(config->devConfig->addrByteSupport == 2) { obj->numAddrBytes = 4; } else { obj->numAddrBytes = 3; } /* Set current protocol as 1s1s1s */ obj->currentProtocol = FLASH_CFG_PROTO_1S_1S_1S; /* Now configure the flash for the selected protocol */ if(config->attrs->deviceId != 0x5A19) { status += Flash_norOspiSetProtocol(config, obj->ospiHandle, params); obj->currentProtocol = config->devConfig->protocolCfg.protocol; } else { status += Flash_norOspiSet8D_ISSI(config); obj->currentProtocol = config->devConfig->protocolCfg.protocol; } /* Set number of address bytes. If 4 byte addressing is supported, switch to that */ status += Flash_norOspiSetAddressBytes(config, obj->ospiHandle); /* Set opcodes in OSPI controller */ OSPI_setXferOpCodes(obj->ospiHandle, config->devConfig->protocolCfg.cmdRd, config->devConfig->protocolCfg.cmdWr); /* Set Mode Clocks and Dummy Clocks in Controller and Flash Memory */ status += Flash_norOspiSetModeDummy(config, obj->ospiHandle); /* Set RD Capture Delay by reading ID */ uint32_t origBaudRateDiv = 0U; OSPI_getBaudRateDivFromObj(obj->ospiHandle, &origBaudRateDiv); uint32_t readDataCapDelay = origBaudRateDiv; OSPI_setRdDataCaptureDelay(obj->ospiHandle, readDataCapDelay); status = Flash_norOspiReadId(config); while((status != SystemP_SUCCESS) && (readDataCapDelay > 0U)) { readDataCapDelay--; OSPI_setRdDataCaptureDelay(obj->ospiHandle, readDataCapDelay); status = Flash_norOspiReadId(config); } /* Enable PHY if attack vector present and PHY mode is enabled */ obj->phyEnable = FALSE; uint32_t phyTuningOffset = Flash_getPhyTuningOffset(config); if(OSPI_isPhyEnable(obj->ospiHandle)) { #if defined (SOC_AM263PX) OSPI_configBaudrate(obj->ospiHandle, MAX_BAUDRATE_DIVIDER); #endif attackVectorStatus = OSPI_phyReadAttackVector(obj->ospiHandle, phyTuningOffset); #if defined (SOC_AM263PX) OSPI_configBaudrate(obj->ospiHandle, origBaudRateDiv); #endif if(attackVectorStatus != SystemP_SUCCESS) { /* Flash the attack vector to the last block */ uint32_t sect = 0, page = 0; uint32_t phyTuningData = 0,phyTuningDataSize = 0; OSPI_phyGetTuningData(&phyTuningData, &phyTuningDataSize); Flash_offsetToSectorPage(config, phyTuningOffset, §, &page); Flash_norOspiEraseSector(config, sect); Flash_norOspiWrite(config, phyTuningOffset, (uint8_t *)phyTuningData, phyTuningDataSize); attackVectorStatus = OSPI_phyReadAttackVector(obj->ospiHandle, phyTuningOffset); } if(attackVectorStatus == SystemP_SUCCESS) { status += OSPI_phyTuneDDR(obj->ospiHandle, phyTuningOffset); if(status == SystemP_SUCCESS) { obj->phyEnable = TRUE; OSPI_setPhyEnableSuccess(obj->ospiHandle, TRUE); } } else { DebugP_logError("%s : PHY enabling failed!!! Continuing without PHY...\r\n", __func__); obj->phyEnable = FALSE; OSPI_setPhyEnableSuccess(obj->ospiHandle, FALSE); status = SystemP_FAILURE; } } else { obj->phyEnable = FALSE; } } /* Any flash specific quirks, like hybrid sector config etc. */ if(params->quirksFxn != NULL) { params->quirksFxn(config); } else { /* Do nothing */ } return status; } static void Flash_norOspiClose(Flash_Config *config) { Flash_NorOspiObject *obj = (Flash_NorOspiObject *)(config->object); obj->ospiHandle = NULL; /* OSPI Driver will be closed outside flash */ return; } int32_t Flash_quirkSpansionUNHYSADisable(Flash_Config *config) { int32_t status = SystemP_SUCCESS; uint8_t regData = 0x00; uint32_t write = 0; /* Hybrid Sector Disable */ status = Flash_norOspiRegRead(config, 0x65, 0x00800004, ®Data); if(status == SystemP_SUCCESS) { if((regData & ((uint8_t)(1 << 3))) == 0) { /* Set UNHYSA bit */ regData |= (1 << 3); write = 1U; } else { /* No action */ } } if(write) { status = Flash_norOspiRegWrite(config, 0x71, 0x04, regData); } return status; }
- Rebuild the libs in the same PROFILE as the example is being built.
- Rebuild the `sbl_uart_uniflash` example.
- Perform the flashing procedure.
Regards,
Prashant
Hello Prashant Shivhare.
Thank you for your reply.
I changed flash_nor_ospi.c.
And I rebuild the libs and sbl_uart_uniflash.
The problem status is the same as before the change.
The program has the following loop.
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
There is this change in the flash_nor_ospi.c for your flash part. Can you stop before Board_driversOpen and see if the control is executing the else part and the function Flash_norOspiSet8D_ISSI
Regards,
Prashant
Hello Prashant Shivhare.
Thank you for your reply.
I tried debugging as you suggested.
Flash_norOspiSet8D_ISSI is called as follows.
The status is 0 after the function is called.
Best regards,
Kiyomasa Imaizumi.
Hello Prashant Shivhare.
Please let me know if there is any way to resolve this issue as soon as possible.
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
It looks like the driver is incompatible with your custom flash part. Before diving deep into the driver, I want to make sure the flash configurations we are working with are correct.
In that regards, I notice that the shared JSON output of ospi_flash_diag is different from the JSON file present in the SDK. May I know the exact steps you are following to run the ospi_flash_diag example?
Regards,
Prashant
Hello Kiyomasa,
I have one more updated flash configurations. Can you please try them?
- Remove all the changes in the source/board/flash/ospi/flash_nor_ospi.c previously shared.
- Replace the contents in source/board/.meta/flash/S28HS512T.json with the following:
{ "flashSize": 33554432, "flashPageSize": 256, "flashManfId": "0x9D", "flashDeviceId": "0x5A19", "flashBlockSize": 131072, "flashSectorSize": 4096, "cmdBlockErase3B": "0xD8", "cmdBlockErase4B": "0xDC", "cmdSectorErase3B": "0x20", "cmdSectorErase4B": "0x21", "protos": { "p111": { "isDtr": false, "cmdRd": "0x03", "cmdWr": "0x02", "modeClksCmd": 0, "modeClksRd": 0, "dummyClksCmd": 0, "dummyClksRd": 0, "enableType": "0", "enableSeq": "0x00", "dummyCfg": null, "protoCfg": null, "strDtrCfg": null }, "p112": null, "p114": null, "p118": { "isDtr": false, "cmdRd": "0x7C", "cmdWr": "0x84", "modeClksCmd": 0, "modeClksRd": 0, "dummyClksCmd": 0, "dummyClksRd": 7, "enableType": "0", "enableSeq": "0x00", "dummyCfg": null, "protoCfg": null, "strDtrCfg": null }, "p444s": null, "p444d": null, "p888s": null, "p888d": { "isDtr": false, "cmdRd": "0x7C", "cmdWr": "0x84", "modeClksCmd": 0, "modeClksRd": 0, "dummyClksCmd": 16, "dummyClksRd": 16, "enableType": "0", "enableSeq": "0x00", "dummyCfg": { "isAddrReg": true, "cmdRegRd":"0x85", "cmdRegWr":"0x81", "cfgReg": "1", "shift":0, "mask":"0xFF", "bitP":16 }, "protoCfg": { "isAddrReg": true, "cmdRegRd": "0x85", "cmdRegWr": "0x81", "cfgReg": "0", "shift": 0, "mask": "0xff", "bitP": 231 }, "strDtrCfg": { "isAddrReg": true, "cmdRegRd": "0x85", "cmdRegWr": "0x81", "cfgReg": "0x00000000", "shift": 255, "mask": 255, "bitP": 0 } }, "pCustom": { "fxn": null } }, "addrByteSupport": "1", "fourByteAddrEnSeq": "0", "cmdExtType": "REPEAT", "resetType": "0x30", "deviceBusyType": "0", "cmdWren": "0x06", "cmdRdsr": "0x05", "srWip": 0, "srWel": 1, "cmdChipErase": "0xC7", "rdIdSettings": { "cmd": "0x9F", "numBytes": 5, "dummy4": 0, "dummy8": 8, "addressBytesSize": 0 }, "xspiWipRdCmd": "0x05", "xspiWipReg": "0x00000000", "xspiWipBit": 0, "flashDeviceBusyTimeout": 72000000, "flashPageProgTimeout": 120 }
- Rebuild the libs.
- Rebuild the `sbl_uart_uniflash`.
- Perform the flashing procedure.
Regards,
Prashant
Hello Prashant Shivhare.
Thank you for your reply.
Here are the steps to run the ospi_flash_diag example.
1. Boot in UART BOOT MODE
2. Run uart_uniflash.py at command prompt.
3. The created sbl_uart_uniflash.Debug.hs_fs.tiimage program runs at EVM, but stops midway.
4. Connect Target CR5 with CCS
5. Reset CR5 from CCS
6. Load and run ospi_flash_diag from CCS
7. The diag result is output to Teraterm (Serial Port).
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
These are not the correct steps to run the ospi_flash_diag example.
For now, can you try the updated flash configurations I shared in my previous reply. If that doesn't work, we will come back to running the ospi_flash_diag the correct way.
Regards,
Prashant
Hello Prashant Shivhare.
Thank you for your quick reply.
I rebuilt and ran sbl_uart_uniflash with the S28HS512T.json file you showed.
Writing sbl_null was successful!
thank you very much.
C:\ti\mcu_plus_sdk_am64x_09_01_00_41\tools\boot>python uart_uniflash.py -p COM3 --cfg=sbl_prebuilt/am64x-evm/default_sbl_null.cfg Parsing config file ... Parsing config file ... SUCCESS. Found 2 command(s) !!! Executing command 1 of 2 ... Found flash writer ... sending ../../for_am6422/sbl_uart_uniflash.Debug.hs_fs.tiimage Sent flashwriter ../../for_am6422/sbl_uart_uniflash.Debug.hs_fs.tiimage of size 382373 bytes in 35.26s. Executing command 2 of 2 ... Command arguments : --file=../../for_am6422/sbl_null.Debug.hs_fs.tiimage --operation=flash --flash-offset=0x0 Sent ../../for_am6422/sbl_null.Debug.hs_fs.tiimage of size 341997 bytes in 101.47s. [STATUS] SUCCESS !!! All commands from config file are executed !!! C:\ti\mcu_plus_sdk_am64x_09_01_00_41\tools\boot>
Below are the questions.
1. What went wrong?
2. Currently, the program is using a file with a different flash name, S28HS512T.json.
The device name is IS25LX256, so please tell me the correct way to modify the project.
3. Please tell me the correct procedure to run ospi_flash_diag.
If the board does not have anything written in FLAHS, it can only be started in UART BOOT MODE.
Can ospi_flash_diag be executed in other ways?
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
That's some good news.
1. What went wrong?
Actually, I also don't have a clear understanding at the moment.
Fortunately, the AM263P-CC board is using the exact flash part IS25LX256. So, I evaluated the AM263P MCU+ SDK and noticed some manual changes in the Flash module of Sysconfig of `sbl_uart_uniflash` on top of the default flash configurations IS25LX256.json. So, I took chose changes and modified the flash configurations and shared with you. And IT DID WORK!!!
The device name is IS25LX256, so please tell me the correct way to modify the project.
The recommended way to modify the flash configurations is documented here:
Please note you would need to do these steps in any example using the FLASH module of Sysconfig like `sbl_ospi` or `ospi_flash_io` examples.
Can ospi_flash_diag be executed in other ways?
Yes, we can initialize the SoC by booting SBL NULL over UART directly and then load/run any example via CCS.
Regards,
Prashant
Hello Prashant Shivhare.
Thank you for your reply.
I'm a little confused.
I attach the latest data obtained with ospi_flash_diag.
Does this mean that this is wrong data (json)?
{ "flashSize": 33554432, "flashPageSize": 256, "flashManfId": "0x9D", "flashDeviceId": "0x5A19", "flashBlockSize": 131072, "flashSectorSize": 4096, "cmdBlockErase3B": "0xD8", "cmdBlockErase4B": "0xDC", "cmdSectorErase3B": "0x20", "cmdSectorErase4B": "0x21", "protos": { "p111": { "isDtr": false, "cmdRd": "0x03", "cmdWr": "0x02", "modeClksCmd": 0, "modeClksRd": 0, "dummyClksCmd": 0, "dummyClksRd": 0, "enableType": "0", "enableSeq": "0x00", "dummyCfg": null, "protoCfg": null, "strDtrCfg": null }, "p112": null, "p114": null, "p118": { "isDtr": false, "cmdRd": "0x7C", "cmdWr": "0x84", "modeClksCmd": 0, "modeClksRd": 1, "dummyClksCmd": 0, "dummyClksRd": 7, "enableType": "0", "enableSeq": "0x00", "dummyCfg": null, "protoCfg": null, "strDtrCfg": null }, "p444s": null, "p444d": null, "p888s": null, "p888d": { "isDtr": false, "cmdRd": "0x0B", "cmdWr": "0x12", "modeClksCmd": 0, "modeClksRd": 0, "dummyClksCmd": 8, "dummyClksRd": 32, "enableType": "0", "enableSeq": "0x00", "dummyCfg": { "isAddrReg": false, "cmdRegRd":"0x00", "cmdRegWr":"0x00", "cfgReg":"0x00000000", "shift":0, "mask":"0x00", "bitP":31 }, "protoCfg": { "isAddrReg": false, "cmdRegRd": "0x00", "cmdRegWr": "0x00", "cfgReg": "0x00000000", "shift": 0, "mask": "0x00", "bitP": 0 }, "strDtrCfg": { "isAddrReg": false, "cmdRegRd": "0x00", "cmdRegWr": "0x00", "cfgReg": "0x00000000", "shift": 0, "mask": "0x00", "bitP": 0 } }, "pCustom": { "fxn": null } }, "addrByteSupport": "1", "fourByteAddrEnSeq": "0x22", "cmdExtType": "REPEAT", "resetType": "0x30", "deviceBusyType": "0", "cmdWren": "0x06", "cmdRdsr": "0x05", "srWip": 0, "srWel": 0, "cmdChipErase": "0xC7", "rdIdSettings": { "cmd": "0x9F", "numBytes": 5, "dummy4": 0, "dummy8": 0 }, "xspiWipRdCmd": "0x00", "xspiWipReg": "0x00000000", "xspiWipBit": 0, "flashDeviceBusyTimeout": 72000000, "flashPageProgTimeout": 120 }
Moreover, if the flash configuration file you shared is correct,
does that mean that the json file in the SDK is also incorrect?
Best regards,
Kiyomasa Imaizumi.
Hello Kiyomasa,
I attach the latest data obtained with ospi_flash_diag.
It seems like the ospi_flash_diag somehow is not working correctly for IS25LX256 flash.
does that mean that the json file in the SDK is also incorrect?
So, we have the following difference in the default configurations and the working modified configurations:
~/ti/mcu_plus_sdk/am64x/09_01_00_41/source/board/.meta/flash ❯ diff IS25LX256.json working-modified-IS25LX256.json 90c90 < "fourByteAddrEnSeq": "0xA1", --- > "fourByteAddrEnSeq": "0", 106c106 < "xspiWipRdCmd": "0x00", --- > "xspiWipRdCmd": "0x05",
xspiWipRdCmd => The Read Status Register (xspiWipRdCmd) for IS25LX256 flash is 0x05 (mentioned in the datasheet) so the value 0x0 present in the default configuration is incorrect.
fourByteAddrEnSeq => The IS25LX256 flash only supports 4B addressing mode in Octal DDR (8D_8D_8D). So, the `fourByteAddrEnSeq` value must be set 0x0 to skip explicitly switching to 4B addressing since the flash will automatically be in 4B addressing mode for Octal DDR.
For any other supported protocol, switching to 4B will require explicit 4B enable sequence. In that case, `fourByteAddrEnSeq` value must be non-zero and set accordingly to the enable sequence.
Regards,
Prashant
Hello Prashant Shivhare.
For now, I think the problem is resolved.
Next time we face any problem, please help us again.
Best regards,
Kiyomasa Imaizumi.