i2cscanner single device, multiple device addresses

zmemw16
Tue Aug 18, 2015 9:08 pm
i’m trying to talk to the i2c at24c08 built into the board which is a
STM32F103ZET6 Minimum System Development Board ARM STM32 Cortex-m3 M75
from
http://www.ebay.co.uk/itm/291305557264? … EBIDX%3AIT

i2c scanner(from examples) shows this

Scanning…
I2C device found at address 0x50
I2C device found at address 0x51
I2C device found at address 0x52
I2C device found at address 0x53
done

the device address is known to be 0x50, so is this just bad address decoding or is it really returning 4 devices?
i’m inclined to the former:-)

the data sheet says single address and im trying to write and then read back from a location; mention is made of
a ‘repeated start.

so my code
int data;
#define Trigger PB3

void setup() {
pinMode(Trigger, OUTPUT);
digitalWrite(Trigger, LOW);
Serial.begin(115200);
Wire.begin();
}

void loop() {
digitalWrite(Trigger, HIGH); // ols trigger
Wire.i2c_start();
Wire.i2c_shift_out(0x50); // device address
Wire.i2c_get_ack();
Wire.i2c_shift_out(0x5a); // writing data to this address
Wire.i2c_get_ack();
Wire.i2c_shift_out(0xa5); // write data
Wire.i2c_get_ack();
Wire.i2c_stop();
delay(5);
Wire.i2c_start();
Wire.i2c_shift_out(0x50); // device address
Wire.i2c_get_ack();
Wire.i2c_shift_out(0x5a); // writing data to this address
Wire.i2c_get_ack();
data = Wire.i2c_shift_in(); // write data
Wire.i2c_get_ack();
Wire.i2c_stop();
digitalWrite(Trigger, LOW); //
delay(5);
}


fredbox
Wed Aug 19, 2015 4:26 am
I would suspect floating address lines on the 24c08, but the schematic shows that all address lines on the eeprom should be grounded. I believe this is the schematic for the board you have here. The schematic rar file contains a pdf, or there is a jpg here.

zmemw16
Wed Aug 19, 2015 8:46 am
i’ll do some probing with the multimeter and check the connections.
all as expected per circuit diagram. b6/b7 to chip & 4k7’s come as 4k67 to 3v3 pin; i’ll live with 0.64% low :-)

the spi flash is definitely marked as a Winbond 25X40BVN1G

data sheet says

Atmel AT24C08C, 8K Serial EEPROM: Internally organized with 64 pages of 16 bytes each, the 8K requires a 10-bit
data word address for random word addressing.


Acknowledge: All addresses and data words are serially transmitted to and from the EEPROM in eight bit words. The
EEPROM sends a zero to acknowledge that it has received each word. This happens during the ninth clock cycle.

crafty little b’s aren’t they(datasheets that is:-)

i was using pb3 as a trigger for the ols and getting a load of side effect, so switched to pg14
trigger line is now a single pulse!

stephen


zmemw16
Wed Aug 19, 2015 10:51 am
although i’m sending 0x20, the ols i2c analyser shows it appearing as 0x40

all the sda data seems to span the 8 clks and is extended to the first pulse for the next transmission

how do i send a set of 9 clocks as this is what seems to shift it left?

stephen


martinayotte
Wed Aug 19, 2015 2:56 pm
zmemw16 wrote:although i’m sending 0x20, the ols i2c analyser shows it appearing as 0x40

zmemw16
Wed Aug 19, 2015 5:16 pm
the 24c08 is mapped at 0x50, and is responsive to addresses 0x50-0x53 from i2cscanner

what i was trying to do was set the location in the chip that i want to read data from.

a complication is that it needs a 10 bit location, 0x00-0x3ff which i interpret as sending 2 bytes;
and i keep seeing a nack after the first.
others are
1. a repeated start?
2. nine clock cycles, i’ve only seen any mention of 9 bits in bit-bang i2c code

stephen


fredbox
Wed Aug 19, 2015 6:16 pm
Have a look at Nick Gammons forum here. There is a nice explanation of I2C with lots of pictures and an example of using an eeprom.

martinayotte
Wed Aug 19, 2015 6:42 pm
Although I’m not using 24C08, but 24C512 (also at 0x50 address), it should be pretty similar. I’m using it on my F4 without any problem.
Here are the snippet of code :

void WireEepromWriteByte(uint16_t theMemoryAddress, uint8_t u8Byte)
{
Wire.beginTransmission(EEPROM_ADDRESS);
Wire.write( (theMemoryAddress >> 8) & 0xFF );
Wire.write( (theMemoryAddress >> 0) & 0xFF );
Wire.write(u8Byte);
Wire.endTransmission();
delay(5);
}

uint8_t WireEepromRead(uint16_t theMemoryAddress)
{
uint8_t u8retVal = 0;
Wire.beginTransmission(EEPROM_ADDRESS);
Wire.write( (theMemoryAddress >> 8) & 0xFF );
Wire.write( (theMemoryAddress >> 0) & 0xFF );
Wire.endTransmission();
delay(5);
Wire.requestFrom(EEPROM_ADDRESS, 1);
u8retVal = Wire.read();
return u8retVal ;
}


zmemw16
Wed Aug 19, 2015 8:09 pm
code is
#include <Wire.h>

#define EEPROM_ADDRESS 0x50
byte data = 0;
#define Trigger PG14

void setup() {
pinMode(Trigger, OUTPUT);
digitalWrite(Trigger, LOW); // set trigger off)
Wire.begin();
}

void loop()
{
digitalWrite(Trigger, HIGH); // ols trigger
digitalWrite(Trigger, LOW); // ols trigger
delayMicroseconds(200);
WireEepromWriteByte(0x55, 0xaa);
data = WireEepromRead(0x55);
}


martinayotte
Wed Aug 19, 2015 8:33 pm
Oh ! I found some thing that I’ve completely forgot, since it is a long time I used those small AT23C02/04/08, I’m using bigger one since awhile, price differences both those are not quite big … ;)

The datasheet http://www.atmel.com/Images/doc3256.pdf mentioned that the addressing is done with a single byte, higher bits from the address should be ORed with the EEPROM address, so it is NOT 2 bytes addressing.

24c08.jpg
24c08.jpg (12.55 KiB) Viewed 1099 times

zmemw16
Wed Aug 19, 2015 9:07 pm
that’s what the p1/p0 bits are in the figure i put up are!!

Figure 8-1. Device Address
Density Access Area Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
8K EEPROM 1 0 1 0 A2 P1 P0 R/W

in fact i’m fairly sure i did a find on p1/p0, that table is the only place they occur
shouldn’t have got out of tech pubs that way

Standard EEPROM Access: The 4K and 8K EEPROM device requires an 8-bit device address word following a start
condition to enable the chip for a read or write operation. The device address word consists of a mandatory “1010” (0xA)
sequence for the first four Most Significant Bits (MSB) as shown in Figure 8-1 on page 11. This is common to all the
EEPROM devices.
The 4K EEPROM only uses the A2 and A1 device address bits with the third bit being a memory page address bit. The
two device address bits must compare to their corresponding hard-wired input pins. The A0 pin is no connect.
The 8K EEPROM only uses the A2 device address bit with the next two bits being for memory page addressing. The A2
address bit must compare to its corresponding hard-wired input pin. The A1 and A0 pins are no connect.
The eighth bit of the device address is the read/write operation select bit. A read operation is initiated if this bit is high and
a write operation is initiated if this bit is low.


zmemw16
Wed Aug 19, 2015 9:16 pm
it also explains the 0x50 – 0x53 responses

thanks


RogerClark
Wed Aug 19, 2015 10:04 pm
I Googled whether there were any existing libraries for this device, and found 2 or 3 different libraries.

IMHO, its probably work looking at libs that other people have written ( unless you are doing this just to improve your understanding of this chip and of I2C)


martinayotte
Wed Aug 19, 2015 11:24 pm
Yes, I’ve seen one awhile ago that support all different chips behaviors simply by providing chipNo in the constructor.
I will try to find it again, either on my drives or on the net …
So, @zmemw16, did you got chance to do some real Read/Write into your ? ;)

