EXTI6 / Hall User Description

공식 AFIO source 선택과 EXTI edge·mask·pending 흐름을 현재 구현의 AFIO_EXTICR2.EXTI6=0000 → PA6 / HALL_IN → EXTI6 경로와 연결합니다. Hall 전기 입력은 외부 3.3 V pull-up을 둔 open-collector 출력으로 해석합니다.

1. 그림에서 먼저 보기

Figure 1의 번호는 아래 표의 같은 번호 행으로 이어집니다. 이 EXTI 문서는 GPIO source → edge/SWIER request → IMR → PR → handler interrupt branch와 EMR → pulse generator → Event branch를 설명합니다. 현재 구현은 그중 PA6 rising edge → RTSR.TR6 → IMR.MR6 → PR.PR6 → EXTI6_IRQHandler subset을 실행합니다.

RM0008-style EXTI interrupt and event controller architecture 1 2 3 4

Figure 1. RM0008-style EXTI interrupt/event controller architecture

RM0008 Rev 21 Figure 20과 EXTI register 설명을 바탕으로 직접 생성한 래스터 재구성입니다. 이 문서의 interrupt branch는 selected trigger request가 IMR을 통과해 PR pending latch를 세운 뒤 handler로 이어집니다. PRx에 1을 쓰면 latched request가 해제됩니다. EMR event branch는 pulse를 만들지만 PR을 거치지 않습니다.

Official AFIO EXTICR2 EXTI6 source selection and implemented Port A PA6 route

Figure 2. 공식 EXTI6 source selection과 현재 Trainer의 PA6 선택값

RM0008 Rev 21 Figure 21과 AFIO_EXTICR2[11:8] (EXTI6[3:0])을 재구성했습니다. GPIO EXTI mapping은 pin index와 line index가 같고, 각 line에는 한 port source만 선택됩니다. 따라서 EXTI6에 PA6·PB6·PC6를 동시에 연결할 수 없습니다. 현재 Trainer는 AFIO_EXTICR2를 노출하며 EXTI6=0000일 때 PA6 / HALL_IN route를 실행합니다.

핵심: MR6, TR6, PR6의 숫자 6은 모두 EXTI line 6을 뜻합니다. 이것만으로 PA6라고 판단할 수는 없습니다. PA6 선택의 근거는 현재 실행 가능한 AFIO_EXTICR2.EXTI6[3:0] = 0000입니다.

그림 구간공식 RM0008 흐름현재 구현 해석
Input sourcePxN → AFIO_EXTICRx → EXTIN. Pin index와 EXTI line index는 같고, line마다 한 port만 선택합니다.AFIO_EXTICR2.EXTI6=0000이면 PA6 → EXTI6 → HALL_IN이 실행됩니다. 다른 port code는 공식 reference 값이지만 현재 Hall source는 만들지 않습니다.
Edge / software requestRTSR과 FTSR이 transition을 선택하고 SWIER request와 OR됩니다. 선택한 transition마다 한 번 요청하며 HIGH level 유지만으로 반복 요청하지 않습니다.Hall rising edge만 effect를 만들고, FTSR은 저장·표시만 하며 SWIER는 노출하지 않습니다.
Interrupt branchrequest → IMR → PR → handler. IMR이 0이면 이 branch를 통과하지 않아 PR도 이 경로로 set되지 않으며, PR은 write-1-to-clear입니다.PR6를 set한 뒤 EXTI6_IRQHandler compatibility hook을 직접 dispatch합니다.
Event branchrequest → EMR → pulse generator → Event. Event-only 요청은 PR을 거치지 않으며 IMR branch와 동시에 enable할 수 있습니다.EMR, pulse generator와 Event output은 모델링하지 않습니다.
Register interface / lane widthAMBA APB bus ↔ Peripheral interface를 PCLK2가 구동합니다. /19는 EXTI0..18의 19개 병렬 lane이며 connectivity-line device만 EXTI19를 추가합니다. RCC에는 별도 EXTIEN이 없습니다.EXTI register는 MMIO로 접근합니다. AFIOEN과 IOPAEN은 upstream source/configuration prerequisite이며 EXTI 자체 enable bit가 아닙니다.

2. 블록 → 레지스터 비트

