페이지

글목록

레이블이 PSOC4인 게시물을 표시합니다. 모든 게시물 표시
레이블이 PSOC4인 게시물을 표시합니다. 모든 게시물 표시

2016년 8월 26일 금요일

[PSOC] PSOC4 UART 부트로더가 내장된 키트 소개(049)

이번에 PSOC4 보드(C8CKIT-049)를 여러 개 샀습니다.



저렴해서 ($4) 여러개 구입했는데, 비슷하게 생긴 보드(C8CKIT-043) 와 다른 점은 JTAG 가 포함되지 않은 점입니다.
또한 USB-to-I2C 도 포함되어 있지 않네요. I2C는 CAPSENSOR 튜닝할 때 필수인데... 없군요.


따라서 프로그램할 수 있는 방법이 없기 때문에, UART 부트로더가 내장되어 있습니다.
전원을 넣을 때, Switch 를 누른 상태로 전원을 넣으면 부드로더 모드가 되서 PSOC Creator 에서 UART로 프로그램을 다운로드할 수 있습니다.

자세한 내용은 다음에 좀 더 시간이 나면 올리겠고,,,
CY8CKIT-049 보드에 대해서 평가를 하자면, UART 부트로더를 테스트할 수 있어서 좋았지만
몇천원 더 주고 043 보드를 사는 것이 훨씬 낫다. 입니다.

JTAG와 USB-I2C 가 없어서 아주 많은 기능을 못 쓰게 되니 1개 사실 때는 043 보드가 좋고,
여러개 사실 때는 043 보드 1개에 049 보드 여러개 사시던가, 디버거가 있으시면 049 보드만 사도 괜 찮겠습니다.

2016년 6월 3일 금요일

[PSOC] PSOC4 SPI 핀 <-> GPIO 핀

SPI 기능으로 설정된 핀을 잠시 GPIO 기능의 핀으로 바꿨다가 다시 SPI로 되돌리는 테스트를 했습니다.

이런 경우는 보통 드문데, 핀이 모자라서 하게 되었습니다.

SPI TopDesign 탭의 내용은 다음과 같습니다.




SPI -> GPIO 동작 방법은 다음과 같습니다.
1. SPI component STOP.
2. SPI 핀 모드를 GPIO 출력인 경우 Strong Drive 로 설정
3. SPI핀 기능을 GPIO 핀으로 변경
4. GPIO 기능 처럼 핀을 프로그램에서 사용.
    SPIFLASH_Stop();
    SPIFLASH_miso_m_SetDriveMode(SPIFLASH_miso_m_DM_STRONG);
    
    SPIFLASH_SET_HSIOM_SEL(*(reg32 *)SPIFLASH_miso_m__0__HSIOM, SPIFLASH_miso_m__0__HSIOM_MASK,
                                   SPIFLASH_miso_m__0__HSIOM_SHIFT, SPIFLASH_HSIOM_GPIO_SEL);

        SPIFLASH_miso_m_Write(1); CyDelayUs(1);
        SPIFLASH_miso_m_Write(0); CyDelayUs(1);
        SPIFLASH_miso_m_Write(1); CyDelayUs(1);

GPIO -> SPI 동작 방법은 다음과 같습니다.
1. SPI핀 기능을 GPIO 핀으로 변경
2. SPI component START.
    SPIFLASH_SET_HSIOM_SEL(*(reg32 *)SPIFLASH_miso_m__0__HSIOM, SPIFLASH_miso_m__0__HSIOM_MASK,
                                   SPIFLASH_miso_m__0__HSIOM_SHIFT, SPIFLASH_HSIOM_SPI_SEL);
    SPIFLASH_Start();

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];
}

[PSOC] PSOC4 CAPSENSOR Tunning

안녕하세요,

이번에는 PSOC의 대표적인 기능인 CAPSENSOR 에 대해서 알아보겠습니다.
제가 해 본 기능으로는 CAPSENSOR 터치 스위치와 약 10센치 정도 거리의 사람을 인식할 수 있는 Proximity 기능입니다.

CAPSENSE 는 말 그대로 콘덴서의 성격을 많이 띠는 것 같습니다.
그리고 아날로그 입력의 특성을 갖고 있습니다. 아날로그 입력을 갖고 있고 작은 신호를 증폭해서 인식을 하기 때문에 
매우 민감합니다.
그래서 튜닝을 잘 해야 제대로 성능이 나오는 것 같습니다.

저는 PSOC을 쓰면서 거의 CAPSENSE 기능을 사용하지 않았는데, 외주 개발을 하다 보니 
터치 스위치 기능을 많이 요구해서 어쩔 수 없이 사용해 보게 되었습니다. 
CAPSENSE 기능은 PSOC에서 처음 사용해 보았고, PSOC5,PSOC4 에서 동작시켜 보았습니다.

