Skip to content

01. GPIO#

1. Setting#

1-1. 프로젝트 생성#

s32ds app project

S32 Design Studio를 실행하고 왼쪽 하단의 S32DS Application Project를 클릭한다.

1-2. 프로젝트 설정#

project name and family

Project name을 입력하고, Family S32K3xx->S32K312를 선택한 후 Next를 클릭한다.

finish

이후 별도의 설정을 건드리지 않고 Finish를 클릭한다.

2. LED 예제 (타이머 주기에 따른 LED Toggle)#

  1. 새로운 예제를 위한 프로젝트를 생성한다.
  2. 원하는 동작을 위해 레지스터와 메모리에 직접 접근해 값을 써야 한다.
  3. 해당 예제에서는 LED를 사용하기 때문에 board schematic에서 LED 정보를 파악한다.
  4. LED가 연결된 GPIO 모듈의 메모리 맵을 분석한다.
  5. 분석 결과를 활용해 임베디드 프로그래밍을 한다.

2-1. Schematic 분석#

led schematic

led port

해당 보드의 Schematic과 HW manual을 참고하면 RGB LED는 PTC10, PTB17, PTB16에 연결되어 있으며 각각 Red, Green, Blue를 제어한다. (Schematic과 RGB 순서가 다르다)
본 예제에서는 RGB LED의 Red를 이용할 것이므로, PTC10을 사용한다.

2-2. Datasheet 분석#

2-2-1. IO 설정#

SIUL2 설명

LED를 사용하기 위해 연결된 핀의 IO 설정이 필요하다.

  1. MSCR(Multiplexed Signal Configuration Register)의 SSS(Source Signal Select) 비트를 0으로 설정하면 GPIO로 동작한다.
  2. MSCR의 OBE 비트를 1로 설정하면 출력으로 동작한다.

MSCR 구조

MSCR SSS

SSS list

MSCR OBE, IBE

PortA offset

PTCm을 제어하기 위한 MSCRn 번호는 \(\rm n=(m+64)\)이다.
MSCRn의 주소는 \(\rm SIUL2\ base + MSCR\ offset+ (n \times 4)\)로 구할 수 있다.
MSCR74 주소: 4029_0368h (4029_0000h + 240h + 128h)

2-2-2. Port Clock 설정#

no clocking

S32K312는 GPIO를 사용하기 위한 별도의 클럭 설정을 할 필요가 없다.

2-2-3. 출력 데이터 설정#

GPDO 주소

GPDO 구조

GPDO 레지스터의 LSB를 write해 원하는 출력을 만들 수 있다.

PTCm을 제어하기 위한 GPDOn 번호는 MSCRn 번호와 동일하다. GPDOn의 주소는 \(\rm SIUL2\ base + GPDO\ offset+ (n+3-2\times(n\ mod\ 4))\)로 구할 수 있다.
GPDO74 주소: 4029_131Eh (4029_0000h + 1300h + 0x49)

2-3. 프로그래밍#

2-3-1. 매크로 정의#

  • IO 설정 관련 레지스터 주소 및 비트 필드 정의
    // SIUL2 Registers
    #define SIUL2_BASE      (0x40290000UL)
    #define SIUL2_MSCR_BASE (SIUL2_BASE + 0x240)
    #define SIUL2_MSCR74    (*(volatile unsigned *)(SIUL2_MSCR_BASE + 0x128))
    #define SIUL2_GPDO_BASE (SIUL2_BASE + 0x1300)
    #define SIUL2_GPDO74    (*(volatile unsigned char *)(SIUL2_GPDO_BASE + 0x49))
    
    // MSCR Bits
    #define OBE_BIT 21 // Output Buffer Enable
    #define SSS_BITS 0 // Source Signal Select
    

2-3-2. main 코드#

  • main 함수
    int main(void) {
      int cycles = 0;
      SIUL2_MSCR74 &= (0b0000 << SSS_BITS);
      SIUL2_MSCR74 |= (1 << OBE_BIT);
    
      while (1) {
        cycles = 720000;
        while (cycles--);
        SIUL2_GPDO74 = 1;
    
        cycles = 720000;
        while (cycles--);
        SIUL2_GPDO74 = 0;
      }
    
      return 0;
    }
    
    MSCR74의 SSS를 0으로 만들고 OBE를 set해 GPIO output으로 설정한다.

이후 일정 주기마다 GPDO29의 값을 바꾸도록 루프문을 작성한다.

2-4. 빌드#

build tool

상단 툴바에서 Build All 버튼을 눌러 빌드한다.

2-5. 디버그#

debug tool

상단 메뉴에서 디버그 툴 옆 삼각형을 눌러 Debug Configurations에 진입한다.

debug config