그림 블록레지스터필드 / bit그림에서 하는 일 / 값 의미지원 여부
1Figure 1 rising trigger selection
Rising-edge selectorEXTI_RTSRTR6[6]그림에서: EXTI6 입력의 low-to-high edge를 selected trigger request로 보냅니다.0 = rising trigger 비활성화1 = rising trigger 활성화현재 Hall pulse가 pending으로 이어지려면 TR6가 1이어야 합니다.지원됨
2Figure 1 falling trigger selection
Falling-edge selectorEXTI_FTSRTR6[6]그림에서: EXTI6 입력의 high-to-low edge를 selected trigger request로 보냅니다.0 = falling trigger 비활성화1 = falling trigger 활성화현재 구현은 값을 저장하고 Registers에 표시하지만 Hall count와 pending 생성은 rising edge만 사용합니다.미지원
3Figure 1 interrupt mask gate
Interrupt request gateEXTI_IMRMR6[6]그림에서: selected EXTI6 trigger request가 pending latch로 들어갈지 결정합니다.0 = line 6 interrupt request mask1 = line 6 interrupt request unmask현재 구현에서도 MR6가 0이면 Hall rising edge가 PR6를 set하지 않습니다.지원됨
4Figure 1 pending latch and clear command
Pending stateEXTI_PRPR6[6]그림에서: unmasked selected trigger request가 발생했음을 pending state로 보관합니다.0 = line 6 pending 없음1 = line 6 pending 있음현재 구현은 active Hall rising edge에서 PR6를 set한 뒤 compatibility handler를 호출합니다.지원됨
Write-1-to-clear commandEXTI_PRPR6[6]그림에서: pending state를 지우는 software write command입니다.0 write = pending state 변화 없음1 write = PR6 pending clearEXTI->PR = EXTI_PR_PR6처럼 대입하며 read-modify-write clear를 가르치지 않습니다.지원됨
5Figure 2 EXTI6 input source selection
Port source selectorAFIO_EXTICR2EXTI6[3:0] / bits [11:8]그림에서: EXTI line 6에 연결할 GPIO port를 한 개 선택합니다.0000 = PA60001 = PB60010 = PC60011..0110 = PD6..PG6, 해당 package 존재 여부 확인현재 Trainer는 field read/write를 지원하고 0000일 때만 motor-integrated Hall source를 PA6/EXTI6에 연결합니다. 다른 port 선택값의 외부 pulse source는 Reference-only입니다.지원됨

3. 표 기준 단순 코드

현재 코드 / 값데이터시트 필드로 해석화면에서 확인
RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAENRCC_APB2ENR.AFIOEN[0] = 1, IOPAEN[2] = 1: 현재 EXTI/GPIOA route prerequisiteRegisters → Clock
GPIOA_CRL[27:24] = 0x4CNF6[27:26] = 01, MODE6[25:24] = 00: PA6 floating digital inputRegisters, Board · Lab pin routes
AFIO->EXTICR[1] &= ~(0xFu << 8)AFIO_EXTICR2.EXTI6[3:0] = 0000: PA6를 EXTI6 source로 선택Registers의 AFIO_EXTICR2와 Board PA6/HALL_IN route
EXTI->RTSR = EXTI_RTSR_TR6EXTI_RTSR.TR6[6] = 1: rising trigger 선택Registers, Graph
EXTI->IMR = EXTI_IMR_MR6EXTI_IMR.MR6[6] = 1: interrupt request unmaskRegisters, Code Watch
exti_pr_before_clear = EXTI->PREXTI_PR.PR6[6] = 1 상태를 W1C command 전에 보존Code Watch
EXTI->PR = EXTI_PR_PR6EXTI_PR.PR6[6] write-1-to-clear commandRegisters, Docs / Log
EXTI_EMR / EXTI_SWIER공식 event gate와 software-trigger register현재 header/MMIO에는 없으며 Figure 1과 경계 표에서만 확인

4. 실행해 보기

FW EDIT에 붙여넣고 BUILD 후 START합니다. EXTI 설정만으로 Hall edge가 생기지는 않으므로, 이 예제는 Hall source를 만들기 위한 현재 구현 전용 전제 조건으로 0/3.3 V TIM2 PWM과 PA3 driver enable도 함께 켭니다. PA2/CCR1 fixed PWM alias는 공식 PA2 timer mapping이 아니며 TIM2/PWM User Description의 경계를 따릅니다. 여러 tick 뒤 HALL_COUNT와 hall_irq_count가 함께 증가하는지 확인합니다.

