Piyamate Wisanuvej / Mbed 2 deprecated NSE5310_programmer

Dependencies:   mbed

main.cpp

Committer:
piyamate
Date:
2014-05-12
Revision:
1:1e577b8befeb
Parent:
0:d488d550469e
Child:
2:af09cade52df

File content as of revision 1:1e577b8befeb:

#include "mbed.h"

DigitalInOut PDIO(p30);
DigitalInOut CLK(p29);
DigitalOut CSn(p21);
Serial pc(USBTX, USBRX);

int read_temperature(I2C i2c, int addr, float *temperature)
{
    char data[5];
    int status = i2c.read(addr, data, 5);
    *temperature = data[4]*0.667-75;
    return status;
}

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 = bit_length-1;
    
    do
    {
        CLK = 1;
        wait_us(30);
        *dest |= (PDIO<<idx);
        CLK = 0;
        wait_us(30);
        idx--;
    }while(idx>=0);
}

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(uint32_t *factory_section)
{
    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);
    }
    
    uint32_t I2C_A = 0; //I2C address <5:1>
    uint32_t CCW = 0; //change increasing/decreasing code with encoder movement
    uint32_t Z = 0; //zero position
    uint32_t output_md1 = 0, output_md0 = 0;
    uint32_t pwmDIS = 0;
    uint32_t MagCompEN = 0;
    uint32_t PWMhalfEN_IndexWidth = 0;
    
    //read all parameters
    OTP_read_bits(&PWMhalfEN_IndexWidth, 1);
    OTP_read_bits(&MagCompEN, 1);
    OTP_read_bits(&pwmDIS, 1);
    OTP_read_bits(&output_md0, 1);
    OTP_read_bits(&output_md1, 1);
    OTP_read_bits(&Z, 12);
    OTP_read_bits(&CCW, 1);
    OTP_read_bits(&I2C_A, 5);
    OTP_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);
        }
    }
    
    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 ID_to_I2C_A(uint8_t id)
{
    return (id&0x7C) >> 2;
}

void OTP_write(uint8_t id, uint32_t factory_section)
{
    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
    uint8_t id_register = ID_to_I2C_A(id);
    wait_us(15);
    for(int i=0; i<5; i++)
    {
        PDIO = ( id_register>>i )&1;
        wait_us(15);
        CLK = 1;
        wait_us(30);
        CLK = 0;
        wait_us(15);
    }
    
    //factory_section
    {
        PDIO = 0;
        wait_us(30);
        for(int i=0; i<29; i++)
        {
            PDIO = ( factory_section>>(29-i-1) )&1;
            CLK = 1;
            wait_us(30);
            CLK = 0;
            wait_us(30);
        }
    }
    
    //mbit0,latch
    {
        for(int i=0; i<2; i++)
        {
            CLK = 1;
            wait_us(30);
            CLK = 0;
            wait_us(30);
        }
    }
}

int scan_NSE5310()
{
    CSn = 0;
    I2C i2c(p28, p27);
    int device_count = 0;
    for(int addr=0x80; addr<0xFE; addr+=2)
    {
        float temperature;
        //pc.printf("addr:0x%02X\n", addr);
        if(read_temperature(i2c, addr, &temperature)==0)
        {
            pc.printf("Found device: 0x%02X, Temperature: %2.1fC\n", addr, temperature);
            device_count++;
        }
    }
    return device_count;
}

int main() {
    CLK.input();
    PDIO.input();
    pc.baud(115200);
    pc.printf("Scanning for NSE5310 devices...\n");
    int device_count = scan_NSE5310();
    //pc.printf("device_count=%d\n", device_count);
    if(device_count==0)
        pc.printf("No device found. Completed.\n");
    else if(device_count>1)
        pc.printf("Found more than one device. Completed.\n");
    else if(device_count==1)
    {
        //device parameters
        uint8_t id = 0;
        uint32_t factory_section = 0;
        
        pc.printf("Entering programming mode...\n");
        
        OTP_setup();
        pc.printf("OTP_read()\n");
        OTP_read(&factory_section);
        OTP_exit();
        pc.printf("\n");
        
        int valid = 0;
        do
        {
            pc.printf("\nInput new device ID in hex (0x80 to 0xFE): 0x");
            //pc.scanf("%x", &id);
            id = 0xC0;
            id &= 0xFC;
            if(id>=0x80 && id<=0xFE)
                valid = 1;
        }while(valid==0);
        pc.printf("\n");
        
        OTP_setup();
        pc.printf("OTP_write(0x%02X)\n", id);
        OTP_write(id, factory_section);
        OTP_exit();
        pc.printf("\n");
        
        OTP_setup();
        pc.printf("OTP_read()\n");
        OTP_read(&factory_section);
        OTP_exit();
        pc.printf("\n");
    }
}