From 77a9f3c341e4283088c021cc9f5f00019fa86978 Mon Sep 17 00:00:00 2001 From: ceb Date: Sun, 13 Feb 2005 19:26:07 +0000 Subject: [PATCH] first i2c test program, master pic0 receives byte over serial, transmits it to slave pic1, which toggles LED colour (does not check contants of byte) --- cebpic/README.protocol | 2 + cebpic/i2c-test.asm | 129 ++++++++++++++++++++++++++++++++++------- 2 files changed, 109 insertions(+), 22 deletions(-) diff --git a/cebpic/README.protocol b/cebpic/README.protocol index 5e86d96..711ce28 100644 --- a/cebpic/README.protocol +++ b/cebpic/README.protocol @@ -22,6 +22,7 @@ Flash memory ID locations ========================= Byte 20 0000h + bits 7-5 = 000 bits 4-0 PIC number (guaranteed to be in range 0..31 inclusive) @@ -34,3 +35,4 @@ Byte 20 0001h I2C === +(slave addresses will be 10xxxxx where xxxxx=PIC number above) diff --git a/cebpic/i2c-test.asm b/cebpic/i2c-test.asm index 882221a..8966c5d 100644 --- a/cebpic/i2c-test.asm +++ b/cebpic/i2c-test.asm @@ -1,11 +1,15 @@ +; write a byte to pic0 via the serial port, pic0 will transmit it to +; pic1, which will then toggle its colour (without checking the contents +; of the byte) ; pin 21 (per-pic-led, RD2/PSP2/C1IN) states: -; high H = green, low L = red, float Z = black +; high H = blue (=green), low L = orange (=red), float Z = black include /usr/share/gputils/header/p18f458.inc + radix dec ; reserved for NMRA: NMRACTRL equ 0x4 ; byte 4: state relevant to NMRA control @@ -164,9 +168,9 @@ common_setup bsf SSPSTAT,7,0 ; disable slew rate control bcf SSPSTAT,6,0 ; disable SMBus specific commands ; (whatever that means) - - + bcf SSPCON2,7,0 ; disable general call (for now) + bcf IPR1,SSPIP,0 ; make interrupt low priority master_or_slave @@ -178,30 +182,43 @@ master_or_slave pic_master_setup + movlw 0x08 + movwf SSPCON1,0 ; set to master mode, clear top 4 bits + +; set baud rate + movlw 100-1 + movwf SSPADD,0 ; set baud rate; clock=Fosc/(4*(SSPADD+1)) + ; Fosc=20MHz, currently want clock=50kHz + ; => SSPADD=99 + goto switch_i2c_on pic_slave_setup + movlw 0x06 + movwf SSPCON1,0 ; set to 7bit slave mode, clear top 4 bits + ; (no extra start/stop interrupts) + +; set slave address + movlb I2C_BUFF_PAGE ; set BSR=i2c BSR (4) + movf PIC_NO,0,1 ; copy pic_no to W (000xxxxx) + iorlw 0x40 ; change top 3 bits t 010 (010xxxxx) + movwf SSPADD,0 ; move to slave address register + ; (bit 7=0, bits 6-0=address) + + goto switch_i2c_on + +switch_i2c_on + bsf SSPCON1,5,0 ; enable I2C mode ; p68 ; p314 ; p 275 ID locs -; test whether master PIC (location 20 0000h bit 0; 1 if true) -; by doing: -; set tblptr (tblptru/tblptrh/tblptrl) -; tblrd * -; result in tablat - -; i2c_master_setup if so, i2c_slave_setup if not - - - - ;---------------------------------------------------------------------------- @@ -211,17 +228,50 @@ pic_slave_setup bsf RCON,7,0 ; enable priority levels bsf INTCON,7,0 ; enable high-priority interrupts bsf INTCON,6,0 ; enable low-priority interrupts + bcf PIE1,3,0 ; disable master synchronous serial port + ; (MSSP; i.e. enable i2c) interrupts + ; (temporary for this simple program) bsf PIE1,5,0 ; enable USART receive interrupt (p85) ;**************************************************************************** +;**************************************************************************** + +main + movlb I2C_BUFF_PAGE ; ser BSR=i2c BSR (4) + btfsc I2C_CTRL,I2C_MASTER ; check =master?, if so + goto main_master ; goto master main routine + goto main_slave ; elso goto slave main routine + + +;---------------------------------------------------------------------------- + +main_master call led_green main_loop_led goto main_loop_led +;---------------------------------------------------------------------------- + +main_slave + + call led_red + +slave_loop + call wait_for_i2c_interrupt ; check buffer full? if not + goto slave_loop ; loop + call led_red ; else light LED red=received + call wait_for_i2c_interrupt ; wait for 2nd (data) byte + btg LATD,2,0 ; toggle colour of LED + goto slave_loop + + + ;**************************************************************************** +;**************************************************************************** + interrupt_high debug 'H' @@ -233,24 +283,59 @@ interrupt_high interrupt_low ; check which interrupt. - debug 'L' + btfsc PIR1,SSPIF,0 ; check if MSSP interrupt generated, if so +; goto interrupt_ms ; check whether master or slave + goto panic ; nothing should generate these ATM.... + btfsc PIR1,5,0 ; check whether serial receive interrupt bit set + ; if so + goto serial_receive ; receive serial + debug 'L' ; else panic goto panic -; serial only? -;**************************************************************************** +interrupt_ms + movlb I2C_BUFF_PAGE ; ser BSR=i2c BSR (4) + btfsc I2C_CTRL,I2C_MASTER ; check =master?, if so + goto interrupt_master ; goto master interrupt routine + goto interrupt_slave ; elso goto interrupt_slave -serial_receive - debug 'S' + +;---------------------------------------------------------------------------- +interrupt_master + debug 'm' goto panic -; serial byte to say pic #, LED flash pattern, look pattern up in table? -; (to test use of flash memory and lookup therein) -; think about serial msg format (in general and (simpler) for here) +;---------------------------------------------------------------------------- +interrupt_slave + debug 's' + goto panic ;**************************************************************************** +serial_receive + bsf SSPCON2,SEN,0 ; i2c START + call wait_for_i2c_interrupt + movlw 0x41 ; transmit address 0100 0001 + call wait_for_i2c_interrupt + btfss SSPCON2,ACKSTAT,0 ; check for ack from slave (=0), if no + goto panic ; then panic, else + movff RCREG,SSPBUF ; copy byte from serial to i2c buffer + call wait_for_i2c_interrupt + btfss SSPCON2,ACKSTAT,0 ; check for ack from slave (=0), if no + goto panic ; then panic, else + bsf SSPCON2,PEN,0 ; i2c STOP + call wait_for_i2c_interrupt + goto main_master + + +wait_for_i2c_interrupt + btfss PIR1,SSPIF,0 ; check if interrupt set, if not, loop + goto wait_for_i2c_interrupt + bcf PIR1,SSPIF,0 ; clear interrupt bit + return + +;**************************************************************************** led_green bcf TRISD,2,0 ; make pin RD2 an output (DS100) bsf LATD,2,0 ; set pin RD2 H (green) -- 2.30.2