2012/02/19

PSoC でGPIO割り込みを使うときの手順



毎度忘れるので、いまさらながらメモっとく。



  1. Pinout の設定で、割り込みをかけたいポートの Interrupt を DisableInt 以外にする

  2. lib/PSoCGPIOINT.asm の59行目あたりに下記を追加

    ;---------------------------------------------------
    ; Insert your custom code below this banner
    ;---------------------------------------------------
    ljmp _GPIO_INT // added



  3. main.c の main() 関数の先頭に下記を追加

    M8C_EnableGInt ; // <--- これはもともとあるので、アンコメントする
    M8C_EnableIntMask(INT_MSK0, INT_MSK0_GPIO); // <--- 追加



  4. main.c に #pragma ディレクティブと割り込みハンドラを追加

    #pragma interrupt_handler GPIO_INT
    void GPIO_INT(void)
    {
    // do something
    }




注意点としては、




  • lib/PSoCGPIOINT.asm に追加した ljmp のジャンプ先ラベル名

  • #pragma ディレクティブで指定したシンボル名

  • 割り込みハンドラの関数名


が一致していないと割り込みが入らないこと。


ちなみに、F6(Generate / Build Project) とか Ctrl+F6(Generate Configuration Files) とかすると、lib 内のファイルは再生成されるので、lib/PSoCGPIOINT.asm に変更を加えるタイミングによっては変更前の状態に上書きされることもある。割り込みが入らないときは、もう一度 lib/PSoCGPIOINT.asm をチェックするのもいいかもしれない。





2012/02/07

続 左手の小指を救え



こないだ作ったこれの続き。


使ってるといい感じなので、SHIFT キーもタッチセンサにしてみた。プロジェクト一式はここに。


CapSense のセンサが1つ増えても GUI で簡単にデバイス追加できる。下は PSoC Designer の Wizard 画面。


f:id:gnrr:20120208014706p:image:w360


Buttons を 1 → 2に変えて、ポートにドラッグアンドドロップしただけ。楽ちんすぎて屁が出る (w


HHK Lite2 の基板と FIRST TOUCH 基板との接続に線4本足した。


f:id:gnrr:20120208014109p:image:w360

ハードの変更はこれだけ*1。逆にソフトの方がめんどく感じる。



//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules

BYTE out_ctrl, out_shift, out_led;

void main(void)
{
M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
// Insert your main routine code here.
M8C_EnableIntMask(INT_MSK0, INT_MSK0_GPIO);
CSD_1_Start();
CSD_1_InitializeBaselines() ; //scan all sensors first time, init baseline
CSD_1_SetDefaultFingerThresholds() ;

while(1) {
BYTE ctrl, shift, led;
CSD_1_ScanAllSensors();
CSD_1_UpdateAllBaselines();

// CTRL: P0_2 -> P1_6
if(CSD_1_bIsSensorActive(0)) {
ctrl = 0x80; // 10xx_xxxx: CTRL SENSEOUT LO
led |= 0x04; // xxxx_0100: BLUE LED ON (touch sw indicator)
} else {
ctrl = 0xC0; // 11xx_xxxx: CTRL SENSEOUT HI (Hi-Z)
led &= 0x0B; // ^
}

// SHIFT: P0_3 -> P1_7
if(CSD_1_bIsSensorActive(1)) {
shift = 0x40; // 01xx_xxxx: SHIFT SENSEOUT LO
led |= 0x08; // xxxx_1000: RED LED ON (touch sw indicator)
} else {
shift = 0xC0; // 11xx_xxxx: SHIFT SENSEOUT HI (Hi-Z)
led &= 0x07; // ^
}

out_ctrl = ctrl;
out_shift = shift;
// PRT1DR = (PRT1DR & 0xC0) | led; // this line occurs mulfunction when typing '-' or '[' !!!
}
}

BYTE p0, p0_old, diff;

#pragma interrupt_handler GPIO_INT
void GPIO_INT(void)
{
// output keyboard matrix drive signal (active-lo)

p0 = PRT0DR;
diff = (p0 ^ p0_old);
if(diff == 0x00) return;

if(diff & 0x04)
PRT1DR = (p0 & 0x04)? 0xC0 : out_ctrl;
else if(diff & 0x08)
PRT1DR = (p0 & 0x08)? 0xC0 : out_shift;

p0_old = p0;
}

ソフトの構成はあまり変わらないが、割り込みハンドラでやることが若干増えた。キーマトリクスのドライブ側のエッジを割り込みで捕まえるのはいいとして、CTRLとSHIFTのどちらで割り込みが入ったのかはわからない。結局は割り込みハンドラの中で判断してるけど、少々めんどくさい。それと、なんでか LED インジケータがバグってる*2ので無効にしてる。なんでか。


外見的には、


f:id:gnrr:20120208014106j:image:w360


写真ではわかりにくいけど、メンブレンシートをカットして、キーの高さを低くしといた。これで小指の負担をさらに軽減できる。


蛇足ながら FIRST TOUCH 基板の回路図とかは Cypress のサイトにある。直リンはよく切れるから探して、落とせる。zip には回路図だけじゃなく、基板のアートワークやらガーバーデータやらBOMやら、一通り入っている。


PSoC って、このへんが至れり尽くせり。慣れるとふつうのワンチップマイコンに戻れなくなりそうで、ちょっと怖くなってきてたり。




*1:他にもポートの設定を変えたり、 チップ抵抗(R9)を外してたりするけど。


*2:誤入力を起こす