본문 바로가기
임베디드 엔지니어링/TMS320F28335

DSP제어(TMS320F28335) : 1ms 주기 LED Toggle 프로그램(2) - GPIO 세팅

by Bennyziio 2019. 4. 9.
반응형

2019/04/09 - [임베디드 프로세서/TMS320F28335] - 1ms 주기 LED Toggle 프로그램(1) - System 세팅

 

1ms 주기 LED Toggle 프로그램(1) - System 세팅

◆ GPIO Toggle 기능을 이용하여 30MHz 오실레이터를 이용하여 150Mhz 클럭을 설정 후 1ms 주기로 제어하는 프로그램을 구현하고자 하였습니다. 추가로 500ms 에서 동작하는 것도 추가를 해 보았으며, 이를 오실로..

bennyziiolab.tistory.com

 

앞선 블로그를 이어서 GPIO 세팅에 관해서 작성하도록 하겠습니다.

 

main() 함수에서 InitSysCtrl() 함수 다음으로 호출된 함수로 InitGpio() 함수를 호출합니다.

void main(void)
{
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2833x_SysCtrl.c file.
   InitSysCtrl();

// Step 2. Initialize GPIO:
// This example function is found in the DSP2833x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
   InitGpio();  // GPIO setup

InitGpio()는 DSP2833x_Gpio.c 소스파일에 작성한 함수로 자세한 내용은 해당 소스파일로 가면 볼 수 있습니다.

 

해당 소스파일을 보여드리기 앞서 GPIO핀을 입/출력으로 사용하기 위한 방법에 대해서 소개를 드리기 위해 GPIO 레지스터에 대해서 설명을 하도록 하겠습니다.

GPIO는 General Purpose Input/Output의 약자입니다.

General Purpose 즉 다목적 입/출력이라고 해석할 수 있습니다.

또한 GPIO Multiplexing 기능을 사용하여 해당 핀을 GPIO로 사용할건지, 주변회로1, 2, 3으로 사용할건지 선택을 할 수 있습니다. 기본값은 GPIO로 설정되어 있기 때문에 GPIO로만 사용할 경우에는 기본값으로 냅두면 되겠습니다.

우선 GPIO 회로 구조를 보시고 좀 더 이야기를 이어가보도록 하겠습니다.

위 구조를 대부분 따라가는데 특성에 따라서 다른 부분도 있으니 이점은 데이터시트를 직접 확인해보시기 바라며, GPIO Control Register에 대해서 설명을 이어가도록 하겠습니다.

위와 같이 GPIO Control Register에는 GPA부터 GPC까지 분류되어 있고 각 레지스터별로 콘트롤하는 핀번호가 다릅니다. 좀 더 함축하여 설명해보도록 하겠습니다.

Gpio0-31핀을 사용하겠다고 가정하여 설명하겠습니다.

 

1. GPACTRL :  GPIO Port A Qualification Control Register로서 입력핀의 샘플링 주기를 설정할때 사용하는 레지스터입니다.

2. GPAQSEL1 : GPIO Port A Qualification Select 1 Register로서 GPIO 0 - 15 핀을 qualification 입력으로 사용할 때 샘플주기를 설정할 수 있는 레지스터입니다.

3. GPAQSEL2 : GPIO Port A Qualification Select 2 Register로서 GPIO 16 - 31 핀을 qualification 입력으로 사용할 때 샘플주기를 설정할 수 있는 레지스터입니다.
4. GPAMUX1 : GPIO Port A Mux 1 Register로서 GPIO 0 - 15핀을 1) GPIO로 사용할지 2) Peripheral 1로 사용할지 3) Peripheral 2로 사용할지 4) Peripheral 3으로 사용할지 설정하는 레지스터입니다.

5. GPAMUX2 : GPIO Port A Mux 2 Register로서 GPIO 16 - 31핀을 1) GPIO로 사용할지 2) Peripheral 1로 사용할지 3) Peripheral 2로 사용할지 4) Peripheral 3으로 사용할지 설정하는 레지스터입니다.

6. GPADIR : GPIO Port A Direction Register로서 GPIO 0 - 31핀의 방향을 정하는 레지스터로 0 - input, 1 - output입니다.

