CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

TCA9548A
Goto page Previous  1, 2, 3, 4  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PrinceNai



Joined: 31 Oct 2016
Posts: 455
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Jun 15, 2023 6:21 pm     Reply with quote

int8 0 frustration, my friend :-). Your goal is to post a question as specific as you can. So, a piece of code and what you want to achieve with it. The problem you have. The goal of everyone here is to help you, if the question is understandable. That is why there are questions regarding your code. To understand your problem. Some suggestions, if needed or not. When that is done, the first 90% of the solution will take the first 90% of the time and answers through iterations of your code. The remaining 10% will take the remaining 90% of the time. It works, believe it or not.
Ttelmah



Joined: 11 Mar 2010
Posts: 19236

View user's profile Send private message

PostPosted: Fri Jun 16, 2023 1:02 am     Reply with quote

OK.

I2C addresses are a consistent source of annoyance for everyone. If you
actually look at the datasheet for the ADXL, the manufacturer there is
very sensible, and gives both figures. So on page 17 for example:
Quote:

With the ALT ADDRESS pin high, the 7-bit
I2C address for the device is 0x1D, followed by the R/W bit. This
translates to 0x3A for a write and 0x3B for a read.


This is one of the nicest descriptions of this I have seen.

The point is that I2C has a '7 bit address', but this has to be sent to the
chip as the high seven bits of an 8bit value, with the R/W bit as the
bottom bit.
So a device with a 7bit address of 0x1D, has to be talked to on the bus
with address bytes of 0x3A for a write, and 0x3B for a read.
Now the transaction to an I2C device has as it's first byte, the 'address',
and it is this byte that the bus scanner returns.
The '7bit device address' is half the numbers the scanner returns, and
half the number that has to be sent to actually address the device.
If you are talking about the 'address byte', this is the 8bit value that
has to be sent.

Now, why the designers of I2C, decided to put the R/W bit at the bottom
of the register, and not the top, is a question that has never really been
answered satisfactorily. It means that the user must get clear in their
head the difference between the logical address, and the physical byte
that has to be used.

Some comments

First of all your chip supports 8MHz from the internal clock. Use this.
Pointless to run slower unless you are trying to same uW of power.

Then your response posted:

TCA Port 1#
Found 0X34

Tells you a device has been found on bus 1 at address 0x34. Now this
is a bit puzzling. Are you absolutely sure of the part numbers of the sensors
used?. The point is the ADXL345, is not means to be on this address.
Now chips can often be bought with custom I2C addresses (AD offer
this on these), so it suggests the chips fitted to the board you have are
not on the default addresses. Normally this is shown in the part number
on the device.

The second puzzling thing is that no chip was found on bus 0. You were
saying that you had a device on this bus as well. So look very carefully
at the wiring for this device. Or is this the one you tried to run with 5v
connections?. If so then I'm afraid it was destroyed.
Blackjackmaster



Joined: 14 May 2023
Posts: 30

View user's profile Send private message

TCA9548A
PostPosted: Fri Jun 16, 2023 7:28 am     Reply with quote

This is the code for the Arduino.

Code:
/**
 * TCA9548 I2CScanner.ino -- I2C bus scanner for Arduino
 *
 *
 */

#include "Wire.h"

#define TCAADDR 0x70

void tcaselect(uint8_t i) {
  if (i > 7) return;
 
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission(); 
}


// standard Arduino setup()
void setup()
{
    while (!Serial);
    delay(1000);

    Wire.begin();
   
    Serial.begin(115200);
    Serial.println("\nTCAScanner ready!");
   
    for (uint8_t t=0; t<8; t++) {
      tcaselect(t);
      Serial.print("TCA Port #"); Serial.println(t);

      for (uint8_t addr = 0; addr<=127; addr++) {
        if (addr == TCAADDR) continue;

        Wire.beginTransmission(addr);
        if (!Wire.endTransmission()) {
          Serial.print("Found I2C 0x");  Serial.println(addr,HEX);
        }
      }
    }
    Serial.println("\ndone");
}

void loop()
{
}


This is what I receive:
TCA9548 Scanner is Ready:
ACK addr: C0
ACK addr: C2
ACK addr: C4
ACK addr: C6
ACK addr: C8
ACK addr: CA
ACK addr: CC
ACK addr: CE
ACK addr: D0
ACK addr: D2
ACK addr: D4
ACK addr: D6
ACK addr: D8
ACK addr: DA
ACK addr: DC
ACK addr: EE

Number of i2c chips found: 16
Bus Array:
238

C0-DC do not go through the TCA9548A. This chip ALS31313 is controlled with voltage for addressing.


