I2C and the MAX7318, need help with address space past $2E


Closed Thread
Results 1 to 3 of 3
  1. #1
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151

    Default I2C and the MAX7318, need help with address space past $2E

    Hello All-
    The project is a 16x16 audio matrix switch in which I have to connect any 1 of 16 25v intercom masters with any of 16 25 volt speakers.
    I am runniing it on a 18F2620 under PBP3 GOLD. I have a large motherboard with 16 'slots' and into each 'slot' I put a daughter card which contains a MAX7318 which is configured to be outputs and uses I2C.
    I am writing to a MAX7318 port expander which looks like a good part in that it will allow up to 64 8 bit ports as either inputs or outputs. It uses a nift 3 pin address scheme in which you tie the 3 pins to +5, GND, SCL, or SDA to get to all of the addressses.
    My code works well for the 1st 8 bit block ($20-$2E) but when I try to write to the next address block $30-$3E it does not work.
    What DOES work is if I address my 8 cards to be $A0-$AE I can get to them and turn on relays.
    Now for even more, the addressing in this space does not work out to be linear like it did with the $20. I have to address the cards to be in this order to be lionear (one after the other); $A0, $A8, $A4, $AC, $A2, $AA, $A6, $AE.
    What is interesting is that I am off by $40 and if you look at the low order byte of the $Ax addresses, they look like the low order is backwards - Huh?

    I have the work around to get the proper relays to fire with the proper inputs but what I don't understand is why do I have to do this?
    Board design looks fine and I could not find any errata on the MAX part.

    Code is cut and paste for the important parts:
    #CONFIG
    __CONFIG _CONFIG1H, _OSC_INTIO67_1H ;Osc=INT, Port on RA6,Port on RA7
    __CONFIG _CONFIG2L, _PWRT_ON_2L & _BOREN_ON_2L & _BORV_1_2L
    ;Power Up Timer is ENABLED
    ;Brown Our Reset is ENABLED
    ;BOR is just under MAXIMUM (0)
    __CONFIG _CONFIG2H, _WDT_OFF_2H ;Watchdog Timer is DISABLED
    __CONFIG _CONFIG3H, _MCLRE_ON_3H & _PBADEN_OFF_3H ;MCLR pin 1 is now RESET

    ;PORTB A/D is DISABLED (digital on reset)
    __CONFIG _CONFIG4L, _LVP_OFF_4L & _STVREN_ON_4L & _XINST_OFF_4L
    ;Low VOltage Programming OFF
    ;Stack Overflow is ENABLED
    ;Enhanced CPU is DISABLED
    __CONFIG _CONFIG5L, _CP0_ON_5L & _CP1_ON_5L & _CP2_ON_5L & _CP3_ON_5L
    ;Code Protect Block 0, 1, 2, 3
    #ENDCONFIG

    '---------------------------------------------------------------------------------------
    'Define the oscillator and setup the INCLUDE files
    DEFINE OSC 8 '8 MHz oscillator, internal
    INCLUDE "DT_INTS-18.bas" 'Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas" 'Include if using PBP interrupts

    '---------------------------------------------------------------------------------------
    'OKAY, Lets set up the registers.....
    T1CON = %00000000 'DISABLES timer1
    INTCON = %11100000 'DISABLES INT0 pin
    CMCON = %00000111 'Comparators are OFF
    OSCCON = %01110000 'set register for 8mhz
    ADCON0 = %00000000 'A2D is DISABLED
    ADCON1 = %00001111 'All PORTA and PORTB bits are digital
    '---------------------------------------------------------------------------------------
    'Direction registers
    'Direction Registers
    TRISA = %11011000 'PORTA for bit3,4,6,7 as INPUTS, resr OUTPUTS
    TRISB = %00111111 'PORTB for bits 7,6 as OUTPUTS, rest are INPUTS
    TRISC = %11110111 'PORTC for bits 3 as OUTPUT, rest INPUTS
    '----------------------------------------------------------------------------------------
    '----------------------------------------------------------------------------------------
    'Assembly routine for the heartbeat LED, serial input, all courtesy from the Man - D.T.!
    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
    ; INT_Handler RX2_INT, _Get_char, PBP, yes
    INT_Handler TMR0_INT, _ToggleHeartBeat, PBP, yes
    endm
    INT_CREATE ; Creates the interrupt processor
    ENDASM
    T0CON=%10000101 'TMR0 enabled, 16 bit mode, use CLK0 (internal)
    'Low to High transition, use prescaler of 1:64
    @ INT_ENABLE TMR0_INT ;enable Timer 0 interrupts
    ;@ INT_ENABLE RX2_INT ;Enable Serial port input interrupt
    '--------------------------------------------------------------------------------------

    '-----------------------------------------------------------------------------------------
    'Additional I/O Definitions
    error var PORTB.6 'ERROR output, ACTIVE HIGH (LED)
    heart var PORTA.0 'Heartbeat to know we are online - ACTIVE HIGH
    LED1 VAR PORTB.7 'Network/ err activity LED1, ACTIVE HIGH
    LED2 VAR PORTA.5 'Network/ err activity LED2, ACTIVE HIGH
    LED3 VAR PORTA.2 'Network/ err activity LED3, ACTIVE HIGH
    LED4 VAR PORTA.1 'Network/ err activity LED4, ACTIVE HIGH
    GO var PORTA.6 'This is the strobe to process the command from the 1220
    ' not used var PORTA.4
    ' not used var PORTB.4
    All_Off var PORTC.1 'Turns OFF all relays
    In_Audio var PORTC.6 'Indicated the device number is the audio SOURCE
    Out_Audio var PORTC.7 'Indicated the device number is the audio OUTPUT (relay)
    Broad var PORTC.0 'Sets up a broadcast, all OTHER outputs not input will turn ON
    Reset var PORTC.5 'Clears the IN and OUT registers
    ' not used var PORTC.2
    Act var PORTA.7 'Bit used for 1=OFF, 0=ON (low active)
    idata var PORTC.4 'I2C data pin - put 4.7k pullup!
    iclock var PORTC.3 'I2C clock pin - put 4.7k pullup!
    '---following used for testing ONLY-----------------
    TX_out var PORTB.5
    RX_in var PORTA.3
    define SER2_BITS 8
    '------------------------------------------------------------------------------------------
    in_port1 con 0 'INPUT port 1 register on MAX7318
    in_port2 con 1 'INPUT port 1 register on MAX7318
    out_port1 con 2 'OUTPUT port 1 register on MAX7318
    out_port2 con 3 'OUTPUT port 2 register on MAX7318
    inv_port1 con 4 'INVERT port 1 register on MAX7318
    inv_port2 con 5 'INVERT port 2 register on MAX7318
    confg_port1 con 6 'CONFIGURATION port 1 register on MAX7318
    confg_port2 con 7 'CONFIGURATION port 2 register on MAX7318
    '------------------------------------------------------------------------------------------
    'Variable List
    errcnt var byte 'Loop counter variable to hold the error LEDs on for a bit
    ireg var byte 'Port register on the MAX 7318
    DEV var byte 'This is the TEMP variable from the 1220
    Rly var byte 'Variable for the RELAY on which to perform the action
    Daughter var byte 'Variable which is the audio daughterboard
    in_h var byte 'MSB of the MAX7318 for the relay
    in_l var byte 'LSB of the MAX7318 for the relay
    invar var byte 'Var which hold the INPUT audio source
    outvar var byte 'Var which holds the relay out for the MAX7318
    inport var word 'Var which holds the bit value for the output relay
    outboard var byte 'Var which holds the I2C address of the requied output channel
    My_Flags var byte 'Var which holds various flags
    Cmd var My_Flags.0 'Command flag, 1 means we have already had a CLOCK

    '---------------------------------------------------------------------------------------------
    'Subroutines here

    PortInit:
    'Now set up all possible MAX7318s with both ports as OUTPUTS & turn OFF
    'There can be a possible 16 MAX7318 port expanders.
    'So, we need 16 address locations starting at$20
    'I can set up the direction register with one command as it operates on the register called out
    'The MAX7318s take up 2 address so, we need 32 addresses for up to 16 devices due to bit 0 being R/W
    'in the address then it AUTOMATCALLY address the next register in the pair

    for outboard=$20 to $3E step 2 'Counter to get all 16 devices
    ireg=confg_port1
    i2cwrite idata,iclock,outboard,ireg,[0,0],errled_I2C 'Set the config reg and make all bits OUTPUTS
    ireg=out_port1
    pause 10 'A pause that refreshes and gives the part to send an ACKNOWLEDGE
    i2cwrite idata,iclock,outboard,ireg,[0,0],errled_I2C 'Ensure outputs are OFF (active HIGH)
    pause 10 'A pause that refreshes and gives the part to send an ACKNOWLEDGE
    next outboard
    return

    Lkup_in:
    'This is where we resolve the needed relay out to an actual port address in low and high byte configuration.
    'The high order byte is inverted due to a board layout mistake.
    lookup2 invar,[0,1,2,4,8,16,32,64,128,32768,16384,8192,4096,2048, 1024,512,256],inport
    in_h=inport.highbyte
    in_l=inport.lowbyte
    return

    Lkup_out:
    'This subroutine will look up the correct board address for the I2C communication
    lookup outvar,[0,$20,$22,$24,$26,$28,$2A,$2C,$2E,$30,$38,$34,$3C, $32,$3A,$36,$3E],outboard
    return
    Ser_in:
    'This subroutine is used to get data in as a debugging tool
    serin2 rx_in, 84, [WAIT("$"),dec2 invar,dec2 outvar]
    return

    Ser_out:
    'This subroutine is used to get data out to a terminal for debugging
    serout2 tx_out, 84,["Input Source= ",dec2 invar, " Output board= ",dec2 outvar," Output addr= ",HEX2 outboard,$0D]
    return

    All_Rly_Off: for outboard=$20 to $3E step 2 'Counter to get all 16 devices
    ireg=out_port1
    i2cwrite idata,iclock,outboard,ireg,[0,0],errled_I2C 'Turn OFF all outputs
    pause 10 'A pause that refreshes and gives the part to send an ACKNOWLEDGE
    next outboard
    return


    Broadcast:
    'This subroutine takes ONE input and broadcasts to the other outputs
    gosub Lkup_in 'Get source of broadcast
    outvar=invar 'Get the address of the source channel
    gosub Lkup_out 'Get source board's address
    ireg=2 'We want the output register
    outvar=outboard 'Equate the originating address to var OUT
    for outboard=$20 to $3E step 2 'Setup ALL 16 boards
    if outvar=outboard then 'Check to make sure we don't broadcast to ourselves
    i2cwrite idata,iclock,outboard,ireg,[0,0],errled_I2C 'If we are the source, Reset the outputs
    else
    i2cwrite idata,iclock,outboard,ireg,[in_h,in_l],errled_I2C 'Set the output
    endif
    pause 10 'A pause that refreshes and gives the part to send an ACKNOWLEDGE
    next outboard 'Get the next output address
    outboard=0 : outvar=0 'Clears the outboard var
    return

    Clearvar: invar=0 : outvar=0 : inport=0 : outboard=0
    return

    ErrLed:
    'We get here when there has been an error
    ErrLed_I2C: High error : high led1 'Indicates an I2C err
    return

    ' The MAX 7318's are addressed such as:
    'Board Number - BD1 BD2 BD3 BD4 BD5 BD6 BD7 BD8 BD9 BD10 BD11 BD12 BD13 BD14 BD15 BD16
    'Board Addr space- 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E

    '################################################# ############################################
    '# Hookay Boyz, We are going to start this Pig!
    '################################################# ############################################
    init: invar=0 : outvar=0 'Sets vars to zero
    gosub PortInit 'Sets up the port xpanders and turns OFF the outputs
    low error : low led1 : low led2 : low led3 : low led4

    'test: gosub ser_in
    ' if in=0 AND out=0 then
    ' gosub all_rly_off
    ' goto test
    ' endif
    ' if in<>0 AND out=0 then
    ' gosub Broadcast
    ' goto test
    ' endif
    ' gosub lkup_in
    ' gosub lkup_out
    ' ireg=2
    ' i2cwrite idata,iclock,outboard,ireg,[in_h,in_l],errled_I2C 'Set the outputs
    ' gosub ser_out
    ' goto test

    Start:
    dev=0
    if cmd=1 and go=0 then goto start 'We are on the same command sequence, so wait for GO to go high
    if cmd=1 and go=1 then cmd=0 'Go is inactive so reset the cmd bit
    if go=0 then 'GO is LOW active
    Cmd=1 'Set the bit to let us know we are on the SAME command sequence
    ' if Reset=0 then gosub Clearvar 'Go clear all the input and output registers
    If all_off=0 then
    gosub all_rly_off 'Turn OFF ALL relays
    ' serout2 tx_out, 84,["All Relays shut OFF",$0D,$0B,$0A]
    goto start
    endif
    dev= (~PORTB) & %00011111 'INVERTS portB then stripsoff high 3 bits and save in var DEV
    if In_Audio=0 then invar=dev 'Device points to audio INPUT
    if out_audio=0 then outvar=dev 'Device points to relay on which to ACT
    ' serout2 tx_out, 84,["Device= ",dec2 dev," Broadcast= ", bin1 broad," All Off= ",bin1 all_off," In= ",bin1 in_audio," Out= ",bin1 out_audio, " Active= ", bin1 act," Invar= ",dec2 invar, " Outvar= ", dec2 outvar,$0D,$0B,$0A]
    Broadcst: if invar <> 0 and outvar = 0 and broad = 0 then
    gosub broadcast 'Go broadcast
    outboard=0 : outvar=0 'Clears the outboard var
    ' serout2 tx_out, 84,["Broadcast Input Source= ",dec2 invar, " Output board= ",dec2 outvar,$0D,$0B,$0A]
    goto start
    endif
    SingleON: if invar <> 0 AND outvar <> 0 and Act=0 then 'Check to see if we have set BOTH in and out and MODE=0
    gosub lkup_in 'Go get the relay needed high and low byte
    gosub lkup_out 'Go get the reqd board address
    ireg=2 'We need the output1 register
    ' serout2 tx_out, 84,["Single Channel Input Source= ",dec2 invar, " Output board= ",dec2 outvar," Board Addr= ",hex2 outboard,$0D,$0B,$0A]
    i2cwrite idata,iclock,outboard,ireg,[in_h,in_l],errled_I2C 'Set the outputs
    gosub clearvar 'Clears vars for next operation
    goto start
    endif
    SingleOFF: if invar =0 AND outvar <> 0 and Act=1 then 'Check to see if we have set BOTH in and out and MODE=0
    gosub lkup_out 'Go get the reqd board address
    ireg=2 'We need the output1 register
    i2cwrite idata,iclock,outboard,ireg,[0,0],errled_I2C 'Reset the outputs
    gosub clearvar 'Clears vars
    goto start
    endif
    endif
    goto Start

    Any help would be appreciated but I cannot see where the problem is especially when the lookup table works for the 1st 8 cards!
    I have searched this venerable forum but no one seems to have tried the Max part.

    Ideas?
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  2. #2
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151

    Default Re: I2C and the MAX7318, need help with address space past $2E

    Sorry guys, I didn't submit in good form.....
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  3. #3
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151

    Default Re: I2C and the MAX7318, need help with address space past $2E

    Found It!
    I was somehow reversing the address bits from the sheet for the x30 address space! Sheesh was a moron!
    The following works like a champ:
    Lkup_out:
    'This subroutine will look up the correct board address for the I2C communication
    lookup outvar,[0,$20,$22,$24,$26,$28,$2A,$2C,$2E,$30,$32,$34,$36, $38,$3A,$3C,$3E],outboard
    return
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

Similar Threads

  1. How to find I2C Slave address of PIC24FJ256GA110?
    By sharath12 in forum Off Topic
    Replies: 2
    Last Post: - 19th March 2012, 14:21
  2. A little blast from my past...
    By Byte_Butcher in forum Off Topic
    Replies: 2
    Last Post: - 9th January 2010, 02:16
  3. 4 bit address decoding I2C chip
    By ecoli-557 in forum General
    Replies: 3
    Last Post: - 10th June 2008, 17:26
  4. Setting Address via ADC
    By breesy in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 14th October 2007, 14:33
  5. 14 bit address for eeprom?
    By kf4mot in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 17th June 2007, 18:45

Members who have read this thread : 2

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts