태그 보관물: 라즈베리파이 피코

[RPI-PICO] 오디오 쥬크박스 만들기 2

이전글들

우선 하드웨어 구성은 아래와 같습니다.

Waveshare Pico-Audio original revision
Waveshare Pico-LCD-1.44
Raspberry Pi Pico
microSD Card Adapter
Waveshare Expander Quad

이중에서 Pico-Audio는 I2C 연결
Pico-LCD-1.44는 SPI 연결
microSD Card Adapter도 SPI 연결이구요

라즈베리파이 피코가 SPI 채널이 두개라, 잘 안겹치게 배정해서 소스코드에 기재하면 됩니다. Expander를 쓰기 때문에 하드웨어적으로는 일단 조정을 잘 안해도 되고 다만 microSD Card Adapter의 경우 핀 구조상으로 Expander에 못끼우기에 점퍼케이블을 female to female로 연결해야 하네요.

본래 Expander Dual을 썼는데 모듈을 하나 더 달아야 해서 Quad로 바꾼 것도 특기해야 합니다.

일단 기존의 샘플 코드를 분석해서 흐름을 꿰찰려고 했는데요. Pico-LCD-1.44의 네개 버튼 시연 코드를 일부 떼어내어 가져와서 메뉴를 구성하고 키값을 구해서 눌린지 확인하는 조건문 코드 안에 Pico-Audio 시연 코드에 들어있는 톤 재생 코드를 두니 버튼 누르면 재생이 되었습니다.

그러나 같은 키를 한번 더 누르면 멈추게 하는 것을 살펴봐야 했고, 이는 제작사에서 제시한 라이브러리로 가능한데요. 음질의 경우 톤으로 내는 것은 소스코드에 텍스트 정보로 톤 정보로만 저장되어 재생되는 구조라 음질이 조금 좋은 부저 정도라, MP3 정도는 되어야 하기에 그만두고 microSD Card Adapter를 구해서 연결해보았습니다. microSD 카드에 MP3를 저장해서 불러오는 용도였죠.

microSD 카드는 킹스턴 제품으로, SDHC class 10 UHS-I 지원 제품인데요. 어떤 이유로 인해 FatFS를 사용하는 모든 기존의 프로젝트에서 f_mount() 실행시 error: physical drivce does not work 같은 오류가 나면서 마운트에 실패합니다.

몇가지 이상 증상은

  • LED 점멸로 상태작동을 보여주는 기능이 작동하다가 안하다가 하는데 무조건 마운트 실패
  • BOOTSEL 연결시 PC에 30초 가량 딜레이가 발생하면서 마우스 커서 버벅임
  • 라즈베리파이 피코 내장 플래시가 2MB인데, 무려 127MB로 60배가 뻥튀기되어 보임
  • 아무런 파일도 기록이 안되던 microSD 카드에 이상한 파일과 디렉토리가 발견

인데요.

뭔가 이상해서 macOS에서도 해보니 똑같이 f_mount()에서 안돕니다.

아무래도 FatFS에서 내부적으로 쓰는 코드 중에 SPI 핀과 SD 카드 명세는 잘 해놨어도 ff.c 같은 파일에서 지정하는 매크로 상수를 튜닝해야 제가 쓰는 microSD 카드와 호환된다는 것 같았는데 위 증상을 보면 석연치 않지만, 일단은 프로젝트 저자들도 SD 카드 브랜드가 문제라고 하기도 하네요. 잘 생각해보면 브랜드마다 사양도 다르고, 특히 블락 크기 설정 같은 설정도 잘 살펴서 해야 할 것 같습니다.

그래서 우선 재껴두고 집에 있는 USB 메모리를 달아 해보려고 하는데요. 라즈베리파이 피코의 USB 단자에 USB 메모리를 장착하고, Expander Quad에 별도로 있는 USB 단자로 전원공급을 해서 해볼 생각입니다. 라즈베리파이 피코를 MSC 호스트로 두고 해보는 것이죠. TinyUSB로 비슷한 작업을 하는게 되던데 잘 살펴보고 있습니다.

일단 USB 표준부터 보고 있고 단행본 입수전에 연구논문과 학위논문을 찾아서 일반적인 해설을 한 부분을 집중해서 보려고 하네요.