CAPSENSOR 사용법은 너무 방대하고(메뉴얼 내용이 정말 많음) 다양해서 여기서 자세한 설명은 못 하겠습니다.
그래서 동작 방법과 튜닝 방법만 우선 설명 드리겠습니다.

1. CAPSENSOR 만드는 방법.
먼저 CAPSENSOR PCB 패드를 기판에 위치시켜야 하는데, 제가 해 본 바로는 동그랗고 적당히 큰(지름 5~10mm 정도) 것이 좋습니다. 간격도 가능한 서로 많이 떨어져 있는 것이 좋습니다. 
너무 작거나 서로 간격이 좁으면 인식이 잘 안되거나 옆의 키를 눌렀는데 키가 눌러진 것으로 인식될 때가 있습니다.


위 그림에서 Guard Sensor 라는 것이 있는데, 이것은 물이 묻어도 정상 동작을 하게 하기 위한 보조 기능입니다.
방수 기능이라고 설명이 되어 있는데, 표현이 좀 이상하네요. ^^

여기까지 HW 설명이였고요, 자세한 내용은 메뉴얼을 찾아 보시면 좋겠습니다. 자료가 너무나 많습니다.

SW 에서는 topDedign.cysch 탭에서 CapSense CSD 콤포넌트를 끌어다 놓습니다.


우측에 EZI2C는 나중에 CAPSENSOR 튜닝할 때에 디버거와 I2C 통신으로 연결하기 위해 필요한 콤포넌트 입니다.
위의 테스트는 프로그램은, 예제 프로젝트 중에서 가져다가 좀 수정한 것이고 소스는 정말 간단합니다.
실제로 동작하는 코드와 튜닝하는 코드가 다르므로, 
튜닝할 때는 프로젝트를 따로 1개 만들어서 CAPSENSOR의 포트만 맞게 설정하여 테스트하시기 바랍니다.

이 글을 시작은 했는데, 짧게 끝날 내용이 아니네요. ㅜㅜ

일단 튜닝 쪽만 다뤄야겠습니다.

다음은 CAPSENSE 콤포넌트의 설정입니다.
General tab 은 다음과 같습니다. default 로 표시한 부분이 CAPSENSOR 콤포넌트의 기본 세팅인데 튜닝 시 설정은 조금 다르네요.


그 다음으로 Widget tab 으로 가면, 좌측 상단의 + 버튼을 눌러서 여러 종류의 터치스위치를 추가, 제거(선택해서 Delete 키) 할 수 있습니다.

각각의 터치 스위치를 선택하면 CAPSESE 의 감도와 인식 Threshold 값 및 노이즈 처리값 등등을 바꿀 수 있습니다.
Scan resolution 을 높이면 감도가 높아져서 좀 더 정밀하게 값을 세팅할 수 있고, 보통 터치센서와 사람의 손가락 사이에 플라스틱 같은 소재로 거리를 띄워서 사용하는데, 감도를 높여야 어느정도 거리에서 손가락을 댔을 때 인식을 합니다.

다음은 Scan order tab 인데, 이부분은 자세히 조사를 못해봤습니다. 나중에 보충하겠습니다. 
현재는 전체 스캔 시간 정도만 참고하고 있습니다.

다음은 Advanced Tab 입니다. 이 부분은 HW 설계와도 좀 관련이 있습니다.
shield 센싱 핀의 유무에 따라서 shield 를 Enable/Disable 할 수도 있고,
Shield Tank Cap 의 사용 유무에 따라 Shield Tank Capacitor 를 Enable/Disable 할 수 있습니다.
Guard sensor 는 water proof(방수) 기능을 추가할 경우 HW에서 패턴으로 터치 센서를 감싸도록 설계한 후에 사용하는 기능이고,
나머지 부분은 아직 제대로 파악을 못했습니다. 나중에 자세한 내용 추가하겠습니다.

다음은, Tunning Helper Tab 입니다.
여기서 Enable tune helper 를 체크해야 튜닝 기능을 사용할 수 있습니다.
컴퓨터에서 튜닝 앱을 실행시켜서 PSOC IC 와 연동해서 동작시켜야 하는데, I2C 통신을 사용합니다.
따라서 EZI2C 콤포넌트를 추가해서 EZI2C 콤포넌트 이름을 Instance name for the SCB component 에 넣어 줘야 합니다.

이렇게 전부 설정했으면, EZI2C 콤포넌트의 설정을 또한 살펴봅시다.
configuration tab은 EZI2C 를 선택하면 되고,

EZI2C Basic TAB 에서 기억할 것은 Primary slave address(7-bit) 에 해당하는 주소하고,
Sub-address Size(bit) 는 16 bit 로 설정하는 것으로.. EZI2C 설정은 이 2가지 외에는 신경 쓰실 필요는 없습니다.