zmemw16
Wed Aug 19, 2015 11:46 pm
so here’s how your routines look now
void WireEepromWriteByte(uint16_t theMemoryAddress, uint8_t u8Byte) {
Wire.beginTransmission( EEPROM_ADDRESS | ( ( theMemoryAddress >> 8 ) & 0x3 ) );
Wire.write( theMemoryAddress & 0xFF );
Wire.write(u8Byte);
Wire.endTransmission();
delay(5);
}

uint8_t WireEepromRead(uint16_t theMemoryAddress) {
Wire.beginTransmission( EEPROM_ADDRESS | ( ( theMemoryAddress >> 8 ) & 0x3 ) );
Wire.write( theMemoryAddress & 0xFF );
Wire.endTransmission();
delay(5);
Wire.requestFrom( (EEPROM_ADDRESS | (theMemoryAddress >> 8) & 0x3), 1);
return Wire.read();
}


martinayotte
Thu Aug 20, 2015 12:04 am
zmemw16 wrote:] apols, but the >>0’s seemed extraneous:-)

zmemw16
Thu Aug 20, 2015 12:08 am
i thought it looked a bit like that in one of your links :-)

stephen


martinayotte
Thu Aug 20, 2015 12:21 am
martinayotte wrote:Yes, I’ve seen one awhile ago that support all different chips behaviors simply by providing chipNo in the constructor.
I will try to find it again, either on my drives or on the net …

RogerClark
Thu Aug 20, 2015 9:41 pm
Martin

Thanks

I will try to test that library at the weekend. I have multiple f103vet board, because of a screw up in eBay, and also 1 x f103zet, all of which have external EEPROMS


zmemw16
Fri Aug 21, 2015 1:49 am
i have had some success with those routines, however i have a nack appearing consistently.
i need to look at the diagrams again.

i also have a couple or more of 103 vet & zet boards, one or more have lcd connections.
there is a serious lot of variation in the lcd connections. 32/36/37/40 pins, 9 or 16 data lines, spi, /rd, /wr, touch etc etc

my next question is how do you find out how to drive one? i had a look at CubeMX and it appears to be down to
the vagaries of the wind as to how the FMSC is configured?
but i suspect that that’s another thread….

stephen


RogerClark
Fri Aug 21, 2015 1:55 am
Your best option on the F103VET and ZET is not to go down the CubeMx route just yet unless you want SDIO or possibly CAN (though CAN has issues as it shares its RAM with USB, making them virtually exclusive hardware)

SPI and I2C work fine in the Maple core.

Various displays have been ported, but they are mainly the I2C and SPI interface variety, however I think a few people were investigating porting some of the libs for the parallel connection displays

I have one of those 3.2in touch + LCD + SD screens, that has a 16 bit data path to the LCD, but I just don’t have time even to wire the thing up, let alone start looking at the libraries ;-(


zmemw16
Fri Aug 21, 2015 3:20 am
my dad, was a mechanical engineer who used to acquire tools usually ancient ones; me, a non-practised mech eng
who went the computers, software and hardware interfaces route – i seem to be collecting assorted electronics.
keep me from too much tv couch in the long winter evenings:-)
so i have one or two 3.2 & other sizes tft lcd + touch + sd as well

actually i was looking at cubemx as it occurs to me that at some point these ‘enhanced’ boards need to be made usable and how do we in effect reverse engineer the ‘addressing’ of the enhancements.

thoughts from the variation of lcd connectors i’ve got so far,
i’ve got to find some 40 pin ide cables, extra long and with three connectors.
what would really make it easier would be port wide operations, 8 & 16 bits; maybe that already exists?
maybe a way of merging ‘bits’ such that you could read/write 8 or 16 bits hiding the way they might be split up
pa0-pa3, pb4-pb7, pc0, pc3, pd4-pd9 sort of thing.
my excuse is it’s 0415
stephen


RogerClark
Fri Aug 21, 2015 3:57 am
It is possible to do a port wide write, but there isnt an API for it

You’d need to write to the output data register, but its really easy, I think its something like

GPIOA->dev->odr = 0x1234;


Leave a Reply

Your email address will not be published. Required fields are marked *