TODO : GPIO 이용하여 RTC 디바이스를 사용하기 위해 RTC I2C통신을 한다.(, 실제 I2C통신을 사용할 주어진 함수를 이용한다.)

 

*SDA: data, SCL : 디바이스 신호 동기화에 사용되는 클럭.

*SCL high data 읽고 Low SDA 바뀐다. 이런식으로 통신

(i2c 데이터 통신 중에는 클럭이 high 시그널일 때에는 데이터(SDA) 시그널이 변경되면 안된다. 이러한 규칙으로 인해 클럭이 high 상태에서는 데이터를 안정적으로 읽는 것을 보장한다.)

 

*Master cpu, slave 디바이스들

 

*Ack 응답 Ack : 0, 무응답 Ack :1(? – Need to check)

 

1. 회로도 분석

 

 

2. Data Sheet 보고 set configuration

 

DDKIomuxSetPinMux DDKGpioSetConfig 등등

3.RTC chip DataSheet 분석

 

=> Slave address를 알 수 있다.

=> data를 보낼 때 여러개의 data를 연달아 보낼 수 있다. 단 1 < 1s 조건 ->1s이상 해본 결과 처음Write 할때 만 이상하게 들어가고 다시 Write하면 제대로잘 들어감

=> R/W mode 방식

=>  data 보낼 여러개의 data 연달아 보낼 있다. 1 < 1s 조건

=>  Lasty data byte 지금은 쓰지 않았지만 레지스터에 여러 데이터를 넣는 경우도 있는 같다.

그리고 Read mode에서 set register read data 사이에 Start, Stop 존재 해야하며 10초정도의

시간이 지나도 읽을 있더라.(자세히 모르겟다)

 

 

 

 

 **주요 이슈

1. DataPin Read 없었음

-> DDK_GPIO_DIR_IN 설정하지 않았음, R/W 마다 신경 써야한다

2. Data Read하는 부분 여러 Read하는데 방법을 잘모르겠으며 처음 한번만 잘나오고 뒤에는 쓰래기값이 나온다.

 - 문제점 1 : 

      int bin[8]={0,};

           =>bin 배열이 clear 되지 않아서 전에 쓰던 값이 들어가는 문제, 전역변수에서 지역변수로 바꿔줌

 - 문제점 2 : Write와 Read의 Data를 읽을 때 Regiter의 주소는 시작하는 주소 하나만 넣어서 8bit씩 읽으면 순차적으로 읽거나 쓸 수 있다.

 

#define myd_speed (10)



void Start()

{

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 13, 0);

        Sleep(myd_speed);

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 12, 0);

        Sleep(myd_speed);

        //Start 신호-> SCL이High 상태일때, SDA이Low로변하면Start

}

void Stop()

{

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 12, 1);

        Sleep(myd_speed);

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 13, 1);

        Sleep(myd_speed);

        //Stop 신호-> SCL이High 상태일때, SDA이High로변하면Stop

}

void SCL_Clock()

{

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 12, 1);

        Sleep(myd_speed);

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 12, 0);

        Sleep(myd_speed);

}





//SDA 8bit Data

void Clock_data(int data)

{

    int bin[8]={0,};    //주소를역순으로보내기위한배열



    int position = 7;

    while(data != 0){//bin 배열Clear후저장

        bin[position] = data %2;

        data /= 2;

        position--;

    }

            

    for(int i=0;i<8;i++){

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 13, bin[i]);

        SCL_Clock();

    }

}



void Read_data(int reg_addr)

{

        UINT32 pinVal;

        RETAILMSG(1, (L"[ I2C Read !!! ] "));

        Start();



        Clock_data(0xD0);//1101000 (Slave address + Write bit)(7bit + 1bit)

        SCL_Clock();//Ack



        Clock_data(reg_addr);//input data(data address)

        SCL_Clock();//Ack



        Stop();





        for(int i=0;i<3;i++){//03h ~ 05h만읽는다.

            Start();



            Clock_data(0xD1);//1101001 (Slave address + Read bit)

            SCL_Clock();//Ack





            /*            print            */

            RETAILMSG(1, (L"Read Data : ["));

            for(int i=0;i<8;i++){

                DDKGpioWriteDataPin(DDK_GPIO_PORT4, 12, 1);

                Sleep(myd_speed);

                DDKGpioSetConfig(DDK_GPIO_PORT4, 13, DDK_GPIO_DIR_IN, DDK_GPIO_INTR_NONE);

                //Set DDK_GPIO_DIR_IN For Read mode enable



                DDKGpioReadDataPin(DDK_GPIO_PORT4, 13, &pinVal);

                RETAILMSG(1, (L"%d",pinVal));



                DDKGpioSetConfig(DDK_GPIO_PORT4, 13, DDK_GPIO_DIR_OUT, DDK_GPIO_INTR_NONE);

                DDKGpioWriteDataPin(DDK_GPIO_PORT4, 12, 0);

                Sleep(myd_speed);

            }

            RETAILMSG(1, (L"]"));

            SCL_Clock();//Ack



            Stop();

        }

}



BOOL MYD_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, 

                   DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,

                   PDWORD pdwActualOut)

{

    BOOL bRet = FALSE;



    switch(dwCode){

        case 1:

            /*                Init            */

            DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL3, DDK_IOMUX_PIN_MUXMODE_ALT5, DDK_IOMUX_PIN_SION_REGULAR);

            //datasheet -> IOMUXC_SW_MUX_CTL_PAD_KEY_COL3 의gpio4_12(SCL)( ALT5) 설정(enable)

            DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW3, DDK_IOMUX_PIN_MUXMODE_ALT5, DDK_IOMUX_PIN_SION_REGULAR);

            //datasheet -> IOMUXC_SW_MUX_CTL_PAD_KEY_ROW3 의gpio4_13(SDA)( ALT5) 설정(enable)



            DDKGpioSetConfig(DDK_GPIO_PORT4, 12, DDK_GPIO_DIR_OUT, DDK_GPIO_INTR_NONE);

            DDKGpioSetConfig(DDK_GPIO_PORT4, 13, DDK_GPIO_DIR_OUT, DDK_GPIO_INTR_NONE);

            //12, 13 bit Write mode enable

            



            RETAILMSG(1, (L"[ I2C Write !!! ] "));//Slave address : 1101000(RTC -> Chip : PCF8523TS/1 ) , Read : 1 Write : 0

            Start();

            

            Clock_data(0xD0);//1101000 (Slave address + Write bit)(7bit + 1bit)

            SCL_Clock();//Ack



            /*

            03h : Seconds(data address)

            04h : Minutes(data address)

            05h : Hours(data address)

            */

            Clock_data(0x03);

            SCL_Clock();//Ack





            Clock_data(0x00);//0초[7]:clock integrity is guaranteed, [6-0] 

            SCL_Clock();//Ack

            Clock_data(0x10);//10분[7]: unused, [6-4]: ten's place, [3-0]: unit place

            SCL_Clock();//Ack

            Clock_data(0x13);//13시[7-6]: unused, 12mode [5] : 0-AM,1-PM, [4]: ten's place,[3-0]: unit place

            SCL_Clock();//Ack                       24mode [5-4]: ten's place,[3-0]: unit place



            Stop();

            

            break;

        case 2:

            Read_data(0x03);



            break;

        case 3:



            break;



    }

      return bRet;

}

'kernel Driver' 카테고리의 다른 글

[Atmega128]Character LCD  (0) 2019.04.30
[Atmega128]PWM(Buzzer)  (0) 2019.04.30

+ Recent posts