ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • W7500 mbed SDK Porting Guide (5/6)
    IT 개발/mbed 2015.10.08 15:03

    W7500 mbed SDK Porting Guide

    I2C Master Porting

    예제 코드

    선택 영역_027.png

    int main() {
        int address = 0xA0;
        char tx_data[27] = {0x00, 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,
                            0x08, 0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,
                            0x10, 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18};
        char rx_data[22]={0};
    
        I2C i2c(I2C_SDA, I2C_SCL);
    
        i2c.start();
        i2c.write(address,tx_data,9);
    
        wait(1);
    
        i2c.start();
        i2c.write(address,0x00,1,true);
    
        i2c.read(address,rx_data,27);
    
        for(int i=0;i<22;i++)
        {
            //pc.printf("Data[%d]: %x\r\n",i, rx_data[i]);
        }
    }
    

    수정할 필요 없는 코드

    api 폴더, common 폴더, hal 폴더에 있는 내용을 수정하면 호환성 문제가 발생 할 수 있으므로 수정하지 않는 것을 권한다.

    • api/I2C.h
    • common/I2C.cpp

    targets/hal/TARGET_WIZNET/TARGET_W7500x/i2c_api.c

    • i2c 초기화 및 frequency 설정을 위한 함수
    void i2c_init(i2c_t *obj, PinName sda, PinName scl)
    {
        // Determine the I2C to use
        I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
        I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
    
        obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
        MBED_ASSERT(obj->i2c != (I2CName)NC);
    
        // Enable I2C1 clock and pinout if not done
        if ((obj->i2c == I2C_0) && !i2c0_inited) {
            i2c0_inited = 1;
            // Configure I2C pins
            pinmap_pinout(sda, PinMap_I2C_SDA);
            pinmap_pinout(scl, PinMap_I2C_SCL);
            pin_mode(sda, OpenDrain);
            pin_mode(scl, OpenDrain);
        }
    
        // Enable I2C2 clock and pinout if not done
        if ((obj->i2c == I2C_1) && !i2c1_inited) {
            i2c1_inited = 1;
            // Configure I2C pins
            pinmap_pinout(sda, PinMap_I2C_SDA);
            pinmap_pinout(scl, PinMap_I2C_SCL);
            pin_mode(sda, OpenDrain);
            pin_mode(scl, OpenDrain);
        }
    
        // Reset to clear pending flags if any
        i2c_reset(obj);
    
        // I2C configuration
        i2c_frequency(obj, 100000); // 100 kHz per default
        obj->is_setAddress = 0;
    }
    
    void i2c_frequency(i2c_t *obj, int hz)
    {
        MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
        I2cHandle = (I2C_TypeDef *)(obj->i2c);
    
        // wait before init
        I2C_ConfigStruct conf;
    
        conf.mode = I2C_Master;
        conf.master.timeout = LONG_TIMEOUT;
    
        // Common settings: I2C clock = 48 MHz, Analog filter = ON, Digital filter coefficient = 0
        switch (hz) {
            case 100000:
                conf.master.prescale  = 0x61;      // Standard mode with Rise Time = 400ns and Fall Time = 100ns
                break;
            case 400000:
                break;
            case 1000000:
                break;
            default:
                break;
        }
    
        // I2C configuration
        I2C_Init(I2cHandle, conf);
    }
    
    특이사항
    • W7500 I2C 구조적인 차이로 i2c_start 시, i2c start signal을 내보내지 않음.
      • W7500은 I2C start signal을 설정하기 전에 Slave Address를 미리 저장하고 있어야 함.
    • 위 문제를 해결하기 위해, read/write 함수에서 Slave Address의 유/무를 확인하여 I2C Start Signal을 송신 함.
    inline int i2c_start(i2c_t *obj)
    {
        obj->is_setAddress = 0;
    
        return 0;
    }
    
    inline int i2c_stop(i2c_t *obj)
    {
        I2cHandle = (I2C_TypeDef *)(obj->i2c);
    
        // Generate the STOP condition
        I2C_Stop(I2cHandle);
        I2C_Reset(I2cHandle);
        obj->is_setAddress = 0;
    
        return 0;
    }
    
    int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
    {
        I2cHandle = (I2C_TypeDef *)(obj->i2c);
        int count;
        int value;
    
        if(!obj->is_setAddress)
        {
           if( I2C_Start(I2cHandle, address, I2C_READ_SA7) == ERROR )
            {
                return -1;
            }
           obj->is_setAddress = 1;
           obj->ADDRESS = address;
        }
        else
        {
            I2C_Restart_Structure(I2cHandle, address, I2C_READ_SA7);
            obj->ADDRESS = address;
        }
    
        // Read all bytes
        for (count = 0; count < (length-1); count++) {
            if( (value = i2c_byte_read(obj, 0)) == -1) return value;
            data[count] = (char)value;
        }
    
        if(stop){
            if( (value = i2c_byte_read(obj, 1)) == -1) return value;
            data[count] = (char)value;
        }
        else{
            if( (value = i2c_byte_read(obj, 0)) == -1) return value;
            data[count] = (char)value;
        }
    
        return count;
    }
    
    int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
    {
        I2cHandle = (I2C_TypeDef *)(obj->i2c);
        int count;
    
        if(!obj->is_setAddress)
        {
           if( I2C_Start(I2cHandle, address, I2C_WRITE_SA7) == ERROR )
            {
                return -1;
            }
           obj->is_setAddress = 1;
           obj->ADDRESS = address;
        }
        else
        {
            I2C_Restart_Structure(I2cHandle, address, I2C_WRITE_SA7);
            obj->ADDRESS = address;
        }
    
        for (count = 0; count < length; count++) {
            i2c_byte_write(obj, data[count]);
        }
    
        // If not repeated start, send stop
        if (stop) {
            i2c_stop(obj);
        }
    
        return count;
    }
    
    int i2c_byte_read(i2c_t *obj, int last)
    {
        I2cHandle = (I2C_TypeDef *)(obj->i2c);
    
        return I2C_ReceiveData(I2cHandle, last);
    }
    
    int i2c_byte_write(i2c_t *obj, int data)
    {
        I2cHandle = (I2C_TypeDef *)(obj->i2c);
        return I2C_SendDataAck(I2cHandle,(uint8_t)data);
    }
    
    void i2c_reset(i2c_t *obj)
    {
        I2cHandle = (I2C_TypeDef *)(obj->i2c);
    
        I2C_Reset(I2cHandle);
    }
    


    'IT 개발 > mbed' 카테고리의 다른 글

    WIZwiki_W7500 CMSIS-DAP Porting  (0) 2015.10.08
    W7500 mbed SDK Porting Guide (6/6)  (0) 2015.10.08
    W7500 mbed SDK Porting Guide (5/6)  (0) 2015.10.08
    W7500 mbed SDK Porting Guide (4/6)  (0) 2015.10.08
    W7500 mbed porting Guide ( 3/6 )  (0) 2015.10.08
    W7500 mbed porting Guide ( 2/6 )  (0) 2015.10.08

    댓글 0

Designed by Tistory.