Read back i.MX28 fuses using DevSupport.DeviceManager.HidDevice

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Read back i.MX28 fuses using DevSupport.DeviceManager.HidDevice

849件の閲覧回数
stephenhewitson
Contributor III

Hi,

I am using the DevSupport.dll (as supplied with BitInit) to burn the fuses inside an i.MX28.

To do this I do the following:

DevSupport.DeviceManager.HidDevice CurrentDevice = (DevSupport.DeviceManager.HidDevice)DeviceManager.Instance.FindDevice(typeof(DevSupport.DeviceManager.HidDeviceClass), new ushort?((ushort)5538), new ushort?());

if (0 == CurrentDevice.InitializeOtpRegs(otpInitLocation))

{

    //Successful

}

How do I read values back from specific registers similar to BitBurner?

Thanks,

Stephen

ラベル(1)
0 件の賞賛
2 返答(返信)

581件の閲覧回数
alejandrolozan1
NXP Employee
NXP Employee

Hi,

I have never used that dll, but I have done is to use the obds and the fuse driver.

Ther you can find API that can be executed in the imx28 to  write and read back the fuse state.

For example:

nt fuse_read(int addr)

{

    int temp;

    /* Check that HW_OCOTP_CTRL_BUSY and HW_OCOTP_CTRL_ERROR are clear */

    temp = *(u32 *) (HW_OCOTP_CTRL);

    temp &= 0x00000300;

    if (temp != 0) {

        printf("OTP is busy or there is an error, register value is: 0x%x\n", temp);

        return -1;

    }

    if (((addr >= 0x8) && (addr <= 0x0F)) || ((addr >= 0x18) && (addr <= 0x1F))) {  /* Address falls within range of shadow registers */

        /* Force re-load of shadow registers */

        *(u32 *) (HW_OCOTP_CTRL_SET) = 0x00000200;

        /* wait until busy and re-load are cleared */

        while (1) {

            temp = *(u32 *) (HW_OCOTP_CTRL);

            temp &= 0x00000120;

            if (temp == 0x00000000) {

                break;

            }

        }

        /* return the value of the register being read */

        return *(u32 *) ((addr << 0x4) + HW_OCOTP_CUST0);

    } else if (addr > 0x1F) {   /* Check to see if the address is a valid one */

        printf("invalid address! \n");

        return -1;

    } else {                    /* Otherwise, the address is a non shadow register and needs a special operation */

        /* Force open all of the fuse banks */

        *(u32 *) (HW_OCOTP_CTRL_SET) = 0x00001000;

        /* After issuing the open-all-banks, poll for BUSY  */

        while (1) {

            temp = *(u32 *) (HW_OCOTP_CTRL);

            temp &= 0x00000100;

            if (temp == 0x00000000) {

                break;

            }

        }

        /* store read value into temp variable */

        temp = *(u32 *) ((addr << 0x4) + HW_OCOTP_CUST0);

        /* now close the fuse bank to save power */

        *(u32 *) (HW_OCOTP_CTRL_CLR) = 0x00001000;

        /* return the value of the register being read */

        return temp;

    }

}

Are you developing a GUI similar to bitburner?

Best Regards,

Alejandro

0 件の賞賛

581件の閲覧回数
stephenhewitson
Contributor III

Alejandro,


Thanks for that information.

I am trying to create some test bed software that, among other things, sets the HW_OCOTP_CUST0 register programmatically.


I have managed to read and write to the register using:

DevSupport.Api.HidApi.PitcRead pitcRead = new DevSupport.Api.HidApi.PitcRead(0, 1, 0, 16);

iResult = CurrentDevice.SendCommand(pitcRead);

DevSupport.Api.HidApi.PitcWrite pw = new DevSupport.Api.HidApi.PitcWrite(0, 1, 0, new byte[] {0,0,0,0});

iResult = CurrentDevice.SendCommand(PitcWrite );

But this only works if BitBurner is ran first, and OtpAccessPitc.MX28.sb is loaded into the processor.

0 件の賞賛