julyjim
Posts: 117
Joined: Tue Jan 31, 2017 5:04 am

Writing data to BCM2835 - SPI

Sat Jun 09, 2018 4:05 pm

Up front
I am posting this here as a C/C++ request for assistance.
Please read and reply to the questions only.
I am not interested reading about anything else.
If you think I am to obnoxious , I am having bad experience from other forums where
people just cannot stay of the subject.

This is copy from BCM2835 datasheet.
I do not understand the b) step.
There are several main registers in SPI - CS and FIFO being of my current interest.

The FIFO register has single entry and should accept it with TA enabled.

So do I write to FIFO - data in single shot ( 32 bits wide )
and then poll CS TDX ?

Or do I have to do "writing bites " - what does that really means?

It seems that "writing BYTES" is a typo anyway.

Apparently I cannot read the FIFO - data after I write it.

10.6.1 Polled
a)
Set CS, CPOL, CPHA as required and set TA = 1.
b)
Poll TXD writing bytes to SPI_FIFO, RXD reading bytes from
SPI_FIFO until all
data written.
c)
Poll DONE until it goes to 1.
d)
Set TA = 0.

User avatar
joan
Posts: 13557
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Writing data to BCM2835 - SPI

Sat Jun 09, 2018 5:17 pm

pigpio and the bcm2835 C libraries both control the SPI hardware at this level.

StuartF
Posts: 27
Joined: Sun Feb 02, 2014 5:41 pm

Re: Writing data to BCM2835 - SPI

Sat Jun 09, 2018 9:20 pm

SPI is a duplex operation.
As you write data out on MOSI signal, data can come in on the MISO signal from the slave device.
This TX & RX is using the same CLK. This CLK is generated by the master.
To kick a slave into transmitting, you have to generate the CLK. This is done by 'writing' to the FIFO.
So when 'reading' the FIFO, it is a byte from the slave for the byte you wrote.

If you sent a command byte to the slave to read 32 bit data back, you would have to write 5 bytes
to the FIFO to read the returned bytes.

julyjim
Posts: 117
Joined: Tue Jan 31, 2017 5:04 am

Re: Writing data to BCM2835 - SPI

Sun Jun 10, 2018 12:25 am

Sorry, that is not what I asked.
I had to add more feedback to the function so I can monitor the progress.
It still looks as "write to FIFO - DATA " and monitor CS - DONE is about all that is needed to transmit via MOSI .
When I get that done I can "wire loopback" and read "MISO" back.

LdB
Posts: 856
Joined: Wed Dec 07, 2016 2:29 pm

Re: Writing data to BCM2835 - SPI

Sun Jun 10, 2018 9:57 am

You are correct you just write and monitor the done signal if you want to pick the transmission completion which can be done by polling or hooking up INTD to interupt.

When you write to the fifo there is no way to read it back .. it's gone.

Look at block 10.4 the read and write fifo are separate things so you can't "read or see" what is in the transmit fifo the read fifo is a whole different fifo. So if you wish to abort a transfer you need to work out a sequence that involves flushing what is in the write fifo by hiting the CLEAR fifo bit.

julyjim
Posts: 117
Joined: Tue Jan 31, 2017 5:04 am

Re: Writing data to BCM2835 - SPI

Sun Jun 10, 2018 1:04 pm

Thanks for confirming my suspicion.
Since the "DONE" signal never materialize I was just curious what else I can check if I have the SPI set ALL correctly. I guess I'll trace all the SPI set-ups and hopefully find the missing one.
I may have bypassed setting the ALT0 functions while coding something else.
Setting / verifying defaults set to zero has been a challenge .
I should end up with a list of all the SPI setting steps.
Thanks again.

julyjim
Posts: 117
Joined: Tue Jan 31, 2017 5:04 am

Re: Writing data to BCM2835 - SPI

Thu Jun 14, 2018 1:42 am

