'****************************************************************** '* Name : gmbi2c.bas * '* Author : Graziano GAIBA * '* Date : 17/06/04 * '* Version : 1.1 * '* Board : GMM 876 + GMB HR84 * '* Language : PIC BASIC Standard Ver. 1.45 * '* Society : Copyright (c) 2004 grifo(r) ITALIAN Technology * '* : All Rights Reserved * '* : Tel.: +39 051 892052 Fax: +39 051 893661 * '* : http://www.grifo.com http://www.grifo.it * '* : E-mail: grifo@grifo.it * '****************************************************************** ' ' This demos allows to communicate to I2C BUS devices connected to CN3 ' of GMB HR84. It is possible to read or write bytes ' at any slave address and location address input by console. ' In detail, when reading the byte read is visualized and when writing ' the byte input is sent. ' ' For serial communication, the hardware serial port management code ' taken from example program Usart.bas is used, opportunely ' modified. ' ' ' ********************************************************************* ' * Definitions and Constants * ' ********************************************************************* ' ' PIC registers symbol INDF = 0 symbol FSR = $04 ' I/O Ports symbol PORTA = $05 symbol TRISA = $85 ' bank 1 symbol PORTB = $06 symbol TRISB = $86 ' bank 1 symbol PORTC = $07 symbol TRISC = $87 ' bank 1 ' I2C BUS symbol SSPCON2= $91 ' bank 1 symbol SSPBUF = $13 symbol SSPADD = $93 ' bank 1 symbol SSPCON1= $14 symbol SSPSTAT= $94 ' bank 1 ' symbol OPTION_REG = $81 ' bank 1 ' Registers used by hardware serial port management taken from ' demo Usart.bas del PIC Basic standard. ' USART registers Symbol PIR1 = $0C ' Peripheral Interrupt Flag register Symbol RCSTA = $18 ' Reception status and control register Symbol TXREG = $19 ' Data to send Symbol RCREG = $1A ' Data received Symbol TXSTA = $98 ' Transmission status and control register Symbol SPBRG = $99 ' Baud Rate Generator register ' ' ' ********************************************************************* ' * Variables used by the program * ' ********************************************************************* ' ' ' Used by USART SYMBOL UsartST = B0 ' USART status SYMBOL UsartOut = B1 ' Character to send symbol UsartIn = B2 ' Character received ' Value to be printed symbol Valore = B3 ' Generic use SYMBOL i = B4 SYMBOL c = B5 symbol z = B6 ' Hexadecimal data and addresses for I2C BUS symbol Slave_Address = B7 symbol Indirizzo = B8 symbol DatoIn = B9 symbol DatoOut = B10 ' Used by demo for EEPROM symbol Dato = B11 ' Used to input an hexadecimal value symbol ValoreHex = B12 ' ' ' ********************************************************************* ' * Main program * ' ********************************************************************* ' Main: gosub Module_init ' Initialisation for i=0 to 43 lookup i,("Demo Program of I2C BUS for GMM 876 Rel. 1.1"),usartout gosub charout next i Menu: gosub demoi2cbus goto menu end ' ' ' ********************************************************************* ' * Program end * ' ********************************************************************* ' ' ' Initialisation of GMM 876 Module_init: ' ' Initialise USART for 19200 Baud Poke SPBRG,64 ' Set baud rate to 19200 Poke RCSTA,%10010000 ' Enable serial port and continuous reception Poke TXSTA,%00100100 ' Enable transmission, asynchronous mode ' and high baud rate ' ' Initialisation for I2C BUS ' Configures RC3 and RC4 as inputs peek trisc, B0 bit3 = 1 bit4 = 1 poke trisc, B0 ' Activates module SSP in master I2C BUS mode, clock 50 kHz poke sspadd, $63 poke sspcon1, $28 ' Switch back to bank 0 before exiting from asm 'ASM 'ENDASM pause 500 return ' ' ' Demo to use I2C BUS hardware interface DemoI2CBUS: I2CBUSMenu: gosub nlcr for c=0 to 26 lookup c,("1) Read",13,10,"2) Write",13,10,"Choice: "), usartout gosub charout next c ' Waits for a character between "1" and "2" and prints it I2CBUSLoop: gosub CharIn if usartin < "1" or usartin > "2" then I2CBUSLoop c = usartin usartout = usartin gosub charout gosub nlcr ' Asks for an address in hexadecimal azioneI2CBUS: gosub inputslaveaddress gosub inputindirizzo ' If it is required to read, do it if c = "1" then I2CBUSRead ' Asks for an hexadecimal data gosub inputdato ' ' Writes data in input to the specified address ' ' Generates I2CBUS Start... gosub i2cbusstart '...and waits for it to complete gosub i2cbussynch ' Send Slave Address to write datoout = slave_address gosub i2cbussend ' If acknowledge is not received, print error message peek sspcon2, B0 if bit6 = 1 then notack ' Send address where to write data datoout = indirizzo gosub i2cbussend ' If acknowledge is not received, print error message peek sspcon2, B0 if bit6 = 1 then notack ' Send data datoout = dato gosub i2cbussend ' If acknowledge is not received, print error message peek sspcon2, B0 if bit6 = 1 then notack ' Send stop gosub i2cbusstop goto I2CBUSDone I2CBUSRead: ' ' Reads one byte from specified address ' for i = 0 to 6 lookup i,("Value: "), usartout gosub charout next i ' Generates I2CBUS Start... gosub i2cbusstart '...and waits for it to complete gosub i2cbussynch ' Send Slave Address to write datoout = slave_address gosub i2cbussend ' If acknowledge is not received, print error message peek sspcon2, B0 if bit6 = 1 then notack ' Send address from which to read data datoout = indirizzo gosub i2cbussend ' If acknowledge is not received, print error message peek sspcon2, B0 if bit6 = 1 then notack ' Generates second I2CBUS Start... gosub i2cbusrepstart '...and waits for it to complete gosub i2cbussynch ' Send Slave Address to read datoout = slave_address | $01 gosub i2cbussend ' If acknowledge is not received, print error message peek sspcon2, B0 if bit6 = 1 then notack ' Read data gosub i2cbusget valore = datoin ' Send NOT acknowledge... peek sspcon2, B0 bit5 = 1 bit4 = 1 poke sspcon2, B0 '...and waits for it to complete gosub i2cbussynch ' Send stop gosub i2cbusstop '...and waits for it to complete gosub i2cbussynch ' Print data read in variable Valore gosub stampahex gosub nlcr I2CBUSDone: for i = 0 to 18 lookup i,("Operation Completed"), usartout gosub charout next i I2CBUSGotoMenu: gosub nlcr goto I2CBUSMenu NotACK: for i = 0 to 23 lookup i,("Acknowledge not received"), usartout gosub charout next i goto I2CBUSGotoMenu I2CBUSEsci: goto menu ' ' ' Generates start I2C BUS I2CBUSStart: peek sspcon2, B0 bit0 = 1 poke sspcon2, B0 return ' ' ' Generates repetead start I2C BUS I2CBUSRepStart: peek sspcon2, B0 bit1 = 1 poke sspcon2, B0 return ' ' ' Generates stop I2C BUS I2CBUSStop: peek sspcon2, B0 bit2 = 1 poke sspcon2, B0 return ' ' ' Sends value of variable DatoOut to I2C BUS I2CBUSSend: poke sspbuf, datoout gosub i2cbussynch return ' ' ' Reads one byte from I2C BUS and store it in DataIn I2CBUSGet: peek sspcon2, B0 bit3=1 poke sspcon2, B0 I2CBusGetLoop: peek sspcon2, B0 if bit3=1 then I2CBusGetLoop peek sspbuf, datoin return ' ' ' Waits for the last I2C BUS operation to complete I2CBUSSynch: peek pir1, B0 if bit3 = 0 then I2CBUSSynch bit3 = 0 poke pir1, B0 return ' ' ' Transforms the value of variable Valore in hexadecimal and in ' ASCII characters then sends them to the serial port. ' Variable Valore must be in the range from 0 to 0FFh. StampaHex: usartout = valore / 16 gosub hexdecode gosub charout StampaNibbleHex: usartout = valore & $0F gosub hexdecode gosub charout return ' HexDecode: Lookup usartout,("0123456789ABCDEF"),usartout return ' HexEncode: lookDown usartin,("0123456789abcdef"),usartin return ' ' ' Moves to a new line NLCR: usartout = 10 ' New Line gosub charout CR: usartout = 13 ' Carriage Return gosub charout return ' ' ' Prints two space characters DueSpazi: usartout = " " ' Space gosub charout gosub charout return ' ' ' Moves to a new line, prints the messagge "Press a key..." then ' moves to a new line TastoPerUscire: gosub nlcr for z = 0 to 13 lookup z, ("Press a key..."),usartout gosub charout next z gosub nlcr return ' ' ' Input an hexadecimal value from 00 to FF then return it into the ' variable Dato InputDato: for z = 0 to 11 lookup z,("Data (Hex): "), usartout gosub charout next z gosub inputhex dato = valorehex return ' ' ' Input an hexadecimal value from 00 to FF then return it into the ' variable Slave_Address InputSlaveAddress: for z = 0 to 20 lookup z,("Slave Address (Hex): "), usartout gosub charout next z gosub inputhex slave_address = valorehex return ' ' ' Input an hexadecimal value from 00 to FF then return it into the ' variable Indirizzo InputIndirizzo: for z = 0 to 14 lookup z,("Address (Hex): "), usartout gosub charout next z gosub inputhex indirizzo = valorehex return ' ' ' Input an hexadecimal value from 00 to FF the return it into the ' variable ValoreHex and move to a new line InputHex: gosub charin if usartin = 0 then InputHex usartout = usartin gosub charout usartin = usartin | $20 gosub hexencode valorehex = usartin * 16 InputHex2: gosub charin if usartin = 0 then InputHex2 usartout = usartin gosub charout usartin = usartin | $20 gosub hexencode valorehex = valorehex + usartin gosub nlcr return ' ' ' Sends a character to USART transmitter ' (blocking) CharOut: Peek pir1,UsartST ' Get Flag in UsartST = B0 If Bit4 = 0 Then charout ' Wait for transmission register empty Poke TXREG,Usartout ' Put data in transmission register Return ' Return to caller ' ' ' Get a character from USART receiver ' (non blocking) CharIn: UsartIn = 0 ' Preset to no char received Peek PIR1,Usartst ' Get Flag in UsartST = B0 If Bit5 = 0 Then ciret ' If reception flag is 0, exit Peek RCREG,UsartIn ' Put received characther in UsartIn = B1 ciret: Return