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 CCS Technical Support

TCA9548A
Goto page 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
Blackjackmaster



Joined: 14 May 2023
Posts: 30

View user's profile Send private message

TCA9548A
PostPosted: Tue Jun 13, 2023 6:21 am     Reply with quote

Hello,

Is there a driver for this chip already created for CCS Complier?

I ran this code and it was not reporting anything:
Code:

#include <16F887.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(clock=4M)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

// This function writes the slave address to the i2c bus.
// If a slave chip is at that address, it should respond to
// this with an "ACK".   This function returns TRUE if an
// ACK was found.  Otherwise it returns FALSE.
int8 get_ack_status(int8 address)
{
int8 status;

i2c_start();
status = i2c_write(address);  // Status = 0 if got an ACK
i2c_stop();

if(status == 0)
   return(TRUE);
else
   return(FALSE);
}


//=================================
void main()
{
int8 i;
int8 status;
int8 count = 0;

printf("\n\rStart:\n\r");

delay_ms(1000);

// 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(i=0x10; i < 0xF0; i+=2)
   {
    status = get_ack_status(i);
    if(status == TRUE)
      {
       printf("ACK addr: %X\n\r", i);
       count++;
       delay_ms(2000);
      }
   }

if(count == 0)
   printf("\n\rNothing Found");
else
   printf("\n\rNumber of i2c chips found: %u", count);

while(1);
}
 


There are 10K pullups on the SDA and SCL line.

Regards....
Ttelmah



Joined: 11 Mar 2010
Posts: 19495

View user's profile Send private message

PostPosted: Tue Jun 13, 2023 7:07 am     Reply with quote

First thing, use the code buttons!...

It should be seen. 10K is rather large. 4.7K is normally recommended.
By default, since you don't specify a clock rate the unit will clock as fast
as possible. With 10K this may not be working. Reduce these.

Change your setup to:
Code:

#include <16F887.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(INTERNAL=4M)


Is your start message being seen?.

How are A0, A1 & A2 connected on the chip?.

How is RESET connected?. It says "Connect to VCC or VDPUM
(1) through a pull-up resistor, if not used".
Blackjackmaster



Joined: 14 May 2023
Posts: 30

View user's profile Send private message

TCA9548A
PostPosted: Tue Jun 13, 2023 9:38 am     Reply with quote

Hello,