Please read this as C/C++ question on how to code BCM2835

10.6.1 Polled
a)
Set CS, CPOL, CPHA as required and set TA = 1.
b)
Poll TXD writing bytes to SPI_FIFO, RXD reading bytes from
SPI_FIFO until all
data written.
c)
Poll DONE until it goes to 1.
d)
Set TA = 0.

I am back,
I am still not sure how to write the data.
I went back to basic and found this so far
Clearing the SPI_CS register , writing all zeroes to it , should reset all SPI required "stuff" - for example spi mode.
Clearing , writing zeroes to TX , RX FIFO should have no effect.
After reading the SPI_CS register back I get TXD bit 18 set to 1 - ready to "accept a byte".
When I set TA , bit 7 - I am reading back bit 18, 16, and 7
Bit 16 set is DONE !
Done what?
Reading SPI_CS register again I get bit 18 ONLY!
No 16 or 7 , zero on 7 indicating "end of transfer".
.
Bit 18 never changes.

I have not set any FIFO _DATA , so I am assuming SPI DATA is garbage.
I can never read FIF0 register DATA ,always all zeroes.

I am little confused with "pooling bytes" - I want to set 32 bits and monitor DONE for completion.
I do not care if it goes out on hardware, I want to make sure I am doing it correct in software first.

I'll tackle "pooling" AKA sending more than 32 bits data after I get this fixed.

I suspect I need to set FIFO - DATA before setting TA , and that is what I''l do next.

Please read this as C/C++ question on how to code BCM2835

My goal is to use ioctl function, so this is just stepping stone for me.

User avatar
Arjan
Posts: 256
Joined: Sat Sep 08, 2012 1:59 pm

Re: Writing data to BCM2835 - SPI

Fri Jun 15, 2018 8:51 am

10.6.1 Polled
a)
Set CS, CPOL, CPHA as required and set TA = 1.
b)
Poll TXD writing bytes to SPI_FIFO, RXD reading bytes from
SPI_FIFO until all
data written.
c)
Poll DONE until it goes to 1.
d)
Set TA = 0.

The above can be implemented as follows:

Code: Select all

void bcm2835_spi_writenb(const char* tbuf, const uint32_t len) {
	uint32_t i;

	// Clear TX and RX fifos
	BCM2835_PERI_SET_BITS(BCM2835_SPI0->CS, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR);
	// Set TA = 1
	BCM2835_PERI_SET_BITS(BCM2835_SPI0->CS, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA);

	for (i = 0; i < len; i++) {
		// Maybe wait for TXD
		while (!(BCM2835_SPI0->CS & BCM2835_SPI0_CS_TXD))
			;
		// Write to FIFO
		BCM2835_SPI0->FIFO = (uint32_t) tbuf[i];

		while ((BCM2835_SPI0->CS & BCM2835_SPI0_CS_RXD)) {
			(void) BCM2835_SPI0->FIFO;
		}
	}

	// Wait for DONE to be set
	while (!(BCM2835_SPI0->CS & BCM2835_SPI0_CS_DONE)) {
		while ((BCM2835_SPI0->CS & BCM2835_SPI0_CS_RXD)) {
			(void) BCM2835_SPI0->FIFO;
		}
	}

	// Set TA = 0
	BCM2835_PERI_SET_BITS(BCM2835_SPI0->CS, 0, BCM2835_SPI0_CS_TA);
}
Where BCM2835_PERI_SET_BITS is:

Code: Select all

#define BCM2835_PERI_SET_BITS(a, v, m)		a = ((a) & ~(m)) | ((v) & (m));
http://www.raspberrypi-dmx.org/
Open Source DMX/RDM/MIDI/OSC/Art-Net/sACN solutions

julyjim
Posts: 117
Joined: Tue Jan 31, 2017 5:04 am

Re: Writing data to BCM2835 - SPI

Fri Jun 15, 2018 1:09 pm