GDB PEMicro Interface Debugging의 하위에서 (프로젝트명)_Debug_FLASH_PNE를 선택하고 Debug를 눌러 디버그에 진입한다.

3. Switch 예제 (Switch를 이용한 LED on/off 제어)#

  1. 새로운 예제를 위한 프로젝트를 생성한다.
  2. 원하는 동작을 위해 레지스터와 메모리에 직접 접근해 값을 써야 한다.
  3. 해당 예제에서는 switch를 사용하기 때문에 board schematic에서 switch 정보를 파악한다.
  4. Switch가 연결된 GPIO 모듈의 메모리 맵을 분석한다.
  5. 분석 결과를 활용해 임베디드 프로그래밍을 한다.

3-1. Schematic 분석#

sw schematic

sw port

해당 보드의 Schematic과 HW manual을 참고하면 User switch는 PTD2, PTD3에 연결되어 있다. Switch가 Active-low 구조이므로 GPDI 값이 0일 때 스위치가 눌린 것으로 파악할 수 있다.

3-2. Datasheet 분석#

3-2-1. IO 설정#

SIUL2 설명

Switch를 사용하기 위해 연결된 핀의 IO 설정이 필요하다.

  1. MSCR(Multiplexed Signal Configuration Register)의 SSS(Source Signal Select) 비트를 0으로 설정하면 GPIO로 동작한다.
  2. MSCR의 IBE 비트를 1로 설정하면 출력으로 동작한다.

MSCR 구조

MSCR SSS

MSCR OBE, IBE

PortB offset

PTDm을 제어하기 위한 MSCRn 번호는 \(\rm n=(m+96)\)로 구할 수 있다.
MSCRn의 주소는 \(\rm SIUL2\ base + MSCR\ offset+ (n \times 4)\)로 구할 수 있다.
MSCR98 주소: 4029_03C8h (4029_0000h + 240h + 188h)

3-2-2. Port Clock 설정#

no clocking

S32K312는 GPIO를 사용하기 위한 별도의 클럭 설정을 할 필요가 없다.

3-2-3. 입력 데이터 읽기#

GPDI 주소

GPDI 구조

GPDO 레지스터의 LSB를 write해 원하는 출력을 만들 수 있다.

PTBm을 제어하기 위한 GPDIn 번호는 MSCRn 번호와 동일하다.
GPDIn의 주소는 \(\rm SIUL2\ base + GPDI\ offset+ (n+3-2\times(n\ mod\ 4))\)로 구할 수 있다.
GPDI98 주소: 4029_1561h (4029_0000h + 1500h + 61h)

3-3. 프로그래밍#

3-3-1. 매크로 정의#

  • IO 설정 관련 레지스터 주소 및 비트 필드 정의
    // SIUL2 Registers
    #define SIUL2_BASE      (0x40290000UL)
    #define SIUL2_MSCR_BASE (SIUL2_BASE + 0x240)
    #define SIUL2_MSCR74    (*(volatile unsigned *)(SIUL2_MSCR_BASE + 0x128))
    #define SIUL2_MSCR98    (*(volatile unsigned *)(SIUL2_MSCR_BASE + 0x188))
    
    #define SIUL2_GPDO_BASE (SIUL2_BASE + 0x1300)
    #define SIUL2_GPDO74    (*(volatile unsigned char *)(SIUL2_GPDO_BASE + 0x49))
    #define SIUL2_GPDI_BASE (SIUL2_BASE + 0x1500)
    #define SIUL2_GPDI98    (*(volatile unsigned char *)(SIUL2_GPDI_BASE + 0x61))
    
    // MSCR Bits
    #define OBE_BIT 21 // Output Buffer Enable
    #define IBE_BIT 19 // Input Buffer Enable
    #define SSS_BITS 0 // Source Signal Select
    

3-3-2. main 코드#

  • main 함수
    int main(void) {
      SIUL2_MSCR74 &= ~(0b1111 << SSS_BITS); // GPIO
      SIUL2_MSCR74 |= (1 << OBE_BIT);        // output
      SIUL2_MSCR98 &= ~(0b1111 << SSS_BITS); // GPIO
      SIUL2_MSCR98 |= (1 << IBE_BIT);        // input
    
      while (1) {
        if (!SIUL2_GPDI98) // Active-low switch
          SIUL2_GPDO74 = 1;
        else
          SIUL2_GPDO74 = 0;
      }
    
      return 0;
    }
    
    MSCR98의 SSS를 0으로 만들고 IBE를 set해 GPIO input으로 설정한다.

이후 GPDI98의 값을 계속 체크해 눌린 경우(0)에 LED를 켜도록 루프문을 작성한다.

3-4. 동작 모습#

  • 빌드, 디버그 후 스위치를 눌렀을 때 LED가 켜지는 것을 확인한다.

led off led on