이렇게 설정을 하면 모두 끝난 것입니다.

튜닝용 소스코드는 모두 똑같습니다.
main.c 에 있는 main() 함수 내용 몇 주만 추가하면 됩니다.

int main()
{
    /* Enable global interrupts */
    CyGlobalIntEnable;
    
    /* Initialize CapSense CSD and EzI2C Start the sensor scanning loop */
    CapSense_CSD_TunerStart();
    
    while(1u)
    {
        /* Process scanning results and communicates with Tuner GUI */
        CapSense_CSD_TunerComm();
    }
}

컴파일해서 프로그램을 다운로드하고,
디버거의 I2C 신호(SCL,SDA)를 PSOC4 의 핀에 맞게 연결을 합니다.



PSOC Creator 의 TopDesign.cysch 탭에서 CAPSENSE 컴포넌트를 선택하고 마우스로 우클릭 해서 Launcher Tunner 를 실행하면 튜닝 앱이 실행됩니다.


튜닝 앱 실행.


여기서 끝이 아니죠. 설정에서 I2C 어드레스 및 관련 설정을 맞춰야 합니다.
이전에 CAPSENSE 의 EZI2C 의 주소(0x08)와 Subaddress 길이를 서로 맞춰 주고 튜닝 툴의 좌즉 상단의 Start 버튼을 눌러주면 실시간으로 값을 바꿔보면서 튜닝을 진행하실 수 있습니다.


튜닝은 많이 해보면서 적당한 값들을 찾아가면 됩니다.
나중에 튜닝했던 데이터를 본 프로그램에 적용하면 큰 문제없이 동작할 겁니다.

[소스코드 링크]

[PSOC] PSOC4 4100M에서 내부 FLASH data Memory 사용하기

지금까지 PSOC5,PSOC4 4200 을 사용하다가 이번에는 PSOC4 4100M 시리즈를 사용하게 되었습니다.


EEPROM 처럼 비휘발성 메모리를 사용하는 방법이 각각 달랐습니다.
(아.. 제가 사용한 방식이 각각 다 달랐다고 말씀드려야겠습니다.)
1. PSOC5는 EEPROM 과 emulate EEPROM 2가지를 사용할 수 있고,
2. PSOC4 4200 시리즈는 emulate EEPROM을 사용할 수 있었고,
3. PSOC4 4100M 시리즈는 Flash Memory 를 EEPROM 처럼 사용할 수 있었습니다.


PSOC4 4200 시리즈까지는 콤포넌트가 있으니까, 예제 불러다가 바로 이식해서 쓰는데 어려움이 없었는데,
PSOC4 4100M 시리즈는 콤포넌트 자체가 없어서 알아 보는데 시간이 좀 걸렸습니다.

SFlash 라는 메모리 영역이 있는데 바로 이 영역에 데이터를 쓰고 읽는 방법이 있었습니다.
PSoC 4 implements a User Supervisory Flash (SFlash), which can be used to store application-specific information.
These rows are not part of the hex file; their programming is optional.

나중에 예제를 검색해 보니 SFlash Write/Read 예제도 있었습니다.
PSOC 이 너무 쉬웠는데, 갑자기 콤포넌트에 없는 예외의 내용이 나오니까 잠시 허둥대 버렸네요. ^^



예제 내용을 보니까, 간단했습니다.
1. PSOC4 에는 User SFLSH 영역이 있고, 그 Address 는 0x0FFFF200 번지이다.
2. User SFLASH 의 영역를 구분하는 단위는 row 라고 부르고, 4개의 Row를 User SFLASH로 사용할 수 있다.
3. 1개의 Row는 128 Byte 이므로, 128 x 4 = 512 Byte 의 User SFLASH 를 EEPROM 처럼 사용할 수 있다.
4. 예제를 보니, 데이터는 1 Row 단위로 쓰는데.. 일반 Serial Flash 메모리 처럼 128 Byte 를 1 block 으로 생각하고
1 block 를 Erase 한 뒤에 다시 쓰는 방식으로 생각된다. 윈본드 serial Flash를 쓸 때를 예를 들자면, 지우지 않고 쓰면(Write) 값이 변하지 않는다. 그리고 쓸 때는 block(또는 sector) 단위로 쓴다.



SFLASH는 컴포넌트가 필요 없고, SFLASH를 사용하려면 다음과 같은 코드를 실행합니다.
    SPIFLASH_SCBCLK_Start();
    SPIFLASH_Start();