Sorry , been there , done that.
The code does the job , but gives no feedback, with the exception of monitoring DONE and TXD .
But TXD never changes!
For one thing - it assumes char to be output - AKA 8 bits.
The BCM2537 SPI_FIFO DATA register is 32 bit wide.
The "standard " SPI data is 8 bits wide , but the BCM hardware has "16 word".
SPI data size can be varied, but it is too early to experiment with that.
The code len is not SPI data length - it is the length of buffer to output to SPI.
I need to monitor single data send to SPI_FIFO DATA register BEFORE I do "len" of characters.
This code just ignores too many things - for example there are no "SPI commands" - some and it appears BCM hardware does , takes command + data in sequence.
Or switching form "command " to data by toggling SS / CEx is not there either.
Than "16 word" register would be useful for that.
This is bare-bones code not worthy spending time to modify it.

The bottom line - BCM datasheet is not telling the whole story, time to go to the source.
Cheers

User avatar
Paeryn
Posts: 2145
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Writing data to BCM2835 - SPI

Fri Jun 15, 2018 3:04 pm

julyjim wrote:
Fri Jun 15, 2018 1:09 pm
Sorry , been there , done that.
The code does the job , but gives no feedback, with the exception of monitoring DONE and TXD .
But TXD never changes!
For one thing - it assumes char to be output - AKA 8 bits.
The BCM2537 SPI_FIFO DATA register is 32 bit wide.
The "standard " SPI data is 8 bits wide , but the BCM hardware has "16 word".
SPI data size can be varied, but it is too early to experiment with that.
The code len is not SPI data length - it is the length of buffer to output to SPI.
I need to monitor single data send to SPI_FIFO DATA register BEFORE I do "len" of characters.
This code just ignores too many things - for example there are no "SPI commands" - some and it appears BCM hardware does , takes command + data in sequence.
Or switching form "command " to data by toggling SS / CEx is not there either.
Than "16 word" register would be useful for that.
This is bare-bones code not worthy spending time to modify it.

The bottom line - BCM datasheet is not telling the whole story, time to go to the source.
Cheers
As to the FIFOs being 16 words, I read that as 16x 8-bit words as 8 bits is the common SPI unit. Though words could be longer for use in LoSSI mode where data being read can be up to 32-bits long (if not then the FIFO would effectively be as small as 4 words long).

From what I gather from the bcm_peripherals data sheet, SPI_FIFO accepts 32-bit data because the hardware can automatically handle LoSSI format which can have 8, 24 or 32 bit incoming data. Also the 32-bits are needed for DMA mode where data is always transferred between the DMA and SPI blocks in 32 bits.
She who travels light — forgot something.

julyjim
Posts: 117
Joined: Tue Jan 31, 2017 5:04 am

Re: Writing data to BCM2835 - SPI

Fri Jun 15, 2018 3:44 pm

Just had a long walk to ponder on the statement of setting the RDX as an indicator that ONE bit is "received".
That is contradictory to SPI protocol of working with minimum of 8 bits.
Why would slave responded after receiving 1 bit?
I am still not sure what triggers the BCM hardware to actually START sending the data.
Perhaps SPI_FIFO_DATA needs to be set BEFORE TA is activated?
More stuff to experiment with.

User avatar
Arjan
Posts: 256
Joined: Sat Sep 08, 2012 1:59 pm

Re: Writing data to BCM2835 - SPI

Fri Jun 15, 2018 4:25 pm

julyjim wrote:
Fri Jun 15, 2018 1:09 pm
This code just ignores too many things - for example there are no "SPI commands" - some and it appears BCM hardware does , takes command + data in sequence.
Or switching form "command " to data by toggling SS / CEx is not there either.
Than "16 word" register would be useful for that.
This is bare-bones code not worthy spending time to modify it.
The code above writes n-bytes to the SPI interface. As it is designed for SPI output only, it just reads the FIFO and ignore the data.

