Menu

When zero is not zero! 00 is not 0 -- a deicmal error - Joys of debugging i2c and mcp23017

Help
ofuzzy1
2013-09-23
2013-09-25
  • ofuzzy1

    ofuzzy1 - 2013-09-23

    Two Issues:

    1. @ 16 Mhz we get a bus error on some writes, @ 4Mhz it is not an issue -- I will need explore that. And only on the triple write sequence. It occurs on both 00 or 0, so it is not related.

    2. 00 [decimal] is not 0

    xb= 00 is not zero but 0x13
    xb= 0 is zero

    Good

    main:
    xb = 0
    i2cWrite (IO_Chip6, IODIRA, xb)  ' make portA outputs
    i2cWrite (IO_Chip6, IODIRB, xb)  ' make portB outputs
    

    0

    0

    BAD!

    main:
    xb = 00
    i2cWrite (IO_Chip6, IODIRA, xb)  ' make portA outputs
    i2cWrite (IO_Chip6, IODIRB, xb)  ' make portB outputs
    

    not0
    not0

    [a $50 logic analyzer: http://dangerousprototypes.com/docs/Open_Bench_Logic_Sniffer]

    i2c data dump - .csv format

    "index","start-time","end-time","event?","event-type","data"
    "0","-42.000 ?s","-42.000 ?s","true","START",""
    "1","-38.000 ?s","84.000 ?s","false","","L"
    "2","92.000 ?s","92.000 ?s","true","ACK",""
    "3","98.000 ?s","228.000 ?s","false",""," "
    "4","236.000 ?s","236.000 ?s","true","ACK",""
    "5","244.000 ?s","372.000 ?s","false","",""
    "6","380.000 ?s","380.000 ?s","true","ACK",""
    "7","402.000 ?s","402.000 ?s","true","BUS-ERROR",""
    "8","402.000 ?s","402.000 ?s","true","STOP",""
    "9","414.000 ?s","414.000 ?s","true","START",""
    "10","418.000 ?s","540.000 ?s","false","","L"
    "11","548.000 ?s","548.000 ?s","true","ACK",""
    "12","554.000 ?s","684.000 ?s","false","",""
    "13","692.000 ?s","692.000 ?s","true","ACK",""
    "14","698.000 ?s","828.000 ?s","false","",""
    "15","836.000 ?s","836.000 ?s","true","ACK",""
    "16","858.000 ?s","858.000 ?s","true","STOP",""
    "17","870.000 ?s","870.000 ?s","true","START",""
    "18","874.000 ?s","996.000 ?s","false","","L"
    "19","1.004 ms","1.004 ms","true","ACK",""
    "20","1.012 ms","1.140 ms","false","",""
    "21","1.148 ms","1.148 ms","true","ACK",""
    "22","1.154 ms","1.280 ms","false","","ÿ"
    "23","1.288 ms","1.288 ms","true","ACK",""
    "24","1.312 ms","1.312 ms","true","STOP",""
    "25","1.324 ms","1.324 ms","true","START",""
    "26","1.328 ms","1.450 ms","false","","L"
    "27","1.458 ms","1.458 ms","true","ACK",""
    "28","1.464 ms","1.592 ms","false","",""
    "29","1.600 ms","1.600 ms","true","ACK",""
    "30","1.608 ms","1.734 ms","false","","ÿ"
    "31","1.742 ms","1.742 ms","true","ACK",""
    

    The Code

    -------------------------------------------------------------------
    ;Chip Settings
    #chip 16F1829, 16
    
    ;Include files (Libraries)
    ;#include <glcd.h>
    
    ;Defines (Constants)
    #define LCD_IO 4
    #define LCD_DB4 PORTC.0
    #define LCD_DB5 PORTC.1
    #define LCD_DB6 PORTC.2
    #define LCD_DB7 PORTC.3
    #define LCD_Enable PORTC.4
    #define LCD_RS PORTC.5
    #define LCD_NO_RW 'Needed when RW is grounded
    
    'I2C settings
    #define I2C_MODE Master
    #define I2C_DATA PORTb.5
    #define I2C_CLOCK PORTb.7
    #define I2C_Read_BIT  = 1
    #define I2C_Write_BIT = 0
    
    'Constants
    ' MCP23017 details
    #define IO_Chip6    0x26 ' NOT Shifted -- 0b01001100 ' the value $26 is shifted left 1 becuse of The RW bit: $26 << 1 = $4C
    ' use bank0 mode addresses
    #define IODIRA  0x00  ' default is INput  0= out 1= in
    #define IODIRB  0x01
    #define IPOLA   0x02  ' input polarity 0= normal, 1= inverted
    #define IPOLB   0x03
    #define GPINTENA    0x04  ' Allow interrupt on change
    #define GPINTENB    0x05
    #define DEFVALA 0x06  ' default value BEFORE interrupt [for easy compare]
    #define DEFVALB 0x07
    #define INTCONA 0x08 ' I/O EXPANDER CONFIGURATION .2 1= Open Drain [wire together interrupts]
    #define INTCONB 0x09
    #define IOCON   0x0A ' 0= Interrupt on change , 1= Interrupt on Difference
    #define IOCON   0x0B
    #define GPPUA   0x0C ' weak pull up resistors [~100kOhhm] very handy
    #define GPPUB   0x0D
    #define ITFA    0x0E ' who done it, the interrupt
    #define ITFB    0x0F
    #define INTCAPA 0x10 ' Saves the event that caused the interrupt
    #define INTCAPB 0x11
    #define GPIOA   0x12 ' the IO port
    #define GPIOB   0x13
    #define OLATA   0x14 ' the LATCH of the IO port see docs
    #define OLATB   0x15
    
    ;Variables
    Dim xB            As byte
    Dim i2cDevice    As byte
    Dim i2cAddress   As byte
    Dim i2cData      As byte
    
    ' Fixes a problem with LCD not working - thanks Kent!
    ' Don't assume that the digital is setup correctly.
    clrf ANSELa
    clrf ANSELb
    clrf ANSELc
    
    main:
    
    xb = 0
    i2cWrite (IO_Chip6, IODIRA, xb)  ' make portA outputs
    i2cWrite (IO_Chip6, IODIRB, xb)  ' make portB outputs
    
    'xb = 255 '0xFF
    xb = 0xFF
    i2cWrite (IO_Chip6, GPIOA, xb)  ' turn all pins on
    i2cWrite (IO_Chip6, GPIOB, xb)  ' turn all pins on
    Wait 250 ms
    
    xb = 0xAA '170
    i2cWrite (IO_Chip6, GPIOA, xb)  ' swap pins on/off
    i2cWrite (IO_Chip6, GPIOB, xb)  '
    Wait 250 ms
    
    xb = 0x55 '85 '
    i2cWrite (IO_Chip6, GPIOA, xb)  ' swap pins on/off
    i2cWrite (IO_Chip6, GPIOB, xb)  '
    Wait 250 ms
    
    xb =  0x00 '0 '
    i2cWrite (IO_Chip6, GPIOA, xb)  ' turn all pins oFF
    i2cWrite (IO_Chip6, GPIOB, xb)  ' turn all pins oFF
    Wait 250 ms
    
    cls
    Locate 0,2
    Print " wrote i2c "
    
    'for xb = 1 to 5
    'Locate 0,xb
    'Print " Hello World "
    'print xb
    'Wait 100 ms
    'next xb
    
    goto main
    end
    
    sub i2cWrite (i2cDevice, i2cAddress, i2cData) #NR
    
    i2cDevice = i2cDevice *2 ' *2 = << 1 ' is shifted left 1 because of The RW bit: $26 << 1 = $4C
     i2cstart
      I2CSend i2cDevice + I2C_Write_BIT  ' Who + how
      I2CSend i2cAddress             ' Where to put it
      I2CSend i2cData                ' What to put there
     I2CStop
    end sub
    
    'not tested yet ....
    Function i2cRead (i2cDevice, i2cAddress)
    i2cDevice = i2cDevice *2 ' *2 = << 1 ' is shifted left 1 because of The RW bit: $26 << 1 = $4C
     i2cstart
      I2CSend     i2cDevice + I2C_Read_BIT   ' Who + how
      I2CSend     i2cAddress             ' Where to GET it
      I2CReceive  i2cData                ' What to GET from there
     I2CStop
    i2cRead  =  i2cData
    end function
    
     

    Last edit: ofuzzy1 2013-09-23
    • Anobium

      Anobium - 2013-09-23

      I know this...

      00 will create an uninitialized BYTE variable. 0 is a value.
      With 00 being an uninitialized variable you then set this to your target variable.

      :-) Don't assign using 00.

      Hugh/Kent... why would this cause strange execution of the code?

       
  • kent_twt4

    kent_twt4 - 2013-09-23

    That's a pretty cool logic analyzer, for not much money.

    It looks like You have fooled the compiler. Is there a particular reason that you end up with dec 00 in the first place? If I wanted to send 00 then I would use a string value "00".

    EDIT: Or " 0"

     

    Last edit: kent_twt4 2013-09-23
  • Anobium

    Anobium - 2013-09-23

    The analyser looks very good! Ofuzzy - thanks for sharing.

     
  • Anobium

    Anobium - 2013-09-23

    The analyser looks very good! Ofuzzy - thanks for sharing.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.