W7500 mbed SDK Porting Guide (5/6)

2015. 10. 8. 15:032018년 이전 관심사/mbed

반응형

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);
}


반응형

'2018년 이전 관심사 > 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 (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