What would this code ignore?
http://www.raspberrypi-dmx.org/
Open Source DMX/RDM/MIDI/OSC/Art-Net/sACN solutions

User avatar
Paeryn
Posts: 2145
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Writing data to BCM2835 - SPI

Fri Jun 15, 2018 6:47 pm

julyjim wrote:
Fri Jun 15, 2018 3:44 pm
Just had a long walk to ponder on the statement of setting the RDX as an indicator that ONE bit is "received".
That is contradictory to SPI protocol of working with minimum of 8 bits.
Why would slave responded after receiving 1 bit?
I am still not sure what triggers the BCM hardware to actually START sending the data.
Perhaps SPI_FIFO_DATA needs to be set BEFORE TA is activated?
More stuff to experiment with.
RXD set says there is at least one byte in the FIFO waiting for you to read. The hardware always transmits the whole byte sequentially, it doesn't (AFAIK) give you any indication nor control of the individual bit transfers.

You set TA before you start, then as soon as there is a byte waiting in the FIFO it transmits it. When you write a value to the FIFO register that byte is placed on the end of the buffer, if the buffer was empty it will immediately start sending it.
I don't know whether you are allowed to pre-fill the buffer before setting TA, the datasheet only says that data is read from / written to the buffers if TA is set so it may (or may not) ignore attempts to fill or drain the FIFOs when TA is clear (unless it is in DMA mode where the values are used to set SPIDLEN and SPICS at the start of a DMA transfer).
She who travels light — forgot something.

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 20489
Joined: Sat Jul 30, 2011 7:41 pm

Re: Writing data to BCM2835 - SPI

Fri Jun 15, 2018 8:19 pm

Isn't this the same as tis thread?

viewtopic.php?f=44&t=215982

Which one should I close to prevent ruthur duplication?
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Please direct all questions to the forum, I do not do support via PM.

julyjim
Posts: 117
Joined: Tue Jan 31, 2017 5:04 am

Re: Writing data to BCM2835 - SPI

Fri Jun 15, 2018 9:05 pm

Well , not really same.
I do not particularly like / want a thread ten miles long..
You are the moderator , you decide.

julyjim
Posts: 117
Joined: Tue Jan 31, 2017 5:04 am

Re: Writing data to BCM2835 - SPI

Fri Jun 15, 2018 9:20 pm

You set TA before you start, then as soon as there is a byte waiting in the FIFO it transmits it.

That is one of the questions I had.
Since I cannot read what I set to SPI_FIFO_DATA - how does it recognize if I write all zeroes as first data?
Seems like catch 22.

User avatar
Paeryn
Posts: 2145
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Writing data to BCM2835 - SPI

Fri Jun 15, 2018 10:15 pm

julyjim wrote:
Fri Jun 15, 2018 9:20 pm
Since I cannot read what I set to SPI_FIFO_DATA - how does it recognize if I write all zeroes as first data?
Seems like catch 22.
The very act of writing to the register puts the value you write onto the TX FIFO.

Hardware registers, whilst looking like normal memory locations, aren't necessarily like that. Instead of being sent to the memory chip for storage it gets routed to the SPI hardware, the hardware knows that if a write request to this location happens then it is to take the value off the data bus and store it in the real TX FIFO memory at the appropriate location (the hardware will keep track internally where in the FIFO the next value is to be stored). Similarly if the cpu tries reading from that location the hardware will get the top value of the RX FIFO and put that on data bus.

So it doesn't matter what was last written to that register, the hardware isn't sat constantly reading a memory location looking for the value to change, it is the accessing of the register which triggers the hardware to do something.
She who travels light — forgot something.

julyjim
Posts: 117
Joined: Tue Jan 31, 2017 5:04 am

Re: Writing data to BCM2835 - SPI

Sat Jun 16, 2018 2:38 am