Quote:
. An alternate
I2C address of 0x53 (followed by the R/W bit) can be chosen by
grounding the SDO/ALT ADDRESS pin (Pin 12). This translates to
0xA6 for a write and 0xA7 for a read.



This is what the data looks like when I connect to the PIC16F877A directly to the ADXL345. The Address is A6.

TCA9548 Scanner is Ready:
ACK addr: A6
ACK addr: C0
ACK addr: C2
ACK addr: C4
ACK addr: C6
ACK addr: C8
ACK addr: CA
ACK addr: CC
ACK addr: CE
ACK addr: D0
ACK addr: D2
ACK addr: D4
ACK addr: D6
ACK addr: D8
ACK addr: DA
ACK addr: DC
ACK addr: EE

Number of i2c chips found: 17
Bus Array:
238

When the address show up in the Arduino code it is 96-110, not C0-DC.

TCA9548A Data
This is what the output looks like from Arduino. The address is different with the ADXL address.
[img]https://learn.adafruit.com/assets/27691[/img]

This is what I expected to see for each port/channel.

Thanks....
Ttelmah



Joined: 11 Mar 2010
Posts: 19236

View user's profile Send private message

PostPosted: Fri Jun 16, 2023 7:53 am     Reply with quote

One glaring thing here is that the Arduino code is for a TCA chip with
A0, A1 & A2 wired low, but you say yours has these pins wired high. That
is why the 7bit address is 0x70, not 0x77. 0x77*2 is 0xEE, while 0x70*2
is 0xE0.
The scan shows the TCA being found at EE, which then means it won't
be switching the bus, since the code tries to talk to it at 0xE0.....
Blackjackmaster



Joined: 14 May 2023
Posts: 30

View user's profile Send private message

TCA9548A
PostPosted: Fri Jun 16, 2023 9:46 am     Reply with quote

I am receiving E0 now.

