W7500 mbed SDK Porting Guide
I2C Master Porting
예제 코드
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++)
{
}
}
수정할 필요 없는 코드
api 폴더, common 폴더, hal 폴더에 있는 내용을 수정하면 호환성 문제가 발생 할 수 있으므로 수정하지 않는 것을 권한다.
targets/hal/TARGET_WIZNET/TARGET_W7500x/i2c_api.c
- i2c 초기화 및 frequency 설정을 위한 함수
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
{
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);
if ((obj->i2c == I2C_0) && !i2c0_inited) {
i2c0_inited = 1;
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
if ((obj->i2c == I2C_1) && !i2c1_inited) {
i2c1_inited = 1;
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
i2c_reset(obj);
i2c_frequency(obj, 100000);
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);
I2C_ConfigStruct conf;
conf.mode = I2C_Master;
conf.master.timeout = LONG_TIMEOUT;
switch (hz) {
case 100000:
conf.master.prescale = 0x61;
break;
case 400000:
break;
case 1000000:
break;
default:
break;
}
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);
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;
}
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 (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);
}