아, 위의 코드 이전에 어드레스 정의와 임시 데이터 저장 공간을 위해 SRAM 메모리 변수를 확보해야 겠습니다.
// Defines last ROW of SFlash 
#define CY_DOOR_SFLASH_ROW       (CY_SFLASH_NUMBER_USERROWS - 1u)
// Defines absolute address of ROW 
#define CY_DOOR_SFLASH_ADDR      (CY_SFLASH_USERBASE + CY_DOOR_SFLASH_ROW * CY_SFLASH_SIZEOF_USERROW)

// SRAM 메모리 130개 (130-Byte),,   > 1 block(128-byte)
uint8_t card_key_data[13][10];

(의의 코드 설명)
디게 복잡하게 보이네요. CY_SFLASH_NUMBER_USERROWS 는 PSOC 에서 이미 만들어진 h 파일에 4라고 되어 있으니,
CY_DOOR_SFLASH_ROW 은 4-1 로 3이네요.

PSOC4 의 User SFLASH 로 사용할 수 있는 Row 값은 0~3 으로 4개이고, 그 중에 3번 Row(CY_DOOR_SFLASH_ROW)를 사용한다는 말이지요.
(예제를 그냥 베껴 썼더니, 복잡해져 버렸다. ^^ 죄송)


CY_SFLASH_USERBASE 는 PSOC 에서 이미 만들어진 h 파일에 0x0FFFF200u 로 User SFLASH 메모리의 시작 Address 입니다. CY_SFLASH_SIZEOF_USERROW 는 128 Byte(1 Row의 구성 단위)이므로 3번 Row의 시작 어드레스는 CY_DOOR_SFLASH_ADDR 으로 정의된 내용입니다.




[SFLASH 읽기/쓰기]
SFLASH에 데이터를 쓰는 과정은 다음과 같습니다.
1. 쓸(Write) 데이터를 1-row 단위(128-Byte)로 임시 저장 변수에 넣는다.
2. returnValue = CySysSFlashWriteUserRow(CY_DOOR_SFLASH_ROW, &card_key_data[0][0]); 의 예제 코드처럼, CySysSFlashWriteUserRow 함수에 입력으로 Row 번호 와 임시저장 변수의 시작 어드레스를 넣으면 출력으로 CY_SYS_SFLASH_SUCCESS 가 return되면 쓰기(Write)성공, 다른 값이 리턴되면 실패로 처리하면 됩니다.

SFLASH에서 데이터를 읽는 과정은 다음과 같습니다.
그냥 해당 어드레스의 값을 읽으면 됩니다. 아무 제약이 없습니다. 일반적으로 어드레스에서 데이터 읽기와 똑같습니다.
다들 아시죠?

이렇게 읽으면 p_mem_data 에 SFLASH의 해당 address의 값이 들어가게 되겠죠? ^^
uint8_t p_mem_data;
uint32_t cnt_sf=0;
p_mem_data = (*((uint8 *) (CY_DOOR_SFLASH_ADDR + cnt_sf)));





프로젝트 예제는 생략합니다. 프로젝트를 만들 때, 예제를 선택해서 SFLASH로 검색하면 예제 프로젝트 나옵니다.
저도 예제 프로젝트 변경해서 썼습니다. ^^

2016년 5월 2일 월요일

[PSOC] PSOC4 Emulated EEPROM Component 사용기

PSOC4는 PSOC5와 달리 EEPROM Component가 없습니다.

그래서 em_EEPROM Component를 사용해야 하는데,
처음에 아무리해도 동작이 안되는 것이여서 여러가지 사례들을 웹에서 찾아봤는데,
별 도움이 안되는군요. 아마 영어가 딸려서 이해를 못 한 것도 큰 것 같습니다.

그러다가, 혹시 하는 생각에 전원을 껐다 켜니 그제서야 제대로 동작하네요.

제가 행한 프로그램 동작 과정은, em_EEPROM를 디버거를 사용해서 프로그램을 다운로드했었습니다.
em_EEPROM은 내부 플래쉬 메모리를 이용하는 방식인데, 
디버거를 사용해서 프로그램을 할 때, 다운로드할 때 플래쉬를 먼저 모두 지워버리나 봅니다.
그리고 초기 값을 쓰죠.

그러니까, 항상 프로그램을 다운로드 할 때 똑같은 초기값으로 써져서 전혀 em_EEPROM 이 동작하지 않는 것처럼 보이는 것이였습니다.

PSOC4 의 예제 중에서, em_EEPROM 예제가 있는데 잘 동작합니다.
주의하실 점, 다운로드하면 전부 지워지고 초기화된다.

따라서, 동작을 확인하려면 다운로드한 후, 리셋를 꾹 눌러본다.

PSOC5의 EEPROM Component는 디버거로 다운로드해도 지워지지 않는다.
PSOC4는 주의하자~~^^

2016년 3월 3일 목요일

[PSOC] PSOC4 CAPSENSE PROXIMITY Widget 영상