Code:
printf("\n\rTCA9548 Scanner is Ready:\n\r");
for (int8 t=0; t<8; t++) {
      select_bus(t);
      printf ("\n\rTCA Port #: %u",t);
 
for (int8 addr=0; addr<=127; addr++) {

if (addr == TCAaddr) continue;
i2c_start ();
i2c_write(addr);
if (!i2c_stop())
{
printf ("\n\rFound I2C 0x%02x", addr);


I am getting an error here:
Code:
if (!i2c_stop())


*** Error 51 "U:\CCS C\I2C Scanner\TCA9548.c" Line 62(15,16): A numeric expression must appear here

I tried t,TCAaddr, and addr. Not sure what else to try.

The TCA will not pick up the port with PIC16F877A. I ran this hardware on the Arduino board and works fine.

Any suggestions?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jun 16, 2023 11:01 am     Reply with quote

Download the CCS manual and put it on your Windows desktop.
https://www.ccsinfo.com/downloads/ccs_c_manual.pdf

Look up i2c_stop() on page 319. The return value is listed as undefined.
You can't do an if() on it and have it be useful. Look at i2c example code on
this forum. Nobody does an if() on i2c_stop().
Blackjackmaster



Joined: 14 May 2023
Posts: 30

View user's profile Send private message

TCA9548A
PostPosted: Fri Jun 16, 2023 12:11 pm     Reply with quote

I did take a look at page 319.

My issues is I want to know when a device is connected to the TCA chip. Currently the program list all the available addresses of Port 0 00-255. I only want the address of what is connected to the port. any suggestions?
temtronic



Joined: 01 Jul 2010
Posts: 9120
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jun 16, 2023 3:24 pm     Reply with quote

You should be able to modify PCMP's 'I2C scanner' program in the code library.
Actually modify a COPY of it NOT the original......

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19236

View user's profile Send private message

PostPosted: Sat Jun 17, 2023 1:18 am     Reply with quote

That is what he has as the basis of his get_ack_status, at the very start
of the thread.
PrinceNai



Joined: 31 Oct 2016
Posts: 455
Location: Montenegro

View user's profile Send private message

PostPosted: Sat Jun 17, 2023 5:50 am     Reply with quote

I put together code from Mr.Ttelmah for selecting channels and PCM's I2C scanner. Scanner is inside one function to make main() easier to read. Names of some variables are changed so they are easier to read for me. I don't have your hardware, so I get 8 "Nothing found" from the code. Try it, maybe it works :-). Note that I forgot to clear device count before each channel is selected, so it will just count on.
Edit: corrected that, trimmed down the range of the scanner to avoid mux own address from being scanned.
Edit2: corrected how select_bus() is called
Code:

#include <18F46k22.h>
#device ADC=16
#device ICD=TRUE

//#fuses HS
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOPUT                   //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(internal=8000000)
#use rs232(baud=9600,parity=N,UART2,bits=8,stream=RS232,errors)
#use i2c(Master, slow,i2c1,force_hw)

unsigned int8 I2C_Address;
unsigned int8 status;
unsigned int8 Device_Count = 0;
int8 Channel;




#define TCAaddr 0xEE                                           //for A0,A1,A2=0b111
const int8 bus_array[8]={1,2,4,8,16,32,64,128};

void select_bus(int bus)
{
    if (bus > 7 )
        return;                                                //trap illegal bus numbers
    I2C_start();
    I2C_write(TCAaddr);
    I2C_write(bus_array[bus]);                                 //select specified bus number
    I2C_stop();                                                //I2C bus now routes to BUS number
}

//Then with the ADXL wired as described above, simply call
//    select_bus(0);
//And the ADXL will now be connected to the I2C bus with level
//translation.
//You then write to the ADXL as normal.


int8 get_ack_status(int8 address)
{
   int8 ack;

   i2c_start();
   delay_us(20);
   ack = i2c_write(address);                                   // Status = 0 if got an ACK
   i2c_stop();
   delay_us(20);
   if(ack == 0)
      return(TRUE);
   else
      return(FALSE);
}

void Get_I2C_Addresses(void){
// Try all slave addresses from 0x10 to 0xEF.
// See if we get a response from any slaves
// that may be on the i2c bus.
//   for(I2C_Address = 0x10; I2C_Address < 0xF0; I2C_Address+=2)   // original
   for(I2C_Address = 0x10; I2C_Address < 0xE8; I2C_Address+=2)   // trimmed down to avoid scanning mux address, just in case
      {
       status = get_ack_status(I2C_Address);
       if(status == TRUE)
         {
            printf("ACK addr: %X\n\r", I2C_Address);
            Device_Count++;
            delay_ms(100);
         }
      }
   
   if(Device_Count == 0){
      printf("Nothing Found\n\r");
      delay_cycles(1);
   }
   else{
      printf("Found: %u\n\r", Device_Count);
      delay_cycles(1);
   }
}




//=================================
void main(){
   output_float(PIN_B0);
   output_float(PIN_B1);


   for(Channel = 0; Channel < 8; Channel++){                     // loop through channels
   
      select_bus(Channel);
      printf("\n\rI2C Channel: %u\n\r", bus_array[Channel]);
      
      Device_Count = 0;
         
      Get_I2C_Addresses();                                       // complete I2C scanner as a function for a simpler main
      
   }
   while(1);



Last edited by PrinceNai on Wed Jun 21, 2023 10:48 am; edited 3 times in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19236

View user's profile Send private message

PostPosted: Sat Jun 17, 2023 6:56 am     Reply with quote

Just trim the count used for the scan 'down', below the address for the
multiplexer. So 0xE8 (say).
Problem is that the multiplexer is designed to load it's configuration
byte immediately after when it sees it's address. The data sheet for it does
not say what happens if it sees a stop at this point, so better to be safe
and not scan it's address.
Neatly done. Very Happy
Blackjackmaster



Joined: 14 May 2023
Posts: 30

View user's profile Send private message

TCA9548A
PostPosted: Mon Jun 19, 2023 9:09 am     Reply with quote

Hello,

Thank you to all that are responding.

I am able to see all the chips on the I2C that have voltage controlled addressing. I want to know how to get the addresses from the TCA. Here is what I receive from the Arduino code when I scan the TCA chip:

TCAScanner is ready
TCA Port #0
TCA Port #1
Found I2C 0x1E
TCA Port #2
TCA Port #3
Found I2C 0x1E
TCA Port #4
TCA Port #5
TCA Port #6
TCA Port #7

This tells me that I have a device connected to Channel 1 and Channel 3. These are ADXL345 chips. From here I can use select_bus (1) and read from the sensor.
Ttelmah



Joined: 11 Mar 2010
Posts: 19236

View user's profile Send private message

PostPosted: Mon Jun 19, 2023 9:38 am     Reply with quote

What Prince Nai posted should already do that for you. Just change
the loop to:
Code:

void main(void)
{
   output_float(PIN_B0);
   output_float(PIN_B1);


   for(Channel = 0; Channel < 8; Channel++)
   {                     // loop through channels
   
      select_bus(bus_array[Channel]);
      printf("\n\rTCA Port #%d",Channel);
     
      Device_Count = 0;
         
      Get_I2C_Addresses();   //I2C scanner
     
   }
   while(1);

Blackjackmaster



Joined: 14 May 2023
Posts: 30

View user's profile Send private message

TCA9548A
PostPosted: Mon Jun 19, 2023 11:21 am     Reply with quote

Hello,

This is the data from the code:

TCA Port #0ACK addr: A6
ACK addr: C0
ACK addr: C2
ACK addr: C4
ACK addr: C6
ACK addr: C8
ACK addr: CA
ACK addr: CC
ACK addr: CE
ACK addr: D0
ACK addr: D2
ACK addr: D4
ACK addr: D6
ACK addr: D8
ACK addr: DA
ACK addr: DC
ACK addr: E0
Found: 17

TCA Port #1ACK addr: A6
ACK addr: C0
ACK addr: C2
ACK addr: C4
ACK addr: C6
ACK addr: C8
ACK addr: CA
ACK addr: CC
ACK addr: CE
ACK addr: D0
ACK addr: D2
ACK addr: D4
ACK addr: D6
ACK addr: D8
ACK addr: DA
ACK addr: DC
ACK addr: E0
Found: 17

TCA Port #2ACK addr: A6
ACK addr: C0
ACK addr: C2
ACK addr: C4
ACK addr: C6
ACK addr: C8
ACK addr: CA
ACK addr: CC
ACK addr: CE
ACK addr: D0
ACK addr: D2
ACK addr: D4
ACK addr: D6
ACK addr: D8
ACK addr: DA
ACK addr: DC
ACK addr: E0
Found: 17

TCA Port #3ACK addr: A6
ACK addr: C0
ACK addr: C2
ACK addr: C4
ACK addr: C6
ACK addr: C8
ACK addr: CA
ACK addr: CC
ACK addr: CE
ACK addr: D0
ACK addr: D2
ACK addr: D4
ACK addr: D6
ACK addr: D8
ACK addr: DA
ACK addr: DC
ACK addr: E0
Found: 17

TCA Port #4ACK addr: A6
ACK addr: C0
ACK addr: C2
ACK addr: C4
ACK addr: C6
ACK addr: C8
ACK addr: CA
ACK addr: CC
ACK addr: CE
ACK addr: D0
ACK addr: D2
ACK addr: D4
ACK addr: D6
ACK addr: D8
ACK addr: DA
ACK addr: DC
ACK addr: E0
Found: 17

TCA Port #5ACK addr: A6
ACK addr: C0
ACK addr: C2
ACK addr: C4
ACK addr: C6
ACK addr: C8
ACK addr: CA
ACK addr: CC
ACK addr: CE
ACK addr: D0
ACK addr: D2
ACK addr: D4
ACK addr: D6
ACK addr: D8
ACK addr: DA
ACK addr: DC
ACK addr: E0
Found: 17

TCA Port #6ACK addr: A6
ACK addr: C0
ACK addr: C2
ACK addr: C4
ACK addr: C6
ACK addr: C8
ACK addr: CA
ACK addr: CC
ACK addr: CE
ACK addr: D0
ACK addr: D2
ACK addr: D4
ACK addr: D6
ACK addr: D8
ACK addr: DA
ACK addr: DC
ACK addr: E0
Found: 17

TCA Port #7ACK addr: A6
ACK addr: C0
ACK addr: C2
ACK addr: C4
ACK addr: C6
ACK addr: C8
ACK addr: CA
ACK addr: CC
ACK addr: CE
ACK addr: D0
ACK addr: D2
ACK addr: D4
ACK addr: D6
ACK addr: D8
ACK addr: DA
ACK addr: DC
ACK addr: E0
Found: 17


These are on the I2C Bus but none of them are going through the TCA. There is one sensor on the TCA and that is on Port 1 which does not show up. 0xE0 is the TCA.

Here is why I need this or equivalent chip. I have one board with 16 sensors on it. The product design can have up to 16 x 6 = 96 sensors. I have already used the the 16 addresses from the voltage levels with the sensor 96-110,0.

Is it possible the PIC16F877A is not compatible with I2C multiplexing?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 19, 2023 12:42 pm     Reply with quote

Is your test circuit setup like Figure 13 in this pdf ?
https://www.ti.com/lit/ds/symlink/tca9548a.pdf

Do you have pull-ups in all the places that the schematic shows ?
It shows 19 pullup resistors. Do you have them all in your test circuit ?
What are the values of the pull-ups ?

Do you have the 3 pullup resistors shown on the left side of the TCA9548A ?
What are their values ?

The schematic list several voltages: VdPUM, Vcc, and VdPUx.
What voltages are you using for each of those ?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3, 4  Next
Page 2 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group