|
|
View previous topic :: View next topic |
Author |
Message |
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
can spi_read() return 16bit value |
Posted: Sun Jul 15, 2012 11:13 am |
|
|
Hi every one!
The chip is 18f2520
May I receive a 16bit value into the SPI read buffer?
I'm wondering because the controller that sends me data, just send 16 bits of data.
In other words, can the function spi_read(data) to return a 16bit value?
Thanks a lot! |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Jul 15, 2012 11:54 am |
|
|
The SPI receiver effectively consists of two 8 bit registers. One is the receive shift register, and the actual buffer. (It's all in the data sheet.)
To receive 16 bit data you read both registers, (by reading the real buffer twice) then merge the two 8 bit chunks into one 16 bit chunk. The CCS manual says the spi_read() returns an 8 bit int!
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sun Jul 15, 2012 1:19 pm |
|
|
Seriously, just use two 8bit transfers.
If you are using the hardware, it only supports 8bits at a time, but it doesn't matter.
Best Wishes |
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Mon Jul 16, 2012 3:41 am |
|
|
May be you mean:
for merging the bytes, but what is the function that calls the seccont byte of SPI buffer?
Thank you guys! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Jul 16, 2012 4:10 am |
|
|
There is no 'second byte of spi buffer'.
Mike's comment is possibly a little misleading here.
SPI has a _one byte buffer_, and the physical receive shift register. SPI_INT triggers when the shift register fills, and this byte transfers to the buffer. Saying 'there is a single byte in the buffer available to read'. As _soon_ as the shift register fills, it's contents are transferred to the buffer, and anything already there is lost, if it has not already been read.
You have to read the first byte, and store it, then wait again for the signal to say 'byte has transferred', and read this. There is potentially up to 1.875 bytes of actual storage (the buffered byte is not lost till the final bit transfer occurs), but there are never two bytes available to you, and the shift register itself is not readable.
You can either use SPI_INT, or just poll the bit saying 'byte has transferred'. SPI_READ does this.
The point is that you have the time _while the second byte is being clocked in_, to store the first.
Code: |
int hi, lo;
hi=spi_read();
lo=spi_read();
//Both of these will _wait_, polling SPI_INT, until one byte has transferred
//to the buffer
|
Best Wishes |
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Thu Jul 19, 2012 10:43 am |
|
|
Oh I see! Thank you Ttelmah! |
|
|
JosedeJesusC
Joined: 29 Mar 2013 Posts: 24
|
|
Posted: Tue Apr 02, 2013 11:13 am |
|
|
Hi everyone.
I have read the CCS Compiler manual, and it makes mention about the #USE SPI and it allow you set the amount of bits to drive and which variable name you want, but I'm not sure if the buffer is extended to receive data larger than 8 bits are.
what do you think? is it true?
I'm going to try to receive 24 bits from the ADS1254 (delta sigma ADC) with the PIC 18f4550.
but till I get the device I can't test any.
The device (ADC) needs some time to send the 1 bit stream result I am not sure if using the #int_ssp
and spi_read(); give me that result from the ADS1254 or within the interruption I have to wait some time before to read the data.
I hope that someone can help me.
best regards!!!! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Tue Apr 02, 2013 11:40 am |
|
|
1) the use spi(..... bits=24)... creates code that takes your data in byte chunks and sends it to the SPI xmit buffer. Very efficient code. I use it for controlling RGB pixels using the WS2801 chip. Simply look at the 'disassembly listing' after you've compiled a working program.
2) the internal hardware SPI is only 8 bits wide (a byte) (a physical limit carved in silicon) however you can easily create your own software SPI that is 16 bits (or 10, 23, 100, etc)wide. This is done all the time in 'proprietary' systems using 'custom' components.
hth
jay |
|
|
JosedeJesusC
Joined: 29 Mar 2013 Posts: 24
|
|
Posted: Wed Apr 03, 2013 4:51 pm |
|
|
Hi temtronic!!!!
What do you mean with 'disassembly listing' and 'proprietary' systems using 'custom' components ?
I imagine that it's an option to compile the code or what is it? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Wed Apr 03, 2013 5:32 pm |
|
|
'disassembly listing' ...
Whenever you create a project in MPLAB, say using CCS C, the compiler generates a 'listing' file. This file consists of the 'source' code as well as the 'machine' code (or assembler).
If your project compiles without errors, this 'listing' file is created. From the MPLAB main screen, select 'view' and scroll down to 'disassembly listing'. Selecting it will load the 'listing' file onto the screen.
There will be several columns of numbers.
address, instruction in hex, machine code,a ssembler code, as well as the C code.
ie: delay_us(500); is C code but the compiler generates the necessary PIC assembler to execute a delay of 500 microseconds. C is a high level language, easier for us humans to understand, Assembler is 'closer' to 'machine code, and PICs really just want ones and zeros.
an example....
Code: |
66: delay_us(500); // delay 500us to latch the IC
0118 0E02 MOVLW 0x2
011A 6E4C MOVWF 0x4c, ACCESS
011C 0EFA MOVLW 0xfa
011E 6E4D MOVWF 0x4d, ACCESS
0120 D7CB BRA 0xb8
0122 2E4C DECFSZ 0x4c, F, ACCESS
0124 D7FB BRA 0x11c
67: }
0126 EF86 GOTO 0x30c
|
here line 66: is the code you typed in, what follows is what is generated by the compiler to be loaded into the PIC.
One reason to read listings is to see if improvements can be made either in speed or size. Size generally may not matter these days, PICs seem to have lots of memory but speed can be optimized depending on how the code is programmed.
'proprietory systems' refers to custom made equipment for a specific client. Think of a 'PC keyboard', generic, off the shelf...press the letter 'j' and a 'j' magically appears on the PC screen. A client may want a 'custom' or 'proprietory' event to happen, say press a 'j' and the screen goes purple.'Custom' components...think of video cards, bill validation, etc. where special components are used, not regular PC hardware.
hth
jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Thu Apr 04, 2013 12:32 am |
|
|
Basically, no, you can't extend the hardware buffer, but if you setup the spi to perform 16bit transfers, using the hardware, the compiler generates the most efficient code possible to do this.
It won't actually make any speed difference from doing it with your own two reads (since the limiting factor will be how fast the buffer fills twice), but instead of fetching two bytes, and then combining them, the 16 bit spi_read transfers the first byte into the top byte of the target variable, and then the second byte into the bottom byte of the variable directly, with no extra moves involved. Slightly more compact code, and uses less RAM.
You can actually do the same (just as efficiently) using make16, and two calls to the 8bit SPI read. However you then have to work out which call is made first. Letting the compiler do this for you, is much easier....
Best Wishes |
|
|
JosedeJesusC
Joined: 29 Mar 2013 Posts: 24
|
|
Posted: Thu Apr 04, 2013 7:40 am |
|
|
thanks so much temtronic and Ttelmah!!!!
Like I said if I set the buffer through the #USE SPI I don't worry about the spi_read(0) function, only with one instruction the CCS compiler makes the remaining.
For example:
Code: | #USE SPI( BITS = 24, stream=SPI_STREAM)
SPI_STREAM = SPI_READ(0); // SEND THE WHOLE STREAM |
or that could be a trouble? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Thu Apr 04, 2013 8:18 am |
|
|
No.
To use #USE SPI, and streams you need to use spi_xfer. So the syntax would be:
Code: |
#USE SPI( SPI1, stream=SPI_STREAM)
result = spi_xfer(SPI_STREAM,0,24);
|
The 'bits' number in the #USE SPI statement, is the _maximum_ to be sent/received. It defaults to 32. You tell the command how many to actually send/receive in the spi_xfer command.
You also have to say you are using SPI1 in the #USE SPI command.
spi_read only transfers 8bits, since this is all the hardware register has.
Best Wishes |
|
|
|
|
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
|