Piyamate Wisanuvej / Mbed 2 deprecated NSE5310_programmer

Dependencies:   mbed

OTP.cpp

Committer:
piyamate
Date:
2014-05-13
Revision:
4:1f708415c442
Parent:
3:1d0c09e43e22

File content as of revision 4:1f708415c442:

#include "OTP.h"
#include <ctype.h>

OTP::OTP(PinName PDIO_pin, PinName CLK_pin, PinName CSn_pin, Serial &pc):
    PDIO( DigitalInOut(PDIO_pin, PIN_INPUT, PullNone, 0) ),
    CLK( DigitalInOut(CLK_pin, PIN_INPUT, PullNone, 0) ),
    CSn( DigitalOut(CSn_pin, 0) ),
    pc( pc )
{
    clear_registers();
}

void OTP::setup()
{
    PDIO = 1;
    PDIO.output();
    CLK = 0;
    CLK.output();
    CSn = 0;
    wait_ms(1);
    CSn = 1;
    wait_us(30);
    CSn = 0;
    wait_us(30);
    CLK = 1;
    wait_us(30);
    CLK = 0;
    wait_us(30);
}

void OTP::read_bits(uint32_t *dest, int bit_length)
{
    int idx = 0;
    
    do
    {
        CLK = 1;
        wait_us(30);
        *dest |= PDIO<<idx;
        CLK = 0;
        wait_us(30);
        idx++;
    }while(idx < bit_length);
}

void OTP::exit()
{
    CLK = 0;
    CSn = 0;
    PDIO = 1;
    PDIO.output();
    wait_us(30);
    CLK = 1;
    wait_us(30);
    CLK = 0;
    wait_us(30);
    CLK = 1;
    wait_us(30);
    CSn = 1;
    wait_us(30);
    CLK.input();
}

void OTP::read()
{
    PDIO = 0;
    wait_us(30);
    CLK = 1;
    wait_us(30);
    CSn = 1;
    wait_us(30);
    CLK = 0;
    wait_us(30);
    
    //generate two CLK pulses
    for(int i=0; i<2; i++)
    {
        CLK = 1;
        wait_us(30);
        CLK = 0;
        wait_us(15);
        
        //switch PDIO to input on first faling edge of CLK
        if(i==0)
            PDIO.input();
        wait_us(15);
    }
    
    //read all parameters
    read_bits(&PWMhalfEN_IndexWidth, 1);
    read_bits(&MagCompEN, 1);
    read_bits(&pwmDIS, 1);
    read_bits(&output_md0, 1);
    read_bits(&output_md1, 1);
    read_bits(&Z, 12);
    read_bits(&CCW, 1);
    read_bits(&I2C_A, 5);
    read_bits(&factory_section, 29);
    
    //mbit0,mbit1
    {
        wait_ms(1);
        for(int i=0; i<3; i++)
        {
            CLK = 1;
            wait_us(30);
            CLK = 0;
            wait_us(30);
        }
    }
    
    CSn = 0;
    wait_us(30);
    
    pc.printf("PWMhalfEN_IndexWidth: %X\n", PWMhalfEN_IndexWidth);
    pc.printf("MagCompEN: %X\n", MagCompEN);
    pc.printf("pwmDIS: %X\n", pwmDIS);
    pc.printf("output_md0: %X\n", output_md0);
    pc.printf("output_md1: %X\n", output_md1);
    pc.printf("Z: 0x%03X\n", Z);
    pc.printf("CCW: %X\n", CCW);
    pc.printf("I2C_A: 0x%02X (0x%02X)\n", I2C_A, (I2C_A<<2)+0x80);
    pc.printf("factory_section: 0x%08X\n", factory_section);
}

uint8_t OTP::ID_to_I2C_A(uint8_t id)
{
    return (id&0x7C) >> 2;
}

void OTP::write()
{
    PDIO = 1;
    CLK = 0;
    wait_us(30);
    CSn = 1;
    wait_us(30);
    
    //generate four CLK pulses
    for(int i=0; i<4; i++)
    {
        CLK = 1;
        wait_us(30);
        CLK = 0;
        wait_us(30);
    }
    
    //start writing data (from bit 51)
    PDIO = 0;
    wait_us(30);
    for(int i=0; i<18; i++)
    {
        CLK = 1;
        wait_us(30);
        CLK = 0;
        wait_us(30);
    }
    //I2C_A
    wait_us(15);
    for(int i=0; i<5; i++)
    {
        PDIO = ( I2C_A>>i )&1;
        wait_us(15);
        CLK = 1;
        wait_us(30);
        CLK = 0;
        wait_us(15);
    }
    
    //factory_section
    {
        factory_section = 0;
        for(int i=0; i<29; i++)
        {
            PDIO = ( factory_section>>(29-i-1) )&1;
            wait_us(15);
            CLK = 1;
            wait_us(30);
            CLK = 0;
            wait_us(15);
        }
    }
    
    //mbit0,latch
    {
        for(int i=0; i<2; i++)
        {
            CLK = 1;
            wait_us(30);
            CLK = 0;
            wait_us(30);
        }
    }
    
    CSn = 0;
    wait_us(30);
}

void OTP::prog()
{
    char input;
    pc.printf("Install capacitor on PDIO (y/n): ");
    pc.scanf("%c", &input);
    
    if(tolower(input) == 'y')
    {
        pc.printf("\nFusing...\n");
        PDIO = 1;
        CLK = 1;
        wait_us(30);
        CSn = 1;
        wait_us(30);
        CLK = 0;
        wait_us(30);
        
        //generate three CLK pulses
        for(int i=0; i<3; i++)
        {
            CLK = 1;
            wait_us(30);
            CLK = 0;
            wait_us(30);
        }
        
        //mbit0
        CLK = 1;
        wait_us(T_PROG_BURN);
        CLK = 0;
        wait_us(T_PROG_REFRESH);
        
        //factory_section
        for(int i=0; i<29; i++)
        {
            CLK = 1;
            wait_us(T_PROG_BURN);
            CLK = 0;
            wait_us(T_PROG_REFRESH);
        }
        
        //I2C_A
        for(int i=0; i<5; i++)
        {
            CLK = 1;
            wait_us(T_PROG_BURN);
            CLK = 0;
            wait_us(T_PROG_REFRESH);
        }
        
        //burn other bits
        for(int i=0; i<19; i++)
        {
            CLK = 1;
            wait_us(T_PROG_BURN);
            CLK = 0;
            wait_us(T_PROG_REFRESH);
        }
    }
    else
    {
        pc.printf("\nCancelled.\n");
    }

    wait_us(30);
    CSn = 0;
    wait_us(30);
}

void OTP::set_id(uint8_t id)
{
    I2C_A = ID_to_I2C_A(id);
}

void OTP::clear_registers()
{
    factory_section = 0;
    I2C_A = 0;
    CCW = 0;
    Z = 0;
    output_md1 = 0;
    output_md0 = 0;
    pwmDIS = 0;
    MagCompEN = 0;
    PWMhalfEN_IndexWidth = 0;
}