#include "training_api.h"

volatile uint32_t hall_irq_count = 0u;
volatile uint32_t exti_pr_before_clear = 0u;

void user_init(void)
{
    trainer_clock_init_72mhz();
    RCC->APB2ENR = RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN;
    RCC->APB1ENR = RCC_APB1ENR_TIM2EN;

    /* PA2 PWM, PA3 driver enable, PA4 direction, PA6 Hall input. */
    GPIOA->CRL = 0x44422200u;
    AFIO->EXTICR[1] &= ~(0xFu << 8); /* EXTICR2.EXTI6=0000: Port A */
    TIM2->PSC = 11999u;
    TIM2->ARR = 99u;
    TIM2->CCR1 = 70u;
    TIM2->CCER = TIM2_CCER_CC1E;
    TIM2->CR1 = TIM2_CR1_CEN;
    GPIOA->BSRR = GPIOA_DRV_EN_BIT;

    EXTI->IMR = EXTI_IMR_MR6;
    EXTI->RTSR = EXTI_RTSR_TR6;
    EXTI->FTSR = 0u;
    EXTI->PR = EXTI_PR_PR6;
}

void EXTI6_IRQHandler(void)
{
    if ((EXTI->PR & EXTI_PR_PR6) != 0u)
    {
        exti_pr_before_clear = EXTI->PR;
        hall_irq_count++;
        EXTI->PR = EXTI_PR_PR6;
    }
}

void user_loop(void)
{
    watch_u32("HALL_COUNT", HALL->COUNT);
    watch_u32("hall_irq_count", hall_irq_count);
    watch_u32("exti_pr_before_clear", exti_pr_before_clear);
}

5. 사이트에서 확인

6. 현재 구현 범위

항목공식 STM32 의미현재 구현 범위지원 여부
AFIO_EXTICR2[11:8] (EXTI6[3:0])EXTI6 source port를 PA6, PB6, PC6 등에서 선택header/MMIO/register read-write가 지원됩니다. 현재 motor Hall runtime은 0000 = Port A에서만 PA6 / HALL_IN edge를 연결하며 다른 port의 외부 source는 모델링하지 않습니다.지원됨
EXTI_FTSR.TR6[6]falling edge trigger 선택값은 저장·표시되지만 Hall pending/count effect는 rising edge만 실행합니다.미지원
EXTI_EMR / EXTI_SWIERevent pulse gate와 software trigger command공식 offset 자리는 C pointer struct에서 reserved로 유지되지만 실행 register로 노출하지 않습니다.미지원
EXTI6_IRQHandler현재 구현 전용 compatibility handler nameactive MR6/TR6 route에서 PR6가 pending이면 직접 dispatch합니다.지원됨
GPIOA_CRL / GPIOA_IDR / RCC_APB2ENRPA6 input mode, live IDR6와 AFIOEN·IOPAEN clock prerequisitesAFIOEN·IOPAEN은 실제 route gate입니다. GPIO는 정확한 0x4뿐 아니라 output이 아닌 mode를 input으로 인정하고, IDR6 level은 virtual Hall source가 board-driven으로 갱신합니다.지원됨
HALL_COUNT / HALL_STATUSSTM32F103 EXTI register map 밖의 구현 전용 telemetryCOUNT는 active route에서 본 rising edge 수입니다. STATUS bit 0은 level, bit 1은 pending 또는 같은 tick의 rising edge, bit 2는 EXTI6 route active를 뜻하며 STATUS는 read-only입니다.지원됨
PA2 / TIM2_CCR1 / PA3Hall edge source를 만드는 구현 전용 motor prerequisitePA2/CCR1 fixed PWM alias와 PA3 driver enable로 virtual motor를 움직입니다. EXTI 공식 설정 순서가 아니며 TIM2/PWM companion의 구현 경계입니다.지원됨
PA6 Hall electrical inputDS5319의 PA6는 FT pin으로 표시되지 않으므로 5 V를 직접 인가하지 않아야 함현재 회로 계약은 motor-integrated Hall의 open-collector 출력을 외부 3.3 V pull-up으로 받아 LOW/3.3 V를 PA6에 입력합니다. 12 transitions/rev와 45 rising pulses/stroke는 특정 Hall 부품 데이터시트 값이 아니라 Trainer 운동 모델 가정입니다.지원됨