이번에, PSOC4 로 doorlock을 개발하면서 터치 센서를 다루게 되었습니다.

현재는 회로 설계를 하면서 자료를 모우는 단계입니다.

기능 중, Proximity 라는 재밌는 기능이 있더군요.

사람이 가까이 가면 꽤 먼 거리에서 CAP SENSE 로 인식을 하는 기능으로,
백색 가전에서 사람이 가까이가면 LED가 켜지는 용도로도 쓰입니다.

관련 동영상을 링크합니다.
이 영상의 출처는 다음과 같습니다.
이 영상은 PSOC4 BLE 를 이용해서 스마트폰 앱에서 모니터링 할 수 있게 구성되어 있군요.

나도 앱을 해보고 싶은데 능력이 안돼네요. ㅜㅜ


Cypress 에서 Proximity Kit 도 나와 있습니다. 
PSOC의 CAPSENSE 기능 중, 제스쳐 와 proximity 기능을 테스트 할 수 있습니다.


PCB 상에 둥그렇게 패턴을 그려서 PSOC의 CAPSENSE 입력으로 넣으면,
영상으로 볼 때, 약 5~10 cm 거리 정도는 안정적으로 감지하는 것 같습니다.

다음은 키트의 내부 TOP 패턴 입니다. 4개의 Gesture 용 패턴과 Shield , Proximity 패턴이 보입니다.

총 6개의 CAPSENSE 를 사용했습니다.



다음은 키트의 실제 동작 테스트 영상입니다.

2016년 2월 27일 토요일

[PSOC] PSOC4 GPIO Interrupt Component SCH

이번에는 PSOC4의 GPIO 인터럽트 테스트를 해봤습니다.

PSOC4 GPIO Interrupt 는 핀 내에 Fixed 된 인터럽트가 3가지 있습니다.
1. Rising Edge
2. Falling Edge
3. Both Edge

즉 Edge 트리거만 지원하는군요.

포트 에서 인터럽트 타입을 선택하면 GPIO 콤포넌트에 irq 출력 핀이 1개 나온다.

이 핀에 인터럽트 콤포넌트를 붙여 줘야하고, 인터럽트 콤포넌트에서 다시 다음의 3가지 타입의 입력을 선택한다.
1. DERIVED : 연결된 콤포넌트의 인터럽트 방식은 그대로 가져다 쓴다.
2. RISING EDGE : 연결된 콤포넌트의 인터럽트 펄스 출력의 RIGING EDGE 에서 인터럽트 발생.
3. LEVEL : 연결된 콤포넌트의 HIGH LEVEL 에서 인터럽트가 반복적으로 걸림


여기까지 진행해야 인터럽트 동작 준비가 끝난다.

이번 회사 프로젝트에서는 Level 트리거가 필요한데, 인터럽트를 1개 더 추가해야했다.


현재까지 다른 방법을 찾지 못했네요. 혹시 이 방법 외에 LEVEL 트리거를 할 수 있는 방법 아시는분~ 손?
LEVEL 트리거 인터럽트는 무조건 HIGH LEVEL 에서만 걸리므로 LOW LEVEL 에서 걸리도록 하려면,
UDB 소자인 INVERTER(NOT) 를 1개 추가해야 한다.

[PSOC] PSOC4 LOW Power Mode Test

현재 진행중인 프로젝트가 NFC 카드에 PSOC4를 넣어서 전원이 무지무지 딸립니다.

전력을 아끼기 위해서 LED 키는데도 조심해야하고, 클럭도 낮췄습니다.

하여간 조금이라도 쉬는 때에 NFC 안테나를 통해 전력을 모아야 했습니다.

그래서 다루게 된게, Sleep Mode입니다.

PSOC4는 Low Power 모드가 총 4가지 있습니다.
1. Sleep Mode
2. Deepsleep Mode
3. Hibernate Mode
4. Stop Mode

----

각 모드마다, 특징이 있는데 먼저 일반적으로 우리가 사용하는 모드를 Active Mode라고 합니다.
저전력 모드는 다음과 같은 특징을 갖습니다.
1. Sleep Mode 는 모든 다른 기능은 살아있고 CPU만 죽어 있습니다.
2. Deepsleep Mode는 CPU,대부분의 Peripheral,HF Clock 등을 사용할 수 없습니다.
3. Hibernate Mode 는 모든 clock이 죽어있고, 로직 상태는 그대로 유지됩니다.
4. Stop Mode는 모두 죽어있고, GPIO 상태만 유지되어 있거나 Frozen 상태로 됩니다.

Frozen : 모든 GPIO 의 설정,모드,상태가 lock 된다. active 모드로 재진입하여 pins이 unlock 되기 전까지 GPIO 상태를 바꿀 수 없다.

[파워 모드 스펙]


[파워 모드 - 이용 가능한 리소스들]

