페이지

글목록

2016년 5월 27일 금요일

[PSOC] PSOC4 AUDIO IC(ISD21xxx) 동작 테스트

예전에 올려 보려고 한 AUDIO 출력 IC 입니다.

PSOC4로 제어해 봤는데, 다른 CPU로도 간단하게 제어 가능한 IC 입니다.

예전에 AUDIO IC에 대해 아무런 지식이 없어서, wave 파일을 raw 데이터로 SPI로 샘플링 주파수를 설정하고 
밀어 넣으면 동작할 것이라 생각하고 wave 파일 구조를 공부해서 정리했었는데 그렇게 제어하는 것이 아니였습니다. ㅜㅜ

괜한 3일을 날려 버렸던 놈인데, 아주 간단히 제어하는 놈이었습니다.

메뉴얼을 제가 이해를 잘 못 한 것도 있지만, 많이 부실하기도 했고요.

ISD2130 AUDIO IC는 SPI로 데이터를 실시간으로 전송하면서 제어할 수 없는 IC라고 합니다.(저는 메뉴얼에서 가능하다고 읽었고 sale 하는 분이 안된다고 해서 더 이상 진행은 않했습니다)

사용 방법은 다음과 같습니다.
1. 내부에 메모리가 있어서 먼저 SPI 통신으로 AUDIO 데이터를 내부 메모리에 USB 전송 툴로 Write 한다고 합니다.
2. USB 전송툴과 윈도우 프로그램에 의해 각각의 AUDIO 소스마다 VP(Voice Prompt 라고 하네요) INDEX를 부여해 줍니다.
3. ISD2130 IC에 SPI 통신으로 PU(Power Up) -> CFG0 REG(Sampling 주파수 설정) 설정 -> CFG_REG2(Compression Souce) 설정 -> VOLC(Volume Control) -> PLAY VP(Voice Prompt #) -> PD(Power Down) 의 과정으로 스피커로 음원이 출력됩니다.

여기서 한가지 주의할 점은 VOLC 명령은 동작하지 않는다는 점 입니다.
아무리 해도 안되서 연락해서 알아본 결과, WR_CFG_REG 명령을 통해서 우회적으로 VOLC 레지스터를 Write 해야 볼륨을 변경할 수 있습니다.

또, 한가지 주의할 점은 VOLC 레지스터의 값은 0x00 이 최대 볼륨이고 0xFF가 가장 작은 볼륨이랍니다.
이것도 전화 연락해서 알 수 있었습니다.

많이 헤메면서 시간이 좀 걸렸지만, ISD2130 은 꽤 쓸만했습니다. 가격이 600원대에 8KHz 로 샘플링하면 꽤 긴 음성 파일 포함해서 저장된 데이터 38개를 Play할 수 있었으니 부저보다 훨씬 다양한 용도로 저렴하게 사용 가능했습니다.


하드웨어는 SPI로 연결하면 됩니다. 인터럽트 입력은 별로 필요 없고 STATUS READ 명령으로 BUSY를 체크하면 됩니다.


PSOC TopDesign.cysch 탭에서 SPI 콤포넌트를 1개 불러다 놓고, /CS 핀을 1개 불러 놓습니다.
다른 CPU에서도 SPI 통신 레지스터 설정 잘 하시고 함수 불러다 쓰시면 됩니다.
현재 프로젝트에서 SPI 통신 1개에 4가지가 연결되어 있어서, 대표적인 Device 이름을 따서 SPI 콤포넌트 이름을 SPIFLASH 로 했습니다. AUD_RDY 핀은 만들어만 놓고 사용하지 않았습니다.



다음은 PSOC4 를 사용할 때, SPI 설정 내용입니다.



버퍼 사이즈는 적당히 조정을 해 주세요. 저는 너무 많이 잡은 듯 합니다.


메인 함수에서 Audio 출력 함수를 사용하는 예는 다음과 같습니다.

main()
{
    SPIFLASH_SCBCLK_Start();
    SPIFLASH_Start();
    CyGlobalIntEnable; /* Enable global interrupts. */

    audio_play(0x21,0x1A);   // 0x21 VP 를 VOLC 0x1A 로 Play
    while(1);
}

다음은 PSOC4 에서의 audio_play 함수 정의 내용입니다.
void audio_play(uint8_t aud_index,uint8_t aud_vol)
{
    uint8_t tx_test_bf[10];
    char tx_buf[100];

    tx_test_bf[0] = 0x10;   // Power up
    SPI_Aud_Write_String(tx_test_bf,1);
    
    tx_test_bf[0] = 0x00;   // CFG_REG0 –Sample Rate Override
    tx_test_bf[1] = 0x60;
    SPI_Aud_Write_String(tx_test_bf,2);

    tx_test_bf[0] = 0xB8;   // Write Config Register
    tx_test_bf[1] = 0x03;   // VOLC : 11.3.4 VOLC –Volume Control
    tx_test_bf[2] = aud_vol;
    SPI_Aud_Write_String(tx_test_bf,3);
/*    
    tx_test_bf[0] = 0x03;   // VOLC : 11.3.4 VOLC –Volume Control
    tx_test_bf[1] = 0xFF;
    SPI_Aud_Write_String(tx_test_bf,2);
*/
    tx_test_bf[0] = 0x02;   // CFG_REG2 –Compression Source
    tx_test_bf[1] = 0x44;
    SPI_Aud_Write_String(tx_test_bf,2);
    
    tx_test_bf[0] = 0xA6;   // PLAY_VP
    tx_test_bf[1] = 0x00;
    tx_test_bf[2] = aud_index;         // M_단선bell_2_VP19 19
    SPI_Aud_Write_String(tx_test_bf,3);
    
    tx_test_bf[0] = 0x12;   // Power Down
    SPI_Aud_Write_String(tx_test_bf,1);
    
    while( (SPI_Aud_Read(0x40) & 0x40) == 0);
    sprintf(tx_buf,"Index : [%02X]\n\r",aud_index);
    UART_1_UartPutString(tx_buf);
}


다은은 Audio IC SPI Write 함수 입니다.
void SPI_Aud_Write_String(uint8_t *write_buf,uint8_t cnt_buf)
{
    uint8_t i,dummy;
    AUD_CS_Write(0);
    CyDelay(10);
    for (i=0;i
    {
        SPIFLASH_SpiUartWriteTxData((uint32)write_buf[i]);     // dummy
        while(SPIFLASH_SpiIsBusBusy());
        dummy = (uint8_t)SPIFLASH_SpiUartReadRxData();
    }
    CyDelay(10);
    AUD_CS_Write(1);
}


다음은 Audio SPI Read 함수 입니다.
uint8_t SPI_Aud_Read(uint8_t REG_cmd)
{
    uint8_t rtn_data[10];
    char tx_buf[100];
    AUD_CS_Write(0);
    SPIFLASH_SpiUartWriteTxData((uint32)REG_cmd);     // instruction
    while(SPIFLASH_SpiIsBusBusy());
    SPIFLASH_SpiUartWriteTxData((uint32)0x00);     // dummy
    while(SPIFLASH_SpiIsBusBusy());
    AUD_CS_Write(1);
    rtn_data[0] = (uint8_t)SPIFLASH_SpiUartReadRxData();
    rtn_data[1] = (uint8_t)SPIFLASH_SpiUartReadRxData();
    
    return rtn_data[1];
}

댓글 1개:

  1. 안녕하세요! 저희 회사도 이 칩을 사용하려 하는데 여러 어려움을 겪고 있습니다... 괜찮으시다면 여러 질문이나 기술적인 도움을 요청드려도 될지요????? 개인적으로 사례하겠습니다 ㅠ

    답글삭제