Saying it different way - if the register is not memory but a hardware why did I went thru memory mapping process?
After all the register addresses in datasheet only the lower part of 32 bit address matches the datasheet
It is all dynamically mapped to different addresses every time start the app.

I wonder how it will work after I use ioctl.

Since some of this forum participants find my style offensive I am stepping down.
I may still read the mail , but I will no longer participate in any discussions where unspecified " style " is preferred over technical content.

Over and out.

User avatar
Paeryn
Posts: 2145
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Writing data to BCM2835 - SPI

Sat Jun 16, 2018 3:49 am

julyjim wrote:
Sat Jun 16, 2018 2:38 am
Saying it different way - if the register is not memory but a hardware why did I went thru memory mapping process?
After all the register addresses in datasheet only the lower part of 32 bit address matches the datasheet
It is all dynamically mapped to different addresses every time start the app.
Because the registers are mapped into the address space, that's the way ARM works. You write to them and read from them just like memory. Some of the registers may be memory, just not memory that is part of the normal RAM, and there is hardware that uses them for the specified roles.

You had to map them into your process' address space because Linux normally doesn't let you have access to them, if you try reading or writing to the addresses without mapping them first then the CPU will generate an exception because those addresses won't be valid for your process. When you map the addresses you are asking the kernel to set things up so that your process can access them.

The addresses in the datasheet are the physical bus addresses as seen by the VC4, the ARM's physical address space is mapped on to the VC4 address space via the VC4's MMU. The ARMs also have their own MMUs which map the virtual addresses that Linux uses onto the ARM physical address space. Take a look at the bcm2835-arm-peripherals doc pages 4 to 7, that explains the difference between the addresses used in the doc and the addresses you have to use (noting that the memory space the registers appear at for the ARM had to change for the RPi 2 & 3 due to the extra RAM).
She who travels light — forgot something.

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 20489
Joined: Sat Jul 30, 2011 7:41 pm

Re: Writing data to BCM2835 - SPI

Sat Jun 16, 2018 7:32 am

julyjim wrote:
Sat Jun 16, 2018 2:38 am
Saying it different way - if the register is not memory but a hardware why did I went thru memory mapping process?
After all the register addresses in datasheet only the lower part of 32 bit address matches the datasheet
It is all dynamically mapped to different addresses every time start the app.

I wonder how it will work after I use ioctl.

Since some of this forum participants find my style offensive I am stepping down.
I may still read the mail , but I will no longer participate in any discussions where unspecified " style " is preferred over technical content.

Over and out.
Since you have received some exceptionally good technical content in the replies here, I find your post rather odd. Your writing style, as exemplified by this very post, is abrasive. It's odd you chose to stop posting, rather than simply adjust your writing, but that your choice. And your loss, not ours.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Please direct all questions to the forum, I do not do support via PM.

julyjim
Posts: 117
Joined: Tue Jan 31, 2017 5:04 am

Re: Writing data to BCM2835 - SPI

Sat Jun 16, 2018 2:57 pm