[파워 모드 테스트 소스 코드]
int main()
{
    CyGlobalIntEnable; // Enable global interrupts. 
    //CySysPmSleep();
    CySysPmDeepSleep();
    //CySysPmHibernate();
    //CySysPmStop();
    while(1);
}

실제로 NFC 안테나를 통해서 전력을 공급받는 회로에서 , 각 파워 모드당 오실로스코프로 VCC를 측정해본 결과 다음과 같습니다.
그런데, Hibernate Mode 와 Stop Mode 가 오히려 전력이 떨어지는 것은 아직 이유를 못 찾았습니다. 뭔가 실수가 있을 것 같은데, 나중에 알게 되면 업데이트 하겠습니다.

DEEPSLEEP 모드가 가장 좋게 나오네요. 일단은 SLEEP 모드보다는 DEEPSLEEP 모드가 좀 더 성능이 좋습니다.
실제로 제가 쓰려고 했던 모드는 SLEEP 이나 DEEPSLEEP 모드입니다. 다른 모드들은 Wakeup 시 시간이 너무 길고, 결정적으로 시스템 리셋이 되 버립니다.


[클럭당 DEEPSLEEP 모드의 전력 비교]

2016년 2월 14일 일요일

[PSOC4] BLE Pioneer Kit(CY8CKIT-042-BLE) H/W 구성

ypress의 BLE Pioneer Kit(CY8CKIT-042-BLE)를 간단히 소개합니다.

얼마 전에 Cypress 사의 블루투스 관련 개발용 키트 교육에 참가해서 이 보드를 공짜로 받았습니다.

이 보드는 크게 2부분으로 되어 있습니다.

PSoC5LP 라는 Cortex-M3 계열의 MCU인 CY8C5868LTH-LP039로 구성된 Programmer and Debugger 와
PSoC4 라는 Corte-M0 계열의 xCY8C4247LQI-BL483로 구성된 PSoC4 BLE Module로 구성되어 있습니다.

[ Programmer and Debugger ]
[ PSoC4 BLE Module ]


그리고 추가로 다음과 같은 구성품이 있습니다.
PC의 USB 2.0 포트에 붙여서 블루투스 통신을 연결해 주는 동글이 있는데,
이 동글의 하드웨어 구성은 또한 CYBL10162-56LQXI MCU를 콘트롤하는 
디버거와 프로그래머가 붙어있는 형태로 되어 있어 CYBL10162-56LQXI MCU를 프로그램 변경 가능합니다.

[ USB 블루투스 동글 ]


또 옵션으로 PSoC4 BLE Module 보다 성능이 떨어지고 가격이 저렴한 블루투스통신 모듈인 PRoC BLE Module이
들어 있습니다. Cortex-M0 코어인 CYBL10563-56LQXI로 구성되어 있습니다.

PRoC BLE Module ]
이 보드의 연습 목적은 PSoC4 BLE Module 이나 PRoC BLE 모듈의 프로그램 및 디버깅 입니다.
PSoC5LP MCU를 프로그래밍 하려면 또 다른 디버깅 툴이 있어야 하고, JTAG 콘넥터가 납땜되어 있지않기 때문에
맞는 콘넥터와 프로그램 및 디버거를 구입해서 테스트 해 봐야 합니다.

하지만 프로그램을 고치게 되면 현재의 기능인 프로그램 및 다운로드 기능을 잃게 되니 
이 보드는 BLE 모듈 을 테스트하는데에만 사용하고, PSoC5LP 를 연습하려면 050개발키트를 구입하는 것이 낫겠습니다.



전체적인 개발 환경 구성은 다음과 같습니다.

[PSOC4] PSOC4에서의 SGPIO

이번엔 PSOC4로 SGPIO 출력을 구현해 보겠습니다.

이전에 PSOC_5LP 에서 만들어 보았던 회로와 구성은 똑같습니다.

하지만 PSOC4는 UDB(Universal Digital Blocks)가 4개 밖에 없는데, 
TCPWM 4개가 UDB에 포함되어있지 않아서, 만약 TCPWM을 적절하게 사용한다면 
PSOC-5LP 만큼은 못하지만 충분히 여러가지 기능들을 구현할 수 있습니다.

또한 PSOC4는 UART/I2C/SPI 등, 어떤 특정 기능의 핀을 바꿀 수 없었습니다.
UDB로 새로 만든 기능은 임의로 핀을 지정해서 입출력핀으로 사용할 수 있지만,
이미 내장된 기능의 핀은 특정 위치로 바꿀 수 없었던 것이 PSOC-5LP와의 차이점으로 보입니다.
(아직도 PSOC을 배워가는 중이라서 이렇게 표현합니다)


