Pages: [1] 2 3   Go Down
Author Topic: Reading MOSI data from Bosch ASIC  (Read 3189 times)
0 Members and 1 Guest are viewing this topic.
UK
Offline Offline
God Member
*****
Karma: 1
Posts: 530
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there,

EDIT - please see latest posts. EDIT.

I'm using a Bosch ASIC in a project I'm toying with, and am trying to communicate with the chip over SPI, essential to its use. However, the Bosch datasheet is incredibly thin on SPI information. Here's all the SPI information on the chip.





I'm struggling with how to write code to interface with this chip, in my SPI setup I've got the following, to correspond with the MSB first requirements, and the clock frequency set as the chip is max 2MBaud.

Code:
SPI.begin();
SPI.setBitOrder(MSBFIRST); // sets SPI data transfer to MSB first
SPI.setDataMode(SPI_MODE0); // sets SPI mode to MODE0
SPI.setClockDivider(SPI_CLOCK_DIV8); // sets shared clock rate to 16Mhz / 8 = 2Mhz

...and to actually read from a register, RD: 78H, I've got the following...

Code:
// select chip
digitalWrite(chip_select, LOW);

// send generic 01 address prefix

// send 78H hexadecimal address
SPI.transfer(0x78H);

// send parity?
SPI.transfer();

// send don't care, if needed?

// send 8 dummy bits of data

Any advice would  be greatly appreciated;

1) The generic 01 pre address, I'm not sure how to send this? What to type
2) I'm not sure what parity is?
3) Don't care, I guess I need to send a bit, 1 or 0?
4) How would I go about sending those 8 dummy bits?
5) That leads me into a whole other ball park, how do I go about reading/saving the bits sent back?

Many thanks in advance.
« Last Edit: January 24, 2013, 06:40:18 pm by jtw11 » Logged

0
Offline Offline
Shannon Member
****
Karma: 216
Posts: 12548
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Where is the link to the datasheet?
Logged