FatFS가 작동하면 128kbps 44.1kHz MP3 파일을 네개 저장해서 불러와서 LCD의 키로 메뉴 선택후 I2S로 재생하는 것을 할 것입니다.

FatFS로는 일단 집에 있는 USB 메모리로 해보고, 시간이 가면 microSD 카드를 최대한 작은 용량으로 오래전 사양으로 맞추어보려고 합니다. 둘다 안되면 FatFS 소스코드를 뒤적여서 하드웨어 명세를 맞추어줘야죠.

오디오 재생은 제가 쓰는 Pico-Audio original revision이 PCM5101A를 디코더로 쓰는데요. 32비트 384kHz까지 감지한다고 되어 있고 다이나믹 레인지가 106dB입니다. 44.1kHz 128kbps MP3 재생에 지장이 없습니다. 라즈베리파이 피코 C SDK에 포함된 USB 사운드 카드 모드로 돌려보면 음질이 좋습니다.

일단 USB MSC부터 살펴보면서 공부한 것을 정리해서 올리겠습니다.

[RPI-PICO] 라즈베리파이 피코의 USB 단자를 통한 Virtual COM Port 시리얼 모니터 사용법

vscode에 Raspberry Pi Pico 확장기능이 잘 설치되어 있다는 가정 하에 진행합니다. (특히 Serial Monitor)

우선 CMakeLists.txt에 아래 코드를 추가합니다

이 코드는 USB에 stdio를 허용하고 UART에는 비허용하는 코드입니다.

그리고 C 코드의 main() 함수에 아래 코드를 추가합니다.

이렇게 해두고 컴파일해서 uf2를 라즈베리파이 피코에 심습니다.

vscode에서 시리얼 모니터를 열고 Toggle Sent Message Echoing 버튼을 누르고 Start Monitoring 버튼을 누릅니다. 그러면 라즈베리파이 피코가 USB에 연결된 상태라면 BOOTSEL이든 일반 연결 모드든 위에 printf()문으로 보낸 정보가 시리얼 모니터에 뜹니다.

처음 연결했다면 printf() 문이 이미 실행되고나서 시리얼 모니터가 켜졌을때 표시가 안될 수 있으니, Toggle Sent Message Echoing을 켜고 Start Monitoring 상태에서 USB를 뺏다 꽂으면 됩니다.

이를 잘 활용하면 함수 실행 결과를 받아와서 조건문으로 검사하고 오류가 난 것을 보여줄 수 있습니다.

[RPI-PICO] 오디오 쥬크박스 만들기 1

라즈베리파이 피코로 쥬크박스를 만들어보려고 합니다. 하드웨어 구성은 살펴볼 필요가 없이 아래처럼 조합했습니다.

라즈베리파이 피코 (RP2040)
Waveshare Pico-LCD-1.44
Waveshare Pico-Audio
Waveshare Dual GPIO Expander

이구요.

https://www.waveshare.com/wiki/Pico-LCD-1.44
https://www.waveshare.com/wiki/Pico-Audio

에서 사양과 해설이 나옵니다. 라이브러리도 제공되네요.

LCD 모듈은 SPI 연결이고 TFT-LCD라고 되어있구요. 스위치가 제공되어 메뉴에서 항목 선택시 해당 기능을 실행하게 하는게 가능합니다. 쥬크박스 메뉴 표시와 선택기로 쓸 것이구요. 라이브러리가 잘 되어 있어서 LCD 구동후 표시한 메뉴에서 스위치문으로 신호를 받아 메뉴가 구현됩니다.

오디오 모듈은 I2C 연결이구요. PCM5101A 디코더가 탑재되어 있습니다. 32비트 384kHz의 사양에 다이나믹 레인지가 106dB이네요. 오디오 모듈 상품에 스피커가 포함되어 있습니다.

둘다 전원은 따로 연결하지 않고 라즈베리파이 피코와 연결된 핀으로 받는 것 같은데 자세한 것은 생략합니다.

우선 PCM 원리를 해설하고 들어가겠습니다.

우리 주변의 소리는 아날로그입니다. 음악소리가 스피커에서 나온다든지, 천둥 소리가 들린다는 것은 아날로그 형태의 음압이 발생해서 사람의 귀로 들어가 뇌가 인식하는 것입니다.

음압을 매질이 진동한다고 보면 파형이 되어 그래프처럼 표현하는게 됩니다.

아날로그 소리는 그래프가 매끄럽게 연결된 상태로 그려지구요. 이를 디지털 기기에서 처리할때는 샘플링이라고 해서 표본값을 얻어내서 좌표에 점찍고 처리가 되는 것으로 유비가 됩니다.

우리가 수학시간에 배웠던 것처럼 그래프를 그릴때 함수값에 따라 얻어진 변화값을 구해서 그래프 용지에 찍고나서 이들을 연결하라고 하죠? 이 연결 전의 점을 얻어내는 변화값 추출이 샘플링이고, 이를 이어주는 것이 고음질로 되는 비법입니다.

진폭을 Y축으로 시간을 X축으로 두고 파형을 그렸을때 1초의 소리 신호를 Y축에 따라 높낮이가 그려지는데요. 이때의 소리 신호를 1초에 몇개의 샘플로 얻어내는지에 의해 그래프가 더 매끄럽게 되듯이 샘플링 레이트가 중요한 사양이 됩니다.

즉 1초에 44100개의 샘플이 가능하면 샘플링 레이트는 44.1kHz가 되고 48000개로 가능하면 48kHz가 되죠. 이는 디지털화되었을때 아날로그값이 손실되는 정도를 줄여주고, 음질도 향상시켜줍니다. 그래서 오디오 CD와 DVD-Audio를 구분하기도 하네요.

이와 함께 몇비트라고 할때는 양자화 단계를 의미합니다. 8비트 양자화가 되면 2의 8승인 256 단계가 가능해지구요. 16비트는 2의 16승, 32비트는 2의 32승이 됩니다. 비트는 두가지 값만 가능하니 전체 가능한 단계가 비트로 표현되면 2의 멱수가 됩니다. 이역시도 비트수가 높아지면 정밀한 파형이 되어 음질이 좋아지게 되죠.

이를 펄스로 다룬다고 해서 pulse구요.

샘플이 취해지고 양자화가 이루어지면 각 샘플에는 이진수가 주어집니다. 16비트라면 0000 0000 0000 0000에서 1111 1111 1111 1111가 가능해지는데 이게 코드(code)입니다.

즉 PCM(pulse code modulation)은 소리를 펄스화해서 코드로 바꾸는 변조라는 의미입니다.

이는 ADC(Analog to Digital Converter)로 자연상태의 소리를 디지털화하게 되구요. DAC(Digital to Analog Converter)를 쓰면 음악파일을 스피커로 출력하는 모듈에 채택이 됩니다. 둘다 가진 모듈이 있고 하나만 가진 모듈도 있는 것 같습니다.

사양적으로 32비트, 384kHz를 제공하는 경우에는 이 전체 사양을 다 만족하는 오디오 데이터라고 해도 늘 이 전체를 다 쓰는건 아니구요. 다이나믹 레인지와 필터링, 인터폴레이션, 밴드 리미트 등의 처리를 해야 되는 알고리즘의 특성상, 사양 그대로보다는 입력 데이터와 처리 알고리즘의 특성에 의해 다 쓰이는 것은 아니죠.

다이나믹 레인지는 보통 6dB 마다 1비트씩 는다고 보면 된다는데, 106dB인 경우 대충 17.6 비트네요.

필터링, 인터폴레이션, 밴드 리미트와 같은 기술은 파형으로 다루는 소리 데이터에 노이즈를 적게 하는 용도로도 쓰이고, 파형 자체를 증폭하거나 커트해야 할 필요에 의해 제정된 기술인데 이게 제작사의 기술력과 관련이 있네요.

PCM5101A 데이터시트에 나온 사양도 이로부터 이해가 됩니다.

일단 이론 공부는 대충 이렇게 해두구요. 조만간 코딩도 해서 올려보겠습니다.

제작사에 문의해보니 제가 구한 제품이 rev2.1이라던데 다시 확인해보니 오리지날 리비전으로 밝혀졌습니다.

rev2.1은 시러스로직의 CS4344를 디코더로 쓰고 오리지날 리비전은 텍사스 인스트루먼트의 PCM5101A를 쓰는데요. 이둘이 거의 같아보여도 후자가 사양이 좋습니다. CS4344는 32비트 192kHz까지 감지가 되는 기종이고 PCM5101A는 32비트 384kHz까지 감지가 되는데요. 다이나믹 레인지가 106dB이니 출력되는 음질은 비슷할 수도 있습니다. 물론 여러 변인이 존재하니까요.

리비전 문제로 인해 며칠 확인작업을 했는데, 전에 쓴 글에 문의를 다시 보낸다고 언급했으나 새로 쓴 글에서 언급을 안해두어 인상이 나빠질 듯하여 추가해둡니다.

DAC와 ADC – 디지털화에 대한 이해

현실 세계에서 존재하는 물리량들은 아날로그적입니다. 아날로그라 함은 다시 말해 날 것 그대로의 자연적인 현상이라는 것입니다. 예를 들면 바람의 추운 정도, 열로 나타낼 수 있는 온도, 소리를 내는 음파와 같은 것입니다. 이 아날로그적인 자연 현상을 전자기기에서 의미있게 다루려면 전기적인 신호로 바꾸어야 합니다. 이 과정을 디지털화한다라고 설명합니다.

보통 센서라고 부르는 장비를 써서 아날로그적인 자연 현상을 전자기기에서 다룰 수 있는 데이터로 바꾸어야 하는데요. 여기에 DAC나 ADC가 관여합니다. DAC는 디지털에서 아날로그로 바꾸는 작업이고, ADC는 아날로그에서 디지털로 바꾸는 작업입니다.

흔히 말하는 이산 처리 과정인데요. 자연 현상을 측정한 데이터는 그래프로 보이면 연속적입니다. 주욱 이어지는 데이터의 흐름이죠. 그러나 전자기기는 처리할 수 있는 한도가 있기에 이를 변환하면 수치마다 딱딱 떨어져 있는 형태가 됩니다. 1부터 100까지로 나타난 아날로그 현상을 그래프로 그리면 특정 구간에서 보여지는 값들은 무한히 많은데요. 1부터 2까지에 1.00001, 1.00002, 1.00003, .. 1.000010, … 등으로 매우 촘촘합니다. 그러나 전자기기 내부 작동의 한도에서 이를 최대한 근사치로 변환해서 처리하는데 이를 가리켜 디지털화한다(digit-ization)이라고 하죠. 보통 정수형으로 변환한다고 설명합니다. 근사치지만, 고교시절 그래프를 그리듯이 대략적인 형태는 지속되기에 자연 상태의 데이터를 전자기기에서 다룰 수 있다고 간주하고 처리하는 것입니다.

전자기기의 작동은 기저에서 보면 두가지 작동으로 환원된다고 합니다. 전류가 인가되었음, 전류가 차단됨 이 두가지 상태입니다. 이를 0과 1 또는 1과 0 등으로 규정해서 데이터를 다루죠. 이 체제 내에서 정수도 표현하고 부동 소수도 표현합니다. 이 과정은 MCU의 비트수나 DAC, ADC의 샘플링 정확도에 의해 품질이 결정되는데요. MP3와 같이 44.1kHz, 128kbps 처럼 표시되는 것이 샘플링 정확도로, 소리를 그래프로 나타냈을때 근사치인 숫자로 변환시 얼마나 정밀한지 보는 척도입니다. 위에 말한 1부터 2까지 사이의 값들이 얼마나 촘촘한지를 의미합니다. 44.1kHz 128kbps보다 48kHz 128kbps가 음질이 더 좋다는 것도, 특정 구간의 그래프를 구성하는 숫자 샘플이 더 정밀하다는 것이구요. MCU 비트수와 DAC, ADC 회로의 성능도 결정 조건이 됩니다. 소프트웨어적인 API의 성능도 관건이구요.

이로부터 전자기기가 재현하는 온도 측정의 정확도, 소리 재생의 음질 등이 기술적으로 결정됩니다.

응용 분야는 영상 신호 처리, 음성 신호 처리, 온도 측정 등등으로 심화되죠.

최대한 전자기기가 알아볼 수 있는 근사치로 나타내면서도 원본 아날로그 값과 오차가 적게 하는 것이 디지털화 기술의 성패입니다. 이를 처리하는 것은 회로의 고도화와 처리 알고리즘의 고도화에 의지합니다.

알고 있는 사실을 요약적으로 해설해서 저보다 초보이신 분들께도 이해가 즉시되는 해설은 아니지만 ^^;; 일단 이해는 되실 것입니다. 위에 샘플된 각 수치들이 그래프로 그려져서 그래프 성분들의 복잡도가 단순화되는 것을 시각적으로 보이면 더 와닿는 해설이 되는데 그림판 열기가 싫어서 생략합니다.

라즈베리파이 피코로 구성하는 MP3 재생기도 DAC로 만듭니다. 이진화된 (디지털화된) MP3 음악파일을 읽어들여서 아날로그인 스피커 소리로 내보내는데 중요한 장치입니다.

일단 이정도로 생각난 것을 정리해두겠습니다. 요즘 생계지속용 공부하느라 공학공부는 재껴두었는데 그래도 틈틈히 라즈베리파이 피코 배우는 중입니다. 교재보다가 전에 배운 것이 생각나서 글로 썼는데 아주 대단한 글은 아니지만 일단은 개념 정리는 되었네요. 저를 위해 게시판도 따로 만들어주셔서 회원님들을 존경하고 있습니다. 열심히 하겠습니다.

SPI (Serial Peripheral Interface; 직렬 주변기기 인터페이스) 에 대한 이해

최근 4주간 공부에 임할 의지가 발동하고 글의 의미를 알 수 있는 모드가 이어져서 공부를 이어가고 있습니다. 매형과 매형 친구분들이 조건 형성을 해주시니 이해를 해서 이행안함 상태에서 나와서 IT 공부가 이어집니다. 최근 사흘간은 생계지속용 플러터 소스코드 작성을 했는데 SPI에 대해서도 이해가 되어 글 올립니다. 전번에 질문드린 글에서 시도님께서 추천해주신 SPI에 대한 이해의 심도 형성과 잉크킹님께서 말씀하신 소프트웨어와 하드웨어 사이의 표준과 응용도 자연스럽게 이해하고 있습니다. 저도 토론에서 말씀해주신 것을 이해할 수 있으니 말씀주시면 이해에 조력이 되어주실 것입니다 ^^

SPI는 동기화된 통신이 되는 인터페이스의 하나로, 1979년에 모토롤라에서 발표한 통신 인터페이스입니다. 보통 4개의 와이어로 연결해서 마스터, 슬레이브를 연결하며 콘트롤러가 마스터, 주변기기가 슬레이브입니다.

SPI 버스는 다음과 같은 네개의 라인으로 주고 받습니다. (시도님께서 필수로 알아야 한다고 정성들여 써주셔서 동기 부여가 강하게 되었습니다^^ 감사합니다)

SCLK: 직렬 클락 (마스터로부터 클락 신호가 출력)
MOSI: Master Out Slave In (데이터 신호가 마스터로부터 출력)
MISO: Master In Slave Out (데이터 신호가 슬레이브로부터 출력)
CS / SS: Chip Select, Slave Select (어느 슬레이브에 보낼 것인가 결정)

SCLK는 시스템 클락을 신호로 보냅니다
MOSI는 슬레이브로 신호를 보내는 라인이고 MISO는 마스터로 보내는 라인입니다
슬레이브 선택은 chip select 라인에 의해 됩니다
슬레이브밖에 없는 장치는 MOSI가 SDI (Serial Data In), MISO가 SDO (Serial Data Out) 으로 표기되기도 합니다.

각각의 라인별 기능을 지시하는 다른 약호들은

SCLK = SCK, CLK, SCL
MOSI = SIMO, MTSR, SDI, DI ,DIN, SI
MISO = SOMI, MRST, SDO, DO, DOUT, SO
SS = SSEL, NSS, CS, CSN, CE

입니다.

SPI 통신에 의한 데이터 송수신은 두개의 시프트 레지스터를 통해 환형 버퍼로 이루어집니다. 마스터와 슬레이브가 각각 신호를 8비트로 구성해서 주고받습니다. 이 경우 총 16비트가 쓰입니다. 이 비트들이 시프트되어가면서 전송이 이루어집니다. 비트수는 경우에 따라 달라지기도 합니다.

때로는 Dual SPI인 경우, 전송 비트는 3비트로 된다고도 하는데 전에 소스코드 보던 당시의 의문이 풀렸습니다. 그러나 3비트가 마스터/슬레이브 통신 16비트의 일부분일뿐인지 아니면 전체를 의미하는지는 미상입니다. 지금 공부하려는 LCD의 SPI가 Dual SPI나 Quad SPI가 아니라면, 제가 쓰려고 한 Pico-LCD-1.44 제어와는 상관이 있는지 확인해봐야 합니다. 잉크킹님께서 HW와 SW 구현이 서로 다르다는 것과 관련이 있는 것 같습니다. 저도 눈치를 챘었는데 그 사례가 Dual SPI와 Quad SPI에서 있는 것 같습니다.

신호를 주고 받을때의 동기화는 생성된 클락 라인의 high와 low를 검사해서 데이터 라인에서 값을 읽습니다. 클락을 생성하면 좋은 장점은 클락 배분에 의해 동기화가 된다는 것입니다. 클락 라인을 생성하는 장치는 마스터, 나머지 참여한 기기는 슬레이브 입니다. 클락 신호는 마스터에서만 보내며 마스터에서 데이터 신호를 전송하는 경우 SCLK, MOSI, 데이터 라인을 쓰며 슬레이브에서 전송하는 경우 MISO를 씁니다. SS는 별도의 신호 선을 연결하는 라인인데, 마스터에서 슬레이브로 연결하여 칩에서 어느 슬레이브와 통신할지 결정하는 역할을 합니다.

슬레이브 연결은 SS 마스터 단에 여러개 두고 여러개의 슬레이브를 연결하는 방법도 있고, 이와 다르게 각각의 마스터 단에 하나의 SS만 두고 여러개의 선으로 여러개의 슬레이브에 연결하기도 합니다. 이로부터 1:N 연결이 성립합니다.

응용마다 다르지만 보통 전이중 모드와 4개 와이어로 동기 전송, 프로그래밍 가능한 clock polarity, clock phase를 갖습니다.

때로는 와이어가 3개이기도 하고 여러 기능이 분기됩니다. GPIO에 분배된 기능을 잘보고 케이블을 연결하면 되고, GPIO 익스텐더를 쓰면 일부러 공들여 분별하지 않아도 통신이 가능할 것 같습니다.

아래와 같은 신호 파형 분석과 모드 번호로 상태를 알아볼 수 있습니다.

  • 전이중 통신 = 양방향 동시 송수신 가능 (전화받으면서 듣기와 말하기가 동시에 된다)
  • 반이중 통신 = 단방향 송수신만 가능

일단 인터넷 문서들만 참조해서 기록에 남깁니다.

https://en.wikipedia.org/wiki/Serial_Peripheral_Interface
https://twinw.tistory.com/149
https://gudgud.tistory.com/30
https://www.hardcopyworld.com/?p=2778
https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi/all
https://www.analog.com/en/analog-dialogue/articles/introduction-to-spi-interface.html

[RPI-PICO] pioasm 기능으로 PIO 재프로그래밍하는 작업 순서

라즈베리파이 피코로 PIO 기능을 구현하기도 합니다. PIO는 Programmable Input Output의 약자로 프로그래머가 재량으로 커스텀해서 시스템 내부 버스, GPIO, SPI나 I2C, IRQ, DMA 등과 통신하는 기반을 제공합니다. PIO를 재정의하면 상태 기계가 만들어지고 이 상태 기계 상태를 얻어와서 C나 C++, 파이썬 등에서 함수 호출을 해서 쓸 수 있습니다. 이를 위해서는 우선 피코 C SDK가 잘 설정되어 있어야 하구요. pioasm 이라고 특별한 어셈 명령어 코드를 써서 pio 파일을 만들어야 합니다.

https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf

이 문서에서 319 페이지 (2022년 12월 31일 기준 문서) 를 보면 인스트럭션 명령어 코드가 나와있고 예제도 있으니 참고하시길요.

우선 아래와 같은 순서로 작업합니다.

(1) 같은 파일 내에 pioasm 코드와 C SDK 함수 정의
(2) CMakeLists.txt에 pico_generate_pio_header() 함수로 (1) 파일 기재
(3) 독립된 C 프로그램 소스코드에 (1)과 (2)로 만든 헤더 파일 인클루드후 함수 호출

pioasm 코드는

으로 시작하구요.

위 링크에 링크한 문서에 나온 명령어 코드를 씁니다. 어셈 코드 아래에 C 코드도 추가해야 하구요.

처럼 { } 블럭 안에 초기화 함수를 써넣는 구조입니다.

digikey의 소개는 대충 이렇습니다. 파일명 (blink.pio)

중요한 것은 .wrap_target 과 .wrap 으로 감싼 pioasm 코드가 기본 베이스가 되고, %c-sdk 에 기재한 함수를 독립된 C 소스코드에서 불러와서 쓰는 구조입니다. 특기할 것은

에서 대입되는 함수인 blink_program_get_default_config() 는 .program 구문에 기술한 이름대로 자동 생성됩니다. 프로그래머는 일단 위에 명세대로 소스코드를 짜서 컴파일하면 됩니다.

위 blink.pio 코드를 활용하려면 C 헤더로 만들어야 합니다. 이를 위해서는 CMakeLists.txt 에

처럼 설정해두어야 하는데요. 중요한 부분은 헤더를 가져와서 쓰는 파일을 main.c로 간주한다면

처럼 add_executable() 에 기재하고, 헤더롤 만들 PIO 파일은 (맨 위에 게시한 pioasm 파일을 blink.pio로 간주합니다)

처럼 pico_generate_pio_header() 에 기재해야 한다는 것이죠. 이렇게 설정해두고 main.c까지 작성후 컴파일하면 헤더 파일이 생성됩니다. (blink.pio.h) 이 헤더를 가져와서 쓸 C 파일에서 (이 경우 main.c)

처럼 헤더를 불러와서 %c-sdk { } % 블락안에 기재한 함수를 호출합니다. 아래처럼 합니다.

위 코드에서 중요한 부분은

로 헤더 파일을 가져오고

로 pio 파일에서 정의한 함수를 호출한다는 것입니다.

이렇게 하고나서 cmake와 make 명령어로 빌드하고 롬에 심으면 실행됩니다.

프로그램 소스코드는 digikey에서 가져왔네요. 귀차니즘이라 일단 작동함을 확인하고 씁니다. 이게 예제에서는 LED 점멸인데, led_pin을 다른 GPIO로 설정해서 부저 울림 등도 가능합니다. 같은 코드로요.

https://cdn-learn.adafruit.com/downloads/pdf/intro-to-rp2040-pio-with-circuitpython.pdf

이 링크에 pioasm 관련 해설이 잘 나와있습니다. 파이썬용이지만 어셈 코드는 같으니 참고하시길요.

[라즈베리파이 피코] 라즈베리파이 피코 패시브 버저 음계 출력 성공

https://github.com/ShellAddicted/PicoPWM 에서 올라온 소스코드를 보고 구조를 짰습니다. 그런데 해당 코드에서 주파수 생성부분에서 큰 소리가 안나고 딕딕 거리면서 프로그램이 종료되는 문제가 있어 기본 함수 틀은 유지한 상태에서 주파수 생성 코드만 전번에 단일음 내는 것으로 바꿨습니다. 아래와 같은 코드구요.

이를 컴파일해서 피코 보드 롬에 올리니 연주가 아주 잘 됩니다.

영상은 이렇습니다.

빵판 설비는 단일음 낼때와 같이 했네요.

잘 되니 기분이 좋습니다. 빵판 설비가 잘 되니 코드는 그저 하루에 반나절 정도면 되는군요. 물론 쉬운 프로젝트라서 그런 것 같습니다.

우선 폴링 개념을 찾아보니 sleep_ms() 함수를 쓰면 된다기에 해보니 되네요. 참고가 잘 되었습니다.