SGPIO 출력의 주요 기능은 다음과 같습니다.
1. Trigger 입력으로 동작하는 특정 갯수만큼 펄스 발생회로.(SHFT CLK)
2. Shift Register
3. Shift Register Load 신호와 CLK신호 (Load 입력 신호에 CLK입력도 넣어 줘야 load 기능 동작함)
4. SHFT CLK(load CLK + SCK) 에서 SCK만 추출해서 SCK를 출력

[ 주요 기능은 SCK에 동기된 SDO 출력입니다. ]


다음은 PSOC Creator 3.3 에서 TopDesign.cysch 탭에 회로도를 그린 내용입니다.

[회로도만 자세히...]

이 회로는 ..
1. Control_Reg_1 의 신호를 0->1로 하여, Trigger 신호를 PWM_1 에 주면,
2. PWM_1 은 입력 클럭의 2(load clk) + 24x2 클럭 만큼 line 출력이 Low였다가 High 바뀝니다.
3. line 출력이 Low->High 로 바뀌는 순간 stop 신호로 rising Edge 입력에 의해 PWM_1 component가 자동으로 멈춥니다.
4. 이 line 출력을 AND 로직으로 CLK과 비교해서 출력 하면 좋겠지만, AND 로직이 CLK입력을 바로 입력 받을 수 없다고
ERROR 을 띄워서 NOT+AND+D-FF를  써서 2분주해서 SCK 출력을 만들어야 했습니다.
만약 AND 입력으로 CLK를 받을 수 있다면 좀 더 빠른 SCK를 만들 수 있겠습니다만, 방법을 못 찾아서 Cypress에 문의해 두었습니다.
5. SCK_MASK 회로(MUX[2:1],Basic_Counter_1,DigitalComp_1)는 load clk+sck 에서 sck만을 걸러내기 위해 만든 회로입니다.
이 신호를 NOT 로직으로 반전하면 Load 신호가 됩니다. 그런데 Shift_Register에 load신호를 주기 위해서 load(High)신호와 1CLK를 동시에 입력해 줘야 load 신호가 동작하기 때문에 처음부터 PWM 에서 CLK 신호를 1개 더 만들었던 것이고, 여기에서 실제 출력할 SCK를 걸르려면 load clk를 빼기위한 신호가 필요했습니다.

main.c 프로그램 소스는 다음과 같습니다.
int main()
{
    CyGlobalIntEnable; /* Enable global interrupts. */

    /* Place your initialization/startup code here (e.g. MyInst_Start()) */
    PWM_1_Start();
    ShiftReg_1_Start();
    
    ShiftReg_1_WriteRegValue(0x00800001);   // 1-Shift value
    Control_Reg_1_Write(0x01);     // Trigger
    Control_Reg_1_Write(0x00);

    ShiftReg_1_WriteData(0x00800002);         // 2-Shift Value
    Control_Reg_1_Write(0x01);     // Trigger
    Control_Reg_1_Write(0x00);

    for(;;)
    {
        /* Place your application code here. */
    }
}

위 소스 코드에서 보면 출력이 워낙 빨리 나가서, 다 나갔는지 체크하는 내용은 뺐습니다. 트리거 하고 다음 쉬프트 값 쓰는 동안 이미 출력은 나가버렸습니다. ^^



다음은 위의 설명에 따른 출력을 오실로 스코프로 보시겠습니다.



Shift 값 0x00800001 과 0x00800002 가 제대로 출력 되었음을 알 수 있습니다.

2016년 1월 20일 수요일

[PSOC] I2C 통신시에 FIFO 초기화 문제(PSOC4)

안녕하세요, 오랜만입니다.

이번 이슈는 PSOC4 에서 I2C 통신을 하다가, I2CMasterWriteBuf() 함수를 사용할 경우 잘못된 SUB ADDRESS에 데이터를 송신하면 송신한 데이터들이 내부 FIFO 버퍼에 쌓여있다가 정상적인 SUB ADDRESS에 다시 데이터를 쓸 경우 이전에 쌓여있는 데이터가 출력되는 것을 발견했습니다.

이 문제의 발생빈도는 on-chip program 시에는 50% 정도이지만, 디버그 모드에서는 80%이상이었습니다. 즉 항상 발생하는 것은 아니라는 것이지만, 문제가 되기에는 충분합니다.

현재 Cypress에 기술 문의를 요청한 상태이고 빨리 해결되었으면 좋겠네요.

항상 제대로된 어드레스에 데이터를 전송하는 것은 아니라, 이런 경우도 있다는 점을 업체에서 인지하지 못했던 것 같습니다.

2016년 1월 6일 수요일

[PSOC] Psoc4 GPIO INPUT (IN/OUT Test 2/2)

이번에는 입력 테스트를 해 보겠습니다.