I will , reluctantly, reply.
( I need a brake from coding,. otherwise I really do not care any more posting ANYTHING here ).
It is obvious, to me, that forum participants are free to criticize my "abrasive style" and I am expected to change to some pleasing BS format.
I developed such style after people waste their and my time by posting irrelevant stiff.
I like to avoid such thus providing instruction in SOME of my posts.
Abrasive? Maybe. (People don't to want to be told HOW to replay - ME INCLUDED! )
I hope pussyfooting around issues is norm in these forums, but not on MY time.
I have learned long time ago that some people just cannot take the heat and need to have things served on silver platter.
Sorry, can't do.

Yes, I do gain much from TECHNICAL forums, but the notion that I do not appreciate that was uncalled for.
I guess coming from you it is not abrasive behaviour...

I hope this gets deleted soon, these "I am better than you" discussions are worthless.

Cheers

User avatar
joan
Posts: 13557
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Writing data to BCM2835 - SPI

Sat Jun 16, 2018 3:54 pm

Unfortunately the questions show that nothing has been learned from previous answers. There is a clear lack of understanding of SPI which should be understood after a look at wiki. Most of the questions are easily answered by looking at existing SPI code. I can only speak for myself but my patience is pretty thin for people who show no progress.

User avatar
DougieLawson
Posts: 33796
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: Writing data to BCM2835 - SPI

Sat Jun 16, 2018 3:58 pm

joan wrote:
Sat Jun 16, 2018 3:54 pm
Unfortunately the questions show that nothing has been learned from previous answers. There is a clear lack of understanding of SPI which should be understood after a look at wiki. Most of the questions are easily answered by looking at existing SPI code. I can only speak for myself but my patience is pretty thin for people who show no progress.
+1

I've had JulyJim on my forum block list for many months for the exceptionally abrasive attitude and the repeated failure to learn from the replies folks have given.
Microprocessor, Raspberry Pi & Arduino Hacker
Mainframe database troubleshooter
MQTT Evangelist
Twitter: @DougieLawson

2012-18: 1B*5, 2B*2, B+, A+, Z, ZW, 3Bs*3, 3B+

Any DMs sent on Twitter will be answered next month.

User avatar
Arjan
Posts: 256
Joined: Sat Sep 08, 2012 1:59 pm

Re: Writing data to BCM2835 - SPI

Sat Jun 16, 2018 5:13 pm

DougieLawson wrote:
Sat Jun 16, 2018 3:58 pm
joan wrote:
Sat Jun 16, 2018 3:54 pm
Unfortunately the questions show that nothing has been learned from previous answers. There is a clear lack of understanding of SPI which should be understood after a look at wiki. Most of the questions are easily answered by looking at existing SPI code. I can only speak for myself but my patience is pretty thin for people who show no progress.
+1

I've had JulyJim on my forum block list for many months for the exceptionally abrasive attitude and the repeated failure to learn from the replies folks have given.
+1

The same block (removal) should happen for this forum. When friendly behavior is not understand, then there is no other option.
Questions and comments should be positive and constructive.
http://www.raspberrypi-dmx.org/
Open Source DMX/RDM/MIDI/OSC/Art-Net/sACN solutions

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 20489
Joined: Sat Jul 30, 2011 7:41 pm

Re: Writing data to BCM2835 - SPI

Sun Jun 17, 2018 7:32 am

julyjim wrote:
Sat Jun 16, 2018 2:57 pm
I will , reluctantly, reply.
( I need a brake from coding,. otherwise I really do not care any more posting ANYTHING here ).
It is obvious, to me, that forum participants are free to criticize my "abrasive style" and I am expected to change to some pleasing BS format.
I developed such style after people waste their and my time by posting irrelevant stiff.
I like to avoid such thus providing instruction in SOME of my posts.
Abrasive? Maybe. (People don't to want to be told HOW to replay - ME INCLUDED! )
I hope pussyfooting around issues is norm in these forums, but not on MY time.
I have learned long time ago that some people just cannot take the heat and need to have things served on silver platter.
Sorry, can't do.

Yes, I do gain much from TECHNICAL forums, but the notion that I do not appreciate that was uncalled for.
I guess coming from you it is not abrasive behaviour...

I hope this gets deleted soon, these "I am better than you" discussions are worthless.

Cheers
The bs format is simply. Be nice to each other. Thats pretty much it. And you are unable to do it. There are system and means of getting technical help. Being an arse isn't one of them.

This is by far the best technical forum for Pi questions, so good luck elsewhere, you are going to find it very difficult to get anyone to give you the time of day with that attitude.

As for here, we don't need you or your behaviour.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Please direct all questions to the forum, I do not do support via PM.

Return to “C/C++”

Who is online

Users browsing this forum: No registered users and 8 guests