[ I won't respond to messages, use the forum please ]

UK
Offline Offline
God Member
*****
Karma: 1
Posts: 530
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Where is the link to the datasheet?

My bad...

http://www.bosch-semiconductors.de/media/pdf_1/einzeldownloads/engine_management/CJ125_Product_Info.pdf

EDIT - As you may have guessed, this is my first venture in to SPI. The hex values I've used in the above code, I've realised don't make sense to me as hex is A through F.... and I've got an H, so I've gone over to binary.

So if I want to transmit a 16bit dataframe, for example, to read the diagnoses register 78h, or decimal 120 - this is what I'm stuck with, where I put this address etc.
« Last Edit: January 24, 2013, 01:06:21 pm by jtw11 » Logged

0
Offline Offline
Faraday Member
**
Karma: 8
Posts: 2526
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

78H means 78 hex.  It's sometimes written as 78H.

In C we write it as 0x78, not 78H (and definitely not 0x78H).

Did 0x78H actually get past the compiler?  It shouldn't  My gcc (solaris and linux) dies with "error: invalid suffix "H" on integer constant" when I tried 0x78H.

-j
Logged

UK
Offline Offline
God Member
*****
Karma: 1
Posts: 530
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Did 0x78H actually get past the compiler?  It shouldn't  My gcc (solaris and linux) dies with "error: invalid suffix "H" on integer constant" when I tried 0x78H.

Ha, no don't worry - it did not. I hadn't yet attempted to compile as I knew the code was far from complete, just earlier on I did have a check and no, it threw it out with the same error as you stated.

The problem is, looking at the sequence - I need to enter

0, 1, address bit 1, address bit 2, address bit 3, address bit 4, parity bit (not sure what this is), then any bit as it's don't care, followed by 8 random bits. Found some more info here. http://www.breitband-lambda.de/pages/lambda---english/controlling-the-cj125.php?lang=EN

However, I'm not sure how to enter those 4 address bits, as I know I've now got 0x78, but have no idea how to enter this as four bits?

I'm thinking perhaps, send a 0, send a 1, send a four bit byte that corresponds to 0x78 (is there such thing as a four bit byte?, then send the parity bit, then either a 1 or 0.


EDIT - You know when you try and work something out all day, then for some reason it clicks. Well, it's clicked.

The address MUST be of the format 01xxxxx-, where x is 0 or 1, and - is don't care.

So, converting ALL the possible hex addresses to 8 bit binary, they all start 01, so for example - the diag register of 0x78 is 01111000, so to read from that one simply transmits 01111000, followed by any other 8 bits.

However, how do I go about capturing the data bits that come back in response?
« Last Edit: January 24, 2013, 05:08:32 pm by jtw11 » Logged

0
Offline Offline
Shannon Member
****
Karma: 216
Posts: 12548
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

SPI.transfer returns a byte result, capture those...
Logged

[ I won't respond to messages, use the forum please ]

UK
Offline Offline
God Member
*****
Karma: 1
Posts: 530
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

SPI.transfer returns a byte result, capture those...

That's exactly what I'm trying to achieve - I just don't know the syntax or whatnot to achieve this, the SPI library page in the playground has no mention either...
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 504
Posts: 19095
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

http://gammon.com.au/spi
Logged


Offline Offline
Faraday Member
**
Karma: 62
Posts: 3080
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Lots of datasheets have a description of the SPI protocol.  It doesn't mean you
have to implement it.

If the device works according to the SPI standards,    then the SPI implementation
on the Arduino should be able to talk to it.

If it doesn't,  give up.  I think it is beyond the capability of most people to identify the
problem, and how would you correct it, even if you could diagnose it ?

What this means,  is that you have to have the wiring correct.    And you have to be
making the correct calls from your arduino sketch to the functions of the SPI interface
library.
Logged

UK
Offline Offline
God Member
*****
Karma: 1
Posts: 530
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote

Brilliant, cheers. So, reading the text under heading "sending & receiving data", because the appropriate data is sent back is sent back at the same time as the data going out, let's check I understand this right.

SPI.transfer (4) would send the value of 4, of course - and writing an a = SPI.transfer(4) would capture the data returned as a result of sending a value of 4 out over SPI?

Code:
a = SPI.transfer (4);
// a is now 1

b = SPI.transfer (3);
// b is now 2

If I send my data as two binary bytes, as below for example, the data I then capture back using the above method, does that come back and save as a binary byte? I've added two entries in to my code to declare bytes to save the contents of the registers.

Code:
byte ident_reg_contents = B00000000;
byte diag_reg_contents = B00000000;

SPI.transfer(B01111000);
diag_reg_contents = SPI.transfer(B00000000);

Quote
If it doesn't,  give up

That somewhat defeats the point of learning to interface with the SPI bus....
« Last Edit: January 25, 2013, 03:10:30 pm by Nick Gammon » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 504
Posts: 19095
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

SPI.transfer (4) would send the value of 4, of course - and writing an a = SPI.transfer(4) would capture the data returned as a result of sending a value of 4 out over SPI?

No, as my page tries to explain.

As each bit is sent and received simultaneously it isn't possible for a single transfer to send data and receive a response (to that same data).

Quote
... because the appropriate data is sent back is sent back at the same time as the data going out, let's check I understand this right.

It is possible to receive valid data as you send stuff, but it won't be in direct response to the byte being sent.
Logged


UK
Offline Offline
God Member
*****
Karma: 1
Posts: 530
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
As each bit is sent and received simultaneously it isn't possible for a single transfer to send data and receive a response (to that same data).

Ah, okay. Maybe i've misunderstood the following from your web page, perhaps you could steer me on the correct track?

Quote
Basically, while the master hardware is clocking out bits on the MOSI line (master out, slave in) it is also clocking in bits on the MISO (master in, slave out). Effectively, during one character time, it both sends and receives one byte. Hence the name of the function SPI.transfer.

Code:
char a, b;

a = SPI.transfer (4);

// a is now 1

b = SPI.transfer (3);

// b is now 2

...as I have replicated this in my code, for example - to read the contents of the identification register, IDENT_REG, at address B01001000 - I have done as you have, declared storage for the received data, I have then sent out the address B01001000, then sent a second transfer B00000000. The second transfer being the dummy bits required to retrieve the contents of the register.

Code:
byte ident_reg_contents = B00000000;

SPI.transfer(B01001000);
ident_reg_contents = SPI.transfer(B00000000);

Certainly that's how this page is implying to do so - http://www.breitband-lambda.de/pages/lambda---english/controlling-the-cj125.php?lang=EN

The 'Read Access' bit of the datasheet shows that too, send the address - then send 8 dummy bits, and the return of each dummy bit is the corresponding register entry, MSB first.

Perhaps i'm missing something fundamental? Do you mean my methodology is wrong, or my syntax to save the returned data is wrong? If it's of any help, I have no compiler errors at all.

Many thanks so far!
« Last Edit: January 25, 2013, 05:40:22 pm by jtw11 » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 504
Posts: 19095
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
SPI.transfer(B01001000);

How about:

Code:
SPI.transfer(0x48);

That's easier to read, and matches the spec.

Their page seems to suggest the data is in 16-bit lots:



So without the device to hand it is hard to be sure. You could try the 16-bit approach:

Code:
SPI.transfer(0);  // MS byte
SPI.transfer(0x48);  // LS byte

byte result1 = SPI.transfer(0);
byte result2 = SPI.transfer(0);

And then try printing those.
Logged


UK
Offline Offline
God Member
*****
Karma: 1
Posts: 530
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I went over to binary to make dealing with setting individual bits on or off, as I can simply line them up with their graphical display in the datasheet. On that note, may one mix hex & binary in the same code?

Quote
Their page seems to suggest the data is in 16-bit lots

Yes, page 5 specifies a 16-bit data frame.

However, sorry - I'm not with you on your 16 bit approach example?
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 504
Posts: 19095
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Each transfer sends 8 bits, so 2 x transfer does 16 bits.
Logged


Pages: [1] 2 3   Go Up
Jump to: