Posted by 구차니

좀더 hal 코드를 써서 고생을 해봐야하나..

아무튼, 간단하게  float input 으로 바꾸기 위해 input mode로 바꾸고

output mode로 바꾸고 나서는 출력을 써줘야 된다.

#define BUF_SIZE 50
uint8_t usb_buf[BUF_SIZE];
uint32_t count = 0;
#if 1
int prev_val = 0;

// STM32F1: 4 bits per pin (CNF[1:0] MODE[1:0]) in CRL (pins 0-7) / CRH (pins 8-15)
static inline void pin_set_cfg(GPIO_TypeDef *port, uint16_t pin, uint32_t cfg)
{
    uint32_t num = __builtin_ctz(pin);
    uint32_t *reg = (num < 8U) ? &port->CRL : &port->CRH;
    uint32_t pos = (num % 8U) * 4U;
    *reg = (*reg & ~(0xFU << pos)) | (cfg << pos);
}

static inline void pin_hiz(GPIO_TypeDef *port, uint16_t pin)
{
    pin_set_cfg(port, pin, 0x4U);  // CNF=01 MODE=00: floating input (Hi-Z)
}

static inline void pin_output(GPIO_TypeDef *port, uint16_t pin)
{
    pin_set_cfg(port, pin, 0x2U);  // CNF=00 MODE=10: push-pull output, 2 MHz
}

void gpio_proc()
{
  int val = 0;
  // row
  // val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) << 4);
  // val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) << 5);
  // val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) << 6);
  // val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) << 7);

  char *swname[4][4] = {
    {"S1", "S2", "S3", "S4"},
    {"S5", "S6", "S7", "S8"},
    {"S9", "S10", "S11", "S12"},
    {"S13", "S14", "S15", "S16"}
  };

  for(uint16_t row_idx = 0; row_idx < 4; row_idx ++)
  {
    uint16_t pin_arr[] = {GPIO_PIN_4, GPIO_PIN_5, GPIO_PIN_6, GPIO_PIN_7};
    pin_output(GPIOA, pin_arr[row_idx]);
    HAL_GPIO_WritePin(GPIOA, pin_arr[row_idx], GPIO_PIN_SET);
    
    HAL_Delay(1);

    // column
    val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) << 0);
    val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) << 1);
    val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) << 2);
    val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) << 3);

    // HAL_GPIO_WritePin(GPIOA, pin_arr[row_idx], GPIO_PIN_RESET);
    pin_hiz(GPIOA, pin_arr[row_idx]);

    int col_idx = 0;
    for(int col_idx = 0; col_idx < 4; col_idx++)
    {
      if((val >> col_idx) & 0x01)
      {
        char *name = swname[row_idx][col_idx];
        sprintf((char*)usb_buf + strlen(usb_buf), "%s ", name);
      }
    }

    val = 0;
  }

  sprintf((char*)usb_buf + strlen(usb_buf), " --- %d %X\r\n", count, val);
  CDC_Transmit_FS(usb_buf, BUF_SIZE);
  memset(usb_buf,0,BUF_SIZE);
  count++;

}
#endif

 

전에는 이건 되었는데

 

요건 안되었었는데 input mode로 바꾸고 나서 잘 된다.

 

 

+

S1 / S4 / S16을 눌렀는데 S13 가 눌린걸로 인식되는건 다이오드 달아야지 머..

 

 

+

2026.09.15

클로드 님의 말

ra4~7(row) 는  open drain / level high

pa0~3(col) 은 input / pull up 설정

row 에서 set - hiz, reset - low 구동으로 된다고

대신 pull up  이라서 col 을 읽을때 논리가 반대가 된다는데

레지스터 바꾸면서 바쁠것 보다는 이게 낫지 않나 생각이 된다. (바꿀게 적으면 클럭이 낮아도 빠른 스캔을 유지할테니까)

근데.. od랑 input pull up이랑 어떻게 되는지 좀 공부 해야 할듯..

 

+

2026.09.16

gpt 조언

col 쪽에 전부 pull up/

row쪽은 Open drain output 으로 설정

 

Posted by 구차니

먼가 이해가 안되서 끄적끄적

row 0(윗줄)에 high로 흘리고