7. GPAPUD : GPIO Port A Pullup Disable Register로서 GPIO 0 - 31핀에 내부 Pullup 저항을 소프트웨어적으로 설정할 수 있는 레지스터입니다.

 

PORT A, PORT B, PORT C에서 똑같이 구성되어 있는데 PORT C에서는 Qualification 기능이 없으므로 관련 레지스터들은 지원이 되지 않습니다.

 

여기까지가 간략한 GPIO의 설명이였으며 각 레지스터를 세부적으로 컨트롤 하는 방법은 코드를 같이 보면서 설명해드리겠습니다. 설명을 드리기 전에 제가 LED Toggle을 진행했던 하드웨어에 대해서 짧게 말씀드리자면 기존에 회사에서 진행했던 시제로서 TMS320F28335 칩을 사용한 보드로 본래 목적의 기능으로 제작된 제어보드입니다만, LED가 3개 달려있어서 이를 이용해서 사용해보았습니다. EVM 모듈을 사용하는 것도 괜찮은 방법입니다만 저는 기왕 있는거 사용하려고 이와 같이 사용했습니다.

 

LED가 GPIO13, 14, 15에 연결되어 있었고 이를 이용하여 GPIO 세팅을 아래와 같이 해보았습니다.

void 
InitGpio(void)
{
	// MUX = 0,0 : GPIO
	//     = 0,1 : PER1
	//     = 1.0 : PER2
	//     = 1,1 : PER3
	// PUD = 0 : pullup
	//	   = 1 : no - pullup
	// DIR : 0 = INPUT, 1 = OUTPUT
	
    EALLOW;
    // [ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ]
    GpioCtrlRegs.GPAMUX2.all = 0x05550FA0;     	// GPIO functionality GPIO16-GPIO31
    GpioCtrlRegs.GPAMUX1.all = 0x00000000;     	// GPIO functionality GPIO0-GPIO15

    //GpioCtrlRegs.GPAQSEL1.all = 0x0000;    	// GPIO0-GPIO15 Synch to SYSCLKOUT
	//GpioCtrlRegs.GPAQSEL2.all = 0x0000;    	// GPIO16-GPIO31 Synch to SYSCLKOUT

    GpioCtrlRegs.GPAPUD.all = 0x0000;      		// Pullup's enabled GPIO0-GPIO31

    GpioCtrlRegs.GPADIR.all = 0xE0D6FFFF;      	// GPIO0-GPIO31 out direction
    GpioDataRegs.GPADAT.all	= 0xE0D6FFFF;	// Out Data
    //GpioDataRegs.GPASET.all = 0xE0D6FFFF;		// Set High
	//GpioDataRegs.GPACLEAR.all = 0x1F250000;		// Set Low

    /* GPIO_NUM	= GPAMUX2 : GPAPUD 	: FUNC 	: 	GPADIR	:  GPADAT 	: DISCRIPTION
    	GPIOB31 = 00	:	0	: GPIO 	: 	OUTPUT	1 : 	1 	: not used
    	GPIOB30 = 00	:	0	: GPIO 	: 	OUTPUT  1 : 	1 	: not used
    	GPIOB29 = 01	:	0	: SCITXDA : 	OUTPUT 	1 : 	1 	: TXD_A
    	GPIOB28 = 01	:	0	: SCIRXDA : 	INPUT  	0 : 	0 	: RXD_A

    	GPIOB27 = 01	:	0	: ECAP4 : 	INPUT  	0 : 	0 	: ECAP4
    	GPIOB26 = 01	:	0	: ECAP3 : 	INPUT  	0 : 	0 	: ECAP3
    	GPIOB25 = 01	:	0	: ECAP2 : 	INPUT  	0 : 	0 	: ECAP2
    	GPIOB24 = 01	:	0	: ECAP1 : 	INPUT  	0 : 	0 	: ECAP1

    	GPIOB23 = 00	:	0	: GPIO 	: 	INPUT   1 : 	1 	: not used
    	GPIOB22 = 00	:	0	: GPIO 	: 	INPUT   1 : 	1 	: not used
    	GPIOB21 = 11	:	0	: CANRXB: 	INPUT  	0 : 	0 	: CANRXB
    	GPIOB20 = 11	:	0	: CANTXB: 	OUTPUT 	1 : 	1 	: CANTXB

    	GPIOB19 = 10	:	0	: SCIRXDB: 	INPUT  	0 : 	0 	: SCI_RXB
    	GPIOB18 = 10	:	0	: SCITXDB: 	OUTPUT 	1 : 	1 	: SCI_TXB
    	GPIOB17 = 00	:	0	: GPIO 	: 	OUTPUT  1 : 	1 	: not used
    	GPIOB16 = 00	:	0	: GPIO 	: 	INPUT   0 : 	0 	: not used

      GPIO_NUM	= GPAMUX1
    	GPIOB15	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: LED3
    	GPIOB14	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: LED2
    	GPIOB13	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1	: LED1
    	GPIOB12	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO

    	GPIOB11	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB10	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB9	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB8	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO

    	GPIOB7	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB6	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB5	= 00	:	0	: GPIO 	: 	OUTPUT 	1 :	1 	: GPIO
    	GPIOB4	= 00	:	0	: GPIO 	: 	OUTPUT 	1 :	1 	: GPIO

    	GPIOB3	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB2	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB1	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB0	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    */

기존에 개발된 보드이다 보니 다른 세팅도 되어 있는 모습을 볼 수 있는데요. 부품이 실장되어 있는 보드이다 보니 전원 연결시 입력인데 출력으로 세팅이 되어 혹시 모를 불상사가 나타나지 않기 위해서 동일하게 설정을 해두었고 저의 목적인 GPIO 13, 14, 15를 LED 출력으로 설정한 것을 볼 수 있습니다.

 

자 이제 위 코드가 뭐냐? 하나하나씩 분석해 봅시다.

앞에서 말씀드린데로 main()함수에서 InitGpio()함수를 콜한다고 했는데요. 네! main() 함수에서 GPIO세팅된 초기값을 불러오겠다는 것이고 그렇다면 GPIO 초기값 세팅을 해주어야 한다는 결론입니다.

작성된 순서대로 설명해드리도록 하겠습니다.

우선 저 위 코드 탬플릿이라고 해야 할까요? 선배들이 해놓은 자료를 보고 제 나름대로 변형을 해 본 것입니다. 이렇게 해두면 한 눈에 들어와서 편하더라구요. 내심 주석에서 bit 단위로 설정한 값을 통틀어 all 단위로 자동 작성이 되면 얼마나 좋을까 생각해봤지만...일단은 중요한건 그게 아니니깐요.

 

자 우선 EALLOW를 해줍니다. 왜냐하면 GPIO는 Protect 기능에 의해 보호되고 있습니다. Protect 기능에 대해서 간략히 설명하면 DSP의 기능들이 이미 설정되어 있는데 이를 맘대로 수정이 되어버리면 제기능을 다하기 어려워 지기 때문에 안전장치로 보호를 하고 있는 것입니다. 그래서 이를 수정하기 위해서 EALLOW를 통해서 보호기능을 잠시 해제하고 마침내 비로소 레지스터에 접근하여 컨트롤 할 수 있게 되는것입니다.

 

GPIO를 설정하는 단계를 TI사에서 제안한 내용이 있어 아래와 같이 첨부하였습니다.

 

저는 1번은 이미 하드웨어적으로 세팅이 되어 있고 2, 3번은 해당 LED_Toggle 프로그램에서는 해당사항이 없어서 4번으로 넘어가서 작성을 하였습니다.

 

GPAMUX1, 2를 세팅해보도록 하겠습니다.

GpioCtrlRegs.GPAMUX1.all = 0x00000000;      // GPIO functionality GPIO0-GPIO15

위와 같이 작성하였는데요. 일단 제가 사용한 TMS320F28335는 32비트 CPU를 탑재하고 있습니다. 외부에는 16비트 버스만 나와있지만 칩 내부에는 32비트 버스가 깔려있습니다. 이게 뭔소리냐? 각 레지스터들의 길이가 32비트라는 소리입니다. 0b00000000000000000000000000000000 -> 0x00000000의 공간을 가지고 있다고 볼 수 있습니다.

그래서 위 레지스터.all = 0xXXXXXXXX; 형태로 작성이 되어 있는 것입니다.

다음 그림을 보면 더 이해가 잘 되실 겁니다.

0부터 시작하여 31까지 총 32개의 공간으로 구성되어 있습니다.

GPAMUX1은 GPIO Port A Multiplexing Register로서 4가지 기능중에서 원하는 기능을 고를 수 있습니다. 

	*/
      GPIO_NUM	= GPAMUX1
    	GPIOB15	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: LED3
    	GPIOB14	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: LED2
    	GPIOB13	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1	: LED1
    	GPIOB12	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO

    	GPIOB11	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB10	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB9	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB8	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO

    	GPIOB7	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB6	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB5	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB4	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO

    	GPIOB3	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB2	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB1	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB0	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    */

GPAMUX1은 GPIO0 - 15까지 핀을 설정할 수 있는 레지스터이고 위와 같이 정리한 주석을 보면 모두 00으로 설정이 되어 있음을 확인하실 수 있을 것니다. 위의 그림을 보시다 시피 GPIO 한개의 핀마다 2비트가 할당되어 있고 이는 4가지 기능들을 설정하기 위해 2비트가 설정된 것입니다. 

위 그림을 보시면 GPAMUX1 bit가 00이면 GPIO, 01이면 Peripheral 1, 10이면 Peripheral 2, 11이면 Peripheral 3의 기능으로 설정이 됩니다.

그리고 저는 LED 출력으로 GPIO 13, 14, 15를 세팅해야 하므로 위 코드와 같이 작성을 한 경우입니다.

그 후 GPAMUX2도 동일한 개념으로 특성에 맞게 세팅하면 되겠습니다.

 

GpioCtrlRegs.GPAPUD.all = 0x00000000;

GPAPUD는 GPIO Port A Pullup Register라고 설명드렸습니다. 사실 Pullup 레지스터는 하드웨어에서 지정을 해주고 소프트웨어적으로는 적용을 해보지 않았기 때문에 가능유무만 알고 있지 건드려보지는 않았으나 추후에 고려해서 설계를 해보고자 합니다. 아래 그림을 참조하시기 바랍니다.

 

GpioCtrlRegs.GPADIR.all = 0xE0D6FFFF;

GPADIR은 GPIO Port A Direction으로 GPIO의 방향을 설정한다고 설명드렸습니다. 우선 LED 출력핀인 GPIO 13, 14, 15를 그런 연유로 Output(1)로 세팅을 하였으며 GPADIR 같은 경우는 GPIO 0-31까지 1bit씩 32bit로 구성되어 있으므로 제가 GPAMUX1에서 Direction이 모두 Output으로 되어 있습니다. 즉 모두 1의 값이며 하위 16개 비트가 모두 1인 FFFF의 값으로 세팅된 것을 볼 수 있으실 겁니다. E0D6은 GPAMUX2의 세팅값을 따라 세팅이 되었습니다. 아래 그림을 참조하시면 이해가 더 잘 될것입니다.

이제까지 GPIO의 기능 설정, 내부 풀업 저항 세팅, input인지 output인지 세팅까지 완료하였습니다. 그럼 이제 각 핀에 데이터를 지정해주어야 출력시 출력값을 내뱉게 됩니다. 이는 GPADAT라는 레지스터에서 세팅해줄 수 있는데 코드는 아래와 같습니다.

GpioDataRegs.GPADAT.all	= 0xE0D6FFFF;

GPADAT는 GPIO Port A Data Register로서 0이면 low, 1이면 high 값을 가지게 됩니다.

GPIO 0 - 31까지의 핀들에 대한 세팅을 할 수 있으며 아래 그림을 참조하시면 더 큰 이해가 될거라 봅니다.

이런 식으로 GPIO Port B, C들도 세팅해 줄 수 있습니다.

 

아래는 DSP2833x_Gpio.c 전체 소스입니다. 

 

void 
InitGpio(void)
{
	// MUX = 0,0 : GPIO
	//     = 0,1 : PER1
	//     = 1.0 : PER2
	//     = 1,1 : PER3
	// PUD = 0 : pullup
	//	   = 1 : no - pullup
	// DIR : 0 = INPUT, 1 = OUTPUT
	
    EALLOW;
    // [ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ]
    GpioCtrlRegs.GPAMUX2.all = 0x05550FA0;     	// GPIO functionality GPIO16-GPIO31
    GpioCtrlRegs.GPAMUX1.all = 0x00000000;     	// GPIO functionality GPIO0-GPIO15

    //GpioCtrlRegs.GPAQSEL1.all = 0x0000;    	// GPIO0-GPIO15 Synch to SYSCLKOUT
	//GpioCtrlRegs.GPAQSEL2.all = 0x0000;    	// GPIO16-GPIO31 Synch to SYSCLKOUT

    GpioCtrlRegs.GPAPUD.all = 0x0000;      		// Pullup's enabled GPIO0-GPIO31

    GpioCtrlRegs.GPADIR.all = 0xE0D6FFFF;      	// GPIO0-GPIO31 out direction
    GpioDataRegs.GPADAT.all	= 0xE0D6FFFF;	// Out Data
    //GpioDataRegs.GPASET.all = 0xE0D6FFFF;		// Set High
	//GpioDataRegs.GPACLEAR.all = 0x1F250000;		// Set Low

    /* GPIO_NUM	= GPAMUX2 : GPAPUD 	: FUNC 	: 	GPADIR	:  GPADAT 	: DISCRIPTION
    	GPIOB31 = 00	:	0	: GPIO 	: 	OUTPUT	1 : 	1 	: not used
    	GPIOB30 = 00	:	0	: GPIO 	: 	OUTPUT  1 : 	1 	: not used
    	GPIOB29 = 01	:	0	: SCITXDA : 	OUTPUT 	1 : 	1 	: TXD_A
    	GPIOB28 = 01	:	0	: SCIRXDA : 	INPUT  	0 : 	0 	: RXD_A

    	GPIOB27 = 01	:	0	: ECAP4 : 	INPUT  	0 : 	0 	: ECAP4
    	GPIOB26 = 01	:	0	: ECAP3 : 	INPUT  	0 : 	0 	: ECAP3
    	GPIOB25 = 01	:	0	: ECAP2 : 	INPUT  	0 : 	0 	: ECAP2
    	GPIOB24 = 01	:	0	: ECAP1 : 	INPUT  	0 : 	0 	: ECAP1

    	GPIOB23 = 00	:	0	: GPIO 	: 	INPUT   1 : 	1 	: not used
    	GPIOB22 = 00	:	0	: GPIO 	: 	INPUT   1 : 	1 	: not used
    	GPIOB21 = 11	:	0	: CANRXB: 	INPUT  	0 : 	0 	: CANRXB
    	GPIOB20 = 11	:	0	: CANTXB: 	OUTPUT 	1 : 	1 	: CANTXB

    	GPIOB19 = 10	:	0	: SCIRXDB: 	INPUT  	0 : 	0 	: SCI_RXB
    	GPIOB18 = 10	:	0	: SCITXDB: 	OUTPUT 	1 : 	1 	: SCI_TXB
    	GPIOB17 = 00	:	0	: GPIO 	: 	OUTPUT  1 : 	1 	: not used
    	GPIOB16 = 00	:	0	: GPIO 	: 	INPUT   0 : 	0 	: not used

      GPIO_NUM	= GPAMUX1
    	GPIOB15	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: LED3
    	GPIOB14	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: LED2
    	GPIOB13	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1	: LED1
    	GPIOB12	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO

    	GPIOB11	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB10	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB9	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB8	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO

    	GPIOB7	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB6	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB5	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB4	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO

    	GPIOB3	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB2	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB1	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    	GPIOB0	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: GPIO
    */

	// [ BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB ]

    GpioCtrlRegs.GPBMUX2.all = 0x00055000;     	// GPIO functionality GPIO48-GPIO63
    GpioCtrlRegs.GPBMUX1.all = 0xFFFF3FF5;     	// GPIO functionality GPIO32-GPIO39

    GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3;		// Async input GPIO32 (SDAA)
    GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;		// Async input GPIO33 (SCLA)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO54 = 3;		// Async input GPIO54 (SPISI)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO55 = 3;		// Async input GPIO55 (SPISO)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO56 = 3;		// Async input GPIO56 (SPICLK)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO57 = 3;		// Async input GPIO57 (SPISTE)

    GpioCtrlRegs.GPBPUD.all = 0x03000077;      	// Pullup's enabled GPIO32-GPIO63

    GpioCtrlRegs.GPBDIR.all = 0x0380FFFF;      	// GPIO32-GPIO63 out direction

    GpioDataRegs.GPBDAT.all = 0x020000F7;		// Out data

    /* GPIO_NUM	= GPBMUX2 : GPAPUD 	: FUNC 	: 	GPADIR	:  GPADAT 	: DISCRIPTION
	GPIOB63 = 00	:	0	: GPIO 	: 	INPUT	0 : 	0 	: not used
    	GPIOB62 = 00	:	0	: GPIO 	: 	INPUT  	0 : 	0 	: not used
    	GPIOB61 = 00	:	0	: GPIO 	: 	INPUT 	0 : 	0 	: not used
    	GPIOB60 = 00	:	0	: GPIO 	: 	INPUT  	0 : 	0 	: not used

    	GPIOB59 = 00	:	0	: GPIO 	: 	INPUT  	0 : 	0 	: not used
    	GPIOB58 = 00	:	0	: GPIO 	: 	INPUT  	0 : 	0 	: not used
    	GPIOB57 = 01	:	1	: SPISTE : 	OUTPUT  1 : 	1 	: SPISTE A
    	GPIOB56 = 01	:	1	: SPICLK : 	OUTPUT  1 : 	0 	: SPICLK A

    	GPIOB55 = 01	:	0	: SPISO : 	OUTPUT  1 : 	0 	: SPISOMI A
    	GPIOB54 = 01	:	0	: SPISI : 	INPUT   0 : 	0 	: SPISIMO A
    	GPIOB53 = 00	:	0	: GPIO	: 	INPUT  	0 : 	0 	: not used
    	GPIOB52 = 00	:	0	: GPIO	: 	INPUT 	0 : 	0 	: not used

    	GPIOB51 = 00	:	0	: GPIO	: 	INPUT  	0 : 	0 	: not used
    	GPIOB50 = 00	:	0	: GPIO	: 	INPUT 	0 : 	0 	: not used
    	GPIOB49 = 00	:	0	: GPIO 	: 	INPUT  	0 : 	0 	: not used
    	GPIOB48 = 00	:	0	: GPIO 	: 	INPUT   0 : 	0 	: not used

      GPIO_NUM	= GPBMUX1
    	GPIOB47	= 11	:	0	: XA7 	: 	OUTPUT 	1 : 	0 	: XA7
    	GPIOB46	= 11	:	0	: XA6 	: 	OUTPUT 	1 : 	0 	: XA6
    	GPIOB45	= 11	:	0	: XA5 	: 	OUTPUT 	1 : 	0	: XA5
    	GPIOB44	= 11	:	0	: XA4 	: 	OUTPUT 	1 : 	0 	: XA4

    	GPIOB43	= 11	:	0	: XA3 	: 	OUTPUT 	1 : 	0 	: XA3
    	GPIOB42	= 11	:	0	: XA2 	: 	OUTPUT 	1 : 	0 	: XA2
    	GPIOB41	= 11	:	0	: XA1 	: 	OUTPUT 	1 : 	0 	: XA1
    	GPIOB40	= 11	:	0	: XA0 	: 	OUTPUT 	1 : 	0 	: XA0

    	GPIOB39	= 00	:	0	: GPIO 	: 	OUTPUT 	1 : 	1 	: not used
    	GPIOB38	= 11	:	1	: WE0 	: 	OUTPUT 	1 : 	1 	: WE0
    	GPIOB37	= 11	:	1	: CS7 	: 	OUTPUT 	1 : 	1 	: nCS7
    	GPIOB36 = 11	:	1	: CS0 	: 	OUTPUT 	1 : 	1 	: nCS0

    	GPIOB35	= 11	:	0	: XRnW 	: 	OUTPUT 	1 : 	0 	: XRnW
    	GPIOB34	= 11	:	1	: XREADY : 	OUTPUT 	1 : 	1 	: READY
    	GPIOB33	= 01	:	1	: SCLA 	: 	OUTPUT 	1 : 	1 	: SCLA
    	GPIOB32	= 01	:	1	: SDAA 	: 	OUTPUT 	1 : 	1 	: SDAA
	*/

    // [ CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC ]

    GpioCtrlRegs.GPCMUX2.all = 0x0000FFFF;     	// GPIO functionality GPIO80-GPIO87
    GpioCtrlRegs.GPCMUX1.all = 0xFFFFFFFF;     	// GPIO functionality GPIO64-GPIO79

    GpioCtrlRegs.GPCDIR.all = 0x00FF0000;      	// GPI064-GPIO95 out direction

    GpioCtrlRegs.GPCPUD.all = 0x00000000;      	// Pullup's enabled GPIO64-GPIO87

    GpioDataRegs.GPCDAT.all = 0x00000000;		// Out Data

    /* GPIO_NUM	= GPCMUX2 : GPAPUD 	: FUNC 	: 	GPADIR	:  GPADAT 	: DISCRIPTION
    	GPIOC95 = X
    	GPIOC94 = X
    	GPIOC93 = X
    	GPIOC92 = X

    	GPIOC91 = X
    	GPIOC90 = X
    	GPIOC89 = X
    	GPIOC88 = X

    	GPIOC87 = 11	:	0	: XA15	: 	OUTPUT  1 : 	0 	: XA15
    	GPIOC86 = 11	:	0	: XA14	: 	OUTPUT  1 : 	0 	: XA14
    	GPIOC85 = 11	:	0	: XA13	: 	OUTPUT  1 : 	0 	: XA13
    	GPIOC84 = 11	:	0	: XA12	: 	OUTPUT 	1 : 	0 	: XA12

    	GPIOC83 = 11	:	0	: XA11	: 	OUTPUT  1 : 	0 	: XA11
    	GPIOC82 = 11	:	0	: XA10	: 	OUTPUT 	1 : 	0 	: XA10
    	GPIOC81 = 11	:	0	: XA9 	: 	OUTPUT  1 : 	0 	: XA9
    	GPIOC80 = 11	:	0	: XA8 	: 	OUTPUT  1 : 	0 	: XA8

      GPIO_NUM	= GPCMUX1
    	GPIOC79	= 11	:	0	: XD0 	: 	INPUT 	0 : 	0 	: XD0
    	GPIOC78	= 11	:	0	: XD1 	: 	INPUT 	0 : 	0 	: XD1
    	GPIOC77	= 11	:	0	: XD2 	: 	INPUT 	0 : 	0	: XD2
    	GPIOC76	= 11	:	0	: XD3 	: 	INPUT 	0 : 	0 	: XD3

    	GPIOC75	= 11	:	0	: XD4 	: 	INPUT 	0 : 	0 	: XD4
    	GPIOC74	= 11	:	0	: XD5 	: 	INPUT 	0 : 	0 	: XD5
    	GPIOC73	= 11	:	0	: XD6 	: 	INPUT 	0 : 	0	: XD6
    	GPIOC72	= 11	:	0	: XD7 	: 	INPUT 	0 : 	0 	: XD7

    	GPIOC71	= 11	:	0	: XD8 	: 	INPUT 	0 : 	0 	: XD8
    	GPIOC70	= 11	:	0	: XD9 	: 	INPUT 	0 : 	0 	: XD9
    	GPIOC69	= 11	:	0	: XD10 	: 	INPUT 	0 : 	0	: XD10
    	GPIOC68	= 11	:	0	: XD11 	: 	INPUT 	0 : 	0 	: XD11

    	GPIOC67	= 11	:	0	: XD12 	: 	INPUT 	0 : 	0 	: XD12
    	GPIOC66	= 11	:	0	: XD13 	: 	INPUT 	0 : 	0 	: XD13
    	GPIOC65	= 11	:	0	: XD14 	: 	INPUT 	0 : 	0	: XD14
    	GPIOC64	= 11	:	0	: XD15 	: 	INPUT 	0 : 	0 	: XD15
	*/

    EDIS;
}	
	
//
// End of file
//

 

그리고 EALLOW로 Protect를 해제한 것을 EDIS로 Protect 모드를 설정하여 보호 기능을 작동시킵니다.

 

이렇게 해서 main() 함수에서 InitGpio() 함수 내에 선언된 GPIO 레지스터 초기값을 설정하고 호출하여 사용하였습니다. 모든 시스템은 초기에 값을 설정해주지 않으면 그안에 쓰레기값이 들어있어 잘못된 기능을 할 수 있습니다. 그러므로 초기화를 해주는 과정은 매우 중요한 과정중에 하나입니다.

 

반응형

댓글