nobcha23の日記

PICマイコンやArduinoを使う電子回路遊びを紹介します

ピポパ電話機用押しボタン(その8) AP-734参考のSSP_ハンドラー部分

今回のキーパッドi2cスレーブ試作において、結果的に苦労したのはmssp割り込みハンドラのところでした。
以前作ったスレーブに判断分岐追加で始めましたが、結局はマイクロチップ社AN-734のASMサンプルを参考にMSSP_HANDLERを作って、MSSP割り込みを5つのイベントで分岐するようにしました。

// ssp int handling function
void ssp_handler(void) {
	unsigned char s_state,dummy;
	s_state=SSP1STAT&0b00101101;
		// SMP,CKE,-D/A,P,-S,-R/W,UA,-BF
	switch(s_state){		
		case 0b00001001:
		// State1 address,S,write,buffer full
			dummy=SSP1BUF;
		// if address, read SSPBUF as dummy
			rcv_count=0;
			break;
		case 0b00101001:
		// State2 data,write,buffer full
			buffer[rcv_count]=SSP1BUF ;
	// 
			if((rcv_count&0x1)==0){
		// receiving RS byte and DATA byte as pair
				lcd_rs_rcv=((buffer[rcv_count]>>6)&0x1);
	       // Set lcd_rs bit
			}
			else if((buffer[rcv_count]==0x10)&(lcd_rs_rcv==0)) 	cnt_stop();
			else if((buffer[rcv_count]==0x11)&(lcd_rs_rcv==0)) 	cnt_setup();
			else if(DEBUG==0) lcd_write_rs(buffer[rcv_count],lcd_rs_rcv);	// Data byte
			stat[rcv_count]=SSP1STAT;
	        // status buffering
			rcv_count++;
		// next buufer
			break;
		case 0b00001100:
		// State3 address,S, read,buffer empty
		case 0b00001101:
		// State3 address,S, read,buffer full
			SSP1CON1bits.CKP=0;
		// CKP clear
			dummy=SSP1BUF;
		// dummy address read
			SSP1BUF=key_in_p;
		// key in data transmitting
			SSP1CON1bits.CKP=1;
		// CKP releas
			break;
		case 0b00101100
		// State4 data,S, read,buffer empty
			SSP1CON1bits.CKP=0;
		// CKP clear
			SSP1BUF=key_in_cnt;
		// key in counter transmitting
			SSP1CON1bits.CKP=1;
		// CKP releas
			break;
		case 0b00101000:
		// State5 data,S, read,buffer empty &full
		case 0b00101101:
			SSP1CON1bits.CKP=1;
		// CKP release
			break;
		default:
			lcd_puts("ERR");				break; 	} }

この関数は割り込み関数の中でMSSP要因判定後(MSSP1IFが有ったら)に入れて各処理に分岐します。
WRITEとREADに別れ、LCD表示の方もすっきりと収容しました。デバッグ用の表示が入ってましたが、割り禁で自前のLCD表示に行くため、次の割り込みが追突します。取っ掛かりの実験で使いましたが、その後は邪魔になりました。最後のバグだと思っていたのはデバッグ用表示の割り込み禁止が原因でした。

MSSPの制御で注意点は、スレーブ受信ではアドレス一致、BUF空きでCKPが自動で0(クロックストレッチモード)になるので、MSSPBUF書き込み後にソフトでCKPを1にすること、送信では、受信したアドレスが入ったMSSPBUFを空読みしてやら無いと次のデータ受信で、オーバーフローになることなどぐらいでしょうか。
それからMSSP以前に良く間違う点は、ackは0でnackが1だというところです。ソースコードに関しては追ってwebに掲載していく予定です。