col 0 / col 1 에서 읽으면 키를 눌러서 연결되어있으니 둘 다 읽히고

 

row 1(아랫줄) 을 읽기 위해서 row 0을 low로 하고 row 1을 high로 하면

row 0, col 1 과 row 1, col 1이 전기적으로 이어지면서 row 1의 전기가 row 0로 넘어가게 되고

row0 를 타고 col 0에 들어가서

눌리지 않은 row 1, col 0이 눌린것으로 오인식되게 된다.

 

신기하네..

그래서 다이오드 쓴다고.

 

얘는 누르지 않아는데 눌린걸로 착각하는 "고스팅"

얘는 스캔라인이 다른데 두개 누르면 안눌린걸로 착각하게 되는 현상인데.. 이건 딱히 용어가 없네

잘은 모르겠지만.. col 쪽 gpio의 threshold를 넘길수 없어서 안눌린걸로 인식되는걸까?

다른 row는 0으로 되어있으니 다른쪽으로 쭈르르르륵 다 빨려들어가서 0으로 되거나?

+

GPT 말로는 2 key roll over / masking 이라고 표현한다고 하는데.. 맞나?

그리고 gpio를 row에서 low/high 값 대신 high-Z(init) / high로 해보란다.

레지스터 직접 건드리면 init까진 아니어도 된다는데 CRL 레지스터에 쓰면 된다고 한다.

 

블로킹은

소스코드(그러니까 작동 알고리즘상)에서 고스팅을 방지하기 위해서 어떤 키가 잘못 눌리는지 판단해서 차단해버리는거

여긴 진짜로 눌렀는데 고스팅 처리에 의해서 막혀서 안눌리게 되는걸 의미하는 듯.

Posted by 구차니
Posted by 구차니

키보드 외관 형태

- 대부분 곡면인데 그냥 평면에 배치

- v자가 되어도 되지만 반대로 왼손만 올라가고 오른손은 평행 유지 컨셉

 

마우스 (빨콩)

- 중간에 빨콩 같은거 있음 좋겠음. 어짜피 벌어져서 공간이 남으면 빨콩대신 조이스틱 최대한 작은거 넣어도 될 듯

- 빨콩처럼 스페이스 아래쪽에 빨콩을 위한 마우스 버튼

- 휠 클릭은 3버튼으로

 

키 배치

- 풀키에 가깝게

    - 과감하게 insert / home / pgup / del / end / pgdn / arrow * 4 를 제거하고

    - 키패드 위에 prtsc / scroll / pause를 배치

- 체리 키보드에서 numlock 위 계산기 버튼 편한데 등록 가능하게? (창내리기 라던가 특정 프로그램 실행이라던가?)

- 윈도우 키 필수! 좌 ctrl / win / alt 우 alt / fn / ctrl

- shift-f10으로 대체되는 우클릭 버튼은 일단 난 잘 안쓰니까 배제

- 키 폭이 1.0, 1.5, 2.0 2.5로 있는데 단계를 좀 줄일까?

    - 쉬프트는 좌우 위치 배치에 따라선 2.5를 없애도 될 듯

- 키패드 5 번에 모드에 따라서 arrow 할당?

 

가변(!)

- F4~F5 사이에 기구를 추가하여 붙여서도 V자로 꺾을수도 있게. 양쪽을 잇는 케이블 정도는 넘길 수 있도록

- 베어링 쓰지 말고 힌지처럼 외부 지지하는 부분에서 걲이게 하고,

- 어느정도 뽑아낼수 있는 구조로 해서 땡기도 꺾으면 무리없을듯? (내구도 제외)

- 하단에는 자석을 통해서 고정되는 구조로 붙으면 땅기기 전에는 빠지지 않게?

 

스캔

- 4 x 5 배열로 5구획 스캔? 4x5x5

 

과거 AT 시절 레이아웃. 백스페이스 왼쪽에 역 슬래시가 위치한다.

[링크 : https://coolenjoy.net/bbs/46/5971]

 

어짜피 벌어지는거 조이스틱 하나 박는다고 문제 될 건 없잖아? ㅋㅋㅋ

[링크 : https://reuno21.tistory.com/107]

Posted by 구차니