본문 바로가기

[TI]/MSPM0G

[MSPM0G3107 SSM-20] MSPM0G3107 I2C 테스트 문제 발생 - LTR559 거리감지 센서 테스트

 

MSPM0를 이용하여 테스트 했던 I2C 테스트 예제를 이용해서 거리 감지 센서 LTR559 모듈을 테스트 해보자.

[MSPM0G1307 SSM-20] 보드의 I2C는 PA17(SCL), PA18(SDA)에 할당되어 있다.

 

SysConfig로 I2C를 추가 하고 기본 세팅에 클럭속도를 설정한다.

 

 

PinMux 설정을 PA17, PA18에 할당하고 저장하면 I2C기본 코드가 자동으로 생성된다.

 

기존에 테스트 했던 MSPM0G3507 I2C 예제 코드를 이용해서 테스트 해 보면 I2C 출력은 정상적으로 되는데... Read가 이상하게 동작한다. 센서가 문제 인가?

그사이 SDK가 변경되었나?

 

우선 STM32G로 LTR559센서가 잘 동작하는지 확인하면 잘 구동된다.

#define I2C_HANLDLE hi2c2
#define _I2C_ADDRESS                 (_LTR559_I2C_ADDR<<1)
#define _I2C_HOW_AM_I				 _LTR559_REG_MID
#define _LTR559_I2C_ADDR             0x23
#define _LTR559_REG_MID              0x87

#define I2C_TIMEOUT_COUNT 1000
void i2c_write8(unsigned char addr, unsigned char data)
{
    HAL_I2C_Master_Transmit(&I2C_HANLDLE, addr, &data, 1, I2C_TIMEOUT_COUNT);
}

void i2c_write_reg(unsigned char addr, unsigned char reg, unsigned char data)
{
    unsigned char buf[2];

    buf[0] = reg;
    buf[1] = data;

    HAL_I2C_Master_Transmit(&I2C_HANLDLE, addr, buf, 2, I2C_TIMEOUT_COUNT);
}

unsigned char i2c_read_reg(unsigned char addr, unsigned char data)
{
    unsigned char rx[1];

    HAL_I2C_Master_Transmit(&I2C_HANLDLE, addr, &data, 1, I2C_TIMEOUT_COUNT);
    HAL_I2C_Master_Receive(&I2C_HANLDLE, addr|0x01, rx, 1, I2C_TIMEOUT_COUNT);

    return (rx[0]);
}

 

STM32에서 제공하는 I2C 라이브버리 함수 HAL_I2C_Master_Transmit, HAL_I2C_Master_Receive 를 MSPM0 코드로 포팅해서 코드 호환성을 통일하면 좋을것 같다.

 

I2C 테스트를 위한 가장 간단한 IO EXPANDER PCF8574 SSM 보드로 출력 테스트를 해보자

먼저 I2C 출력 함수 I2C_Write8 함수를 구현하면 

#define I2C_INST           I2C_0_INST
#define I2C_TIMEOUT_COUNT 10000

void HAL_I2C_Master_Transmit(I2C_Regs *i2c, uint8_t addr, uint8_t *buf, uint16_t len, uint16_t timeout)
{
    DL_I2C_fillControllerTXFIFO(i2c, buf, len);

    /* Wait for I2C to be Idle */
    while (!(
        DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_IDLE))
        ;

    /* Send the packet to the controller.
     * This function will send Start + Stop automatically.
     */
    DL_I2C_startControllerTransfer(i2c, addr>>1, DL_I2C_CONTROLLER_DIRECTION_TX, len);

    /* Workaround for errata I2C_ERR_13 */
    //delay_cycles(32000);

    /* Poll until the Controller writes all bytes */
    while (
        DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_BUSY)
        ;

    /* Trap if there was an error */
    if (DL_I2C_getControllerStatus(i2c) &
        DL_I2C_CONTROLLER_STATUS_ERROR) {
        /* LED will remain high if there is an error */
        __BKPT(0);
    }

    /* Wait for I2C to be Idle */
    while (!(
        DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_IDLE))
        ;
}

 

 

MSP0G1307 I2C를 이용하여 GPIO 핀을 확장하는 예제를 구동해 보자.

#define I2C_INST           I2C_0_INST
#define I2C_TIMEOUT_COUNT 1000

#define ADDR_PCF8574      (0x20<<1)

void i2c_write8(uint8_t addr, uint8_t data)
{
    HAL_I2C_Master_Transmit(I2C_INST, addr, &data, 1, 0);
}


void delay_ms(uint16_t ms)
{
	while(ms--)
		delay_cycles(DELAY_1US*1000); 
}

int cnt = 0;
int main(void)
{
    SYSCFG_DL_init();
    PCF8574_Write(0xFF);
    
    while (1) {
        uint8_t led_output = 0;
        if(cnt>8)cnt=0;

        I2C_Write8(ADDR_PCF8574, ~(1<<cnt++));

        delay_ms(100);
    }
}

 

잘 동작한다.

 


이제 STM32에서 사용했던 LTR559 테스트 코드를 그대로 구동해 보자.

LTR559의 거리 값을읽어서 PCF8574에 바그래프 형태로 출력하는 예제를 작성해 보자.

 

#define I2C_INST           I2C_0_INST
#define I2C_TIMEOUT_COUNT 1000
#define ADDR_PCF8574      (0x20<<1)
#define ADDR_LTR559       (0x23<<1)

#define LTR559_PART_ID          0x86
#define LTR559_ALS_CONTR        0x80
#define LTR559_PS_CONTR         0x81


void i2c_write8(uint8_t addr, uint8_t data)
{
    HAL_I2C_Master_Transmit(I2C_INST, addr, &data, 1, 0);
}

unsigned char i2c_read_reg(unsigned char addr, unsigned char data)
{
    unsigned char rx[1];

    HAL_I2C_Master_Transmit(I2C_INST, addr, &data, 1, I2C_TIMEOUT_COUNT);
    HAL_I2C_Master_Receive(I2C_INST, addr|0x01, rx, 1, I2C_TIMEOUT_COUNT);

    return (rx[0]);
}

void i2c_write_reg(unsigned char addr, unsigned char reg, unsigned char data)
{
    unsigned char buf[2];

    buf[0] = reg;
    buf[1] = data;

    HAL_I2C_Master_Transmit(I2C_INST, addr, buf, 2, I2C_TIMEOUT_COUNT);
}



int main(void)
{
    uint8_t id = 0;
	unsigned int distance = 0;
	uint8_t led_mask;
    
    SYSCFG_DL_init();
   
    Led1On();
    delay_ms(1000);
        
    i2c_write8(ADDR_PCF8574, 0xFF);

    id = i2c_read_reg(ADDR_LTR559, LTR559_PART_ID);

    if(id == 0x92)
    {
        // 2. 센서 활성화 (ALS 및 PS 켜기)
        // ALS_CONTR (0x80): Active Mode 설정 (0x01)
        i2c_write_reg(ADDR_LTR559, LTR559_ALS_CONTR, 0x01);
        
        // PS_CONTR (0x81): Active Mode 설정 (0x03)
        i2c_write_reg(ADDR_LTR559, LTR559_PS_CONTR, 0x03);
    }
    else {
    
                  
    }

    while (1) {
        unsigned char led = i2c_read_reg(ADDR_LTR559, 0x8E);
        if(led > 8)led = 8;

        // 바그래프 비트 생성
        led_mask = (1 << led) - 1;
        i2c_write8(ADDR_PCF8574, ~led_mask);
    }
}

 

 

MSPM0G3107 LTR559 거리감지 센서 테스트 결과