I am using the PIC16F877A Development Kit from CCS. Reset is pulled up to 5V. I have changed the header file to [#include <16F877A.h>]. I also receive an error for no internal Osc.[#include <16F877A.h>
Code:
#fuses NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(INTERNAL=4M)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)]


I have changed the resistors to 3.1K (that is what I had). I removed the TCA9548A and connected straight to the sensor (with the pullups on SDA and SCL) from the PIC16F877A.

Update:

I do have the program running and nothing is connected to the bus and the program reports 112 Chips found.


Last edited by Blackjackmaster on Tue Jun 13, 2023 10:16 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19495

View user's profile Send private message

PostPosted: Tue Jun 13, 2023 10:14 am     Reply with quote

The 877A, does not have an internal oscillator. The 887 does. Hence that
error.

You won't see the sensor connected via the transceiver, until this is
programmed to enable whichever connection you use. You should though
see an ACK from the transceiver device itself. Where this will be seen
depends on how you have A0, A1 & A2 connected. This is why I asked about
these.
Without the transceiver, you should see an ACK from the sensor.
However you have not told us what chip this is?. It may well not support
the clock rate you are trying to use. A lot of sensors only support 100K.

#use i2c(Master, sda=PIN_C4, scl=PIN_C3, FAST=100K)

Some only support slow rates.
Blackjackmaster



Joined: 14 May 2023
Posts: 30

View user's profile Send private message

TCA9548A
PostPosted: Tue Jun 13, 2023 11:39 am     Reply with quote

Currently I have an ADXL345 Sensor connected straight to the PIC16F877A. I took out the mux because I want to see if this will work with a sensor directly wired to the Micro. The mux has A0,A1,A0 pulled high.
temtronic



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

View user's profile Send private message

PostPosted: Tue Jun 13, 2023 2:48 pm     Reply with quote

that's bad news....
adxl spec sheet...
Supply voltage range: 2.0 V to 3.6 V

that 877A PIC is FIVE volts....

POOF ! you've let the magic smoke out !!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19495

View user's profile Send private message

PostPosted: Wed Jun 14, 2023 12:42 am     Reply with quote

Ignoring the bang mode, the multiplexer would be on addresses 0xEE, and
0xE1 with the A0, A1 & A2 wired high. It should have been seen there on
your original test.
Now the multiplexer could have solved the level problem.
You'd have needed the multiplexer power by 5v. Then connect the ADXL
to SD0 & SCO,with it powered off 3.3v, and pull up resistors on these
lines to 3.3v.
You'd then program the TCA, with:
Code:

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

void select_bus(int number)
{
    if (number>7)
        return; //trap illegal bus numbers
    I2C_start();
    I2C_write(TCAaddr);
    I2C_write(bus_array[number]); //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.


The TCA will now route the I2C bus to the SD0/SC0 connections. So
with this done, the ADXL will now appear at it's I2C address on the bus.

There is no great programming involved in the multiplexer. All you have to
do is select it (by writing to it's address), and then send a single byte
with the bit set corresponding to the bus you want to use. The routine
shown handles this.
Blackjackmaster



Joined: 14 May 2023
Posts: 30

View user's profile Send private message

TCA9548A
PostPosted: Thu Jun 15, 2023 7:27 am     Reply with quote

Hello thank you for the routine. I was able to see 0XEE.

I am not sure where to put this routine.
Code:
#include <16F877A.h>
#fuses NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(crystal=20mHz)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3, FAST=100000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
// This function writes the slave address to the i2c bus.
// If a slave chip is at that address, it should respond to
// this with an "ACK".   This function returns TRUE if an
// ACK was found.  Otherwise it returns FALSE.

#define TCAaddr 0xEE //for A0,A1,A2=0b111


int8 get_ack_status(int8 address)
{
int8 status;

i2c_start();
status = i2c_write(address);  // Status = 0 if got an ACK
i2c_stop();

if(status == 0)
   return(TRUE);
else
   return(FALSE);
}
const bus_array[8]={1,2,4,8,16,32,64,128};
void select_bus(int number);

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

//=================================
void main()
{
int8 i;
int8 status;
int8 count = 0;

printf("\n\rStart:\n\r");

delay_ms(1000);

// 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(i=0x10; i < 0xF0; i+=2)
   {
    status= get_ack_status(i);
    if(status == TRUE)
      {
       printf("ACK addr: %X\n\r", i);
       count++;
       delay_ms(20);
      }
   }

if(count == 0)
   printf("\n\rNothing Found");
else
   printf("\n\rNumber of i2c chips found: %u", count);

while(1);

}


I am getting an "Expecting a Declaration" error. when compiling. I have the ADXL's on Channel 0 and Channel 1 on the TCA9548 and they are not recognized
Ttelmah



Joined: 11 Mar 2010
Posts: 19495

View user's profile Send private message

PostPosted: Thu Jun 15, 2023 9:16 am     Reply with quote

First thing:

void select_bus(int number);

There should not be a ';' at the end of this line.

Then in terms of where you use it, _before_ you talk to any bus.
You select the bus you want to use, then do the I2C transactions, and
once the transactions are complete, you then select the next bus and
perform the transactions on this.
It is a function to attach the I2C bus to a specified set of target
connections.

For I2C mode, CS on the ADXL needs to be tied high. Then if SDO is low
the device will be on A6/A7, if this is high then it'll be on 3A/3B.

Understand that at lower voltages the I2C pull up has to drop. The
maximum specified pull up current is normally 3mA. At 5v, this gives
about 1600R min resistor. At 3.3v, just 1100R.

So to see both devices, you'd need to select bus 0, then run the scan
code, then select bus 1, and run the scan code again on this bus.

Are you intending to have a lot more devices?. If not then get rid of
the multiplexer, and just add an I2C level shifter, and set the two
ADXL's to different addresses.
PrinceNai



Joined: 31 Oct 2016
Posts: 478
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Jun 15, 2023 9:19 am     Reply with quote

I found two mistakes, after that it compiles ok.

First: const bus_array[8]={1,2,4,8,16,32,64,128};
should be const int8 bus_array[8]={1,2,4,8,16,32,64,128};

and second you have one semicolon extra on the next line in the function.
Blackjackmaster



Joined: 14 May 2023
Posts: 30

View user's profile Send private message

TCA9548A
PostPosted: Thu Jun 15, 2023 11:21 am     Reply with quote

Thank you for the responses....

I added:
Code:
 printf("\n\rBus Array:\n\r %Lu", bus_array);




to see the bus array from the chip. I expected to see a 0 for channel 0 and 1 for Channel 1.

This is what I received:

Bus Array:
4112
Blackjackmaster



Joined: 14 May 2023
Posts: 30

View user's profile Send private message

TCA9548A
PostPosted: Thu Jun 15, 2023 11:32 am     Reply with quote

I tried this as well....

for (int8 number=0; number<8; number++) {
select_bus(number);
printf ("TCA Port #: %lu",number);
}
PrinceNai



Joined: 31 Oct 2016
Posts: 478
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Jun 15, 2023 11:51 am     Reply with quote

And what was the result?

I'd avoid using the same name for global and local variables or in function declarations(number). Makes it way harder to read and debug. Also if you declare something as int8, why using 16 bit printout (Lu)? What are you trying to print out? In your code you are not even using the function to select channel (void select_bus(int number); ). It is also easier to debug if you declare your variables as int8 or int16 instead of just int. That way you can see at once what kind of variable you are dealing with.
Ttelmah



Joined: 11 Mar 2010
Posts: 19495

View user's profile Send private message

PostPosted: Thu Jun 15, 2023 12:43 pm     Reply with quote

There is no code to read from the multiplexer here. The value you are
getting for 'BusArray', is just potentially it's address in the ROM. Means
nothing.
All the code does is turns on a switch in the multiplexer to connect the
processor I2C bus to the external I2C bus pair.

You do understand that the external busses need their own pull-ups,
and these have to go to the voltages supported by the external chips?.

You show code selecting the busses, but then don't do any transactions
on the selected bus.
Sequence needs to be:
Select BUS 0
Perform the device scan (but stop it at 0xE0 - you don't want to send
an address byte to the multiplexer -m this will potentially re-program
it....
Select BUS 1
Perform a second device scan - same comment

etc..
Blackjackmaster



Joined: 14 May 2023
Posts: 30

View user's profile Send private message

TCA9548A
PostPosted: Thu Jun 15, 2023 4:42 pm     Reply with quote

Hello,

The goal is this:

TCA Port 0#
TCA Port 1#
Found 0X34
TCA Port 2#....

I am trying to figure out how to detect the sensor and what port it is connected to. See the Link...

Is this possible with the configuration I am using? There is existing hardware that was developed and has one set of pullups for 16 chips and has Arduino software on it. I am not a software expert but I am working on converting this to the CCS compiler and PIC16F877A. I did look at the TCA9548A data sheet and it shows pullups for each sensor. The current system works fine but now it is time to make this without the Arduino Bootloader.

There are other issues I have as well. The current addresses are from 96-101. When I scan these sensors I get C0-D? ( I do not have the list with me) and then I have to divide by 2. One is processor treats it like a 7-bit and the other 8-bit. I have not figured out which is which yet.

I understand from the responses some frustration from the two that have responded. Thank you for your support and I apologize for the confusion.
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 1, 2, 3, 4  Next
Page 1 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