1. 먼저 Digital Input Pin [v2.10] 콤포넌트를 선택해서 cysch 파일에 넣습니다.
이름은 적당히 지어 줍니다. 저는 SW_IN_1,SW_IN_2,SW_IN_3 이라고 지었고, 나중에 컴파일하면 자동으로 입력함수인 SW_IN_1_Read() ,SW_IN_2_Read() ,SW_IN_3_Read() 함수가 생깁니다.


2. 입력 핀 설정 중에서 , HW connection 옵션을 제거합니다.
또한 핀 Drive mode 에서 resistive pullup으로 내부 풀업을 걸어 줍니다.


3. cydwr 파일에서 핀을 회로도에 맞게 지정을 해 줍니다.


PSOC4 IC 의 입력핀 회로도와 이에 연결된 SW 회로도 첨부합니다.


5. 이제 컴파일을 하면 자동으로 SW_IN_x_Read() 함수가 생기는데 이것을 사용해서 포트값을 읽으면 됩니다.
코드의 예는 다음과 같습니다.
    for(;;)
    {
        if (f_50ms)
        {
            f_50ms = 0;
            sw_stat_old = sw_stat_new;
            sw_stat_new = (((SW_IN_1_Read()<<0 b="" ead="" x07="">
           
            if (sw_stat_new != sw_stat_old)
            {
                UART_1_UartPutString("switch stat = ");
                ser_tx_buf[0] = htoa(sw_stat_new);
                ser_tx_buf[1] = '\n';
                ser_tx_buf[2] = '\r';
                ser_tx_buf[3] = '\0';
                user_UART_PutString(ser_tx_buf);
            }
        }
        /* Place your application code here. */
    }

2016년 1월 5일 화요일

[PSOC] Psoc4 GPIO OUTPUT (IN/OUT Test 1/2)

PSOC4 에서의 GPIO IN/OUT TEST

이전 게시물에서 LED를 사용하는 GPIO OUT을 이미 테스트 했는데,
아무 설명을 하지 못해서 INPUT 테스트와 같이 다뤄 보겠습니다.

PSOC IC에 SW를 3개 달아서, 이전에 만들어 놓았던 타이머 인터럽트를 이용해서 50ms 마다 Switch 입력을 읽어서 값이 바뀔 때마다 스위치 값을 UART로 출력하는 내용입니다.

GPIO 출력은 이전에 해뒀던 내용인데, 100ms 마다 포트값을 토글하는 내용입니다.

먼저 OUTPUT을 설명드리겠습니다.

1. PSOC Creator 의 cysch 에서 Digital Output Pin [v2.10] 콤포넌트를 그려 넣습니다. 핀 이름은 적당하게 고치면 되는데 이름에 따라 함수가 자동으로 만들어집니다.
저는 LED_1,LED_2,LED_3 라고 정했는데, 출력 함수 이름은 자동으로 LED_1_Write() , LED_2_Write() , LED_3_Write() 으로 만들어 집니다.


2. OUTPUT PIN 콤포넌트를 마우스로 더블클릭하면 핀 설정이 나오는데, HW connection 체크를 해제 해 주십시요. 이것은 내부에서 다른 콤포넌트와 연결 하지 않을 경우에 해당되며, 이 옵션을 해제하지 않으면 에러가 납니다.

3. cydwr 파일에서 PSOC4 IC에 OUTPUT으로 사용할 핀을 지정

PSOC4 IC 와 연결된 출력 핀과 여기에 연결된 LED 회로도 그림을 아래 첨부합니다.



4. 소스 코드에서 포트 이름에 따라 자동 생성된 LED_x.c 안의 LED_x_Write() 함수로 비트를 ON(1),OFF(0) 하면 됩니다.

이전에 만든 타이머 인터럽트 코드 안에 있는 출력함수 예는 다음과 같습니다.

CY_ISR(Timer_INT_Handler)
{

    uint32 InterruptHpn;
    static uint8_t LED_1_stat=0,LED_2_stat=0,LED_3_stat=0;
    /* Check interrupt source and clear Inerrupt */
    InterruptHpn = Timer_1_GetInterruptSourceMasked();
    if (InterruptHpn == Timer_1_INTR_MASK_CC_MATCH)
    {
        Timer_1_ClearInterrupt(Timer_1_INTR_MASK_CC_MATCH);
    }
    else
    {
        cnt_50ms++;
        if (cnt_50ms > 49)
        {
            f_50ms = 1;
        }
        LED_1_stat = 1-LED_1_stat;
        LED_2_stat = 1-LED_2_stat;
        LED_3_stat = 1-LED_3_stat;
        LED_1_Write(LED_1_stat);
        LED_2_Write(LED_2_stat);
        LED_3_Write(LED_3_stat);
        Timer_1_ClearInterrupt(Timer_1_INTR_MASK_TC);
    }
}