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 support@ccsinfo.com

can spi_read() return 16bit value

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rikotech8



Joined: 10 Dec 2011
Posts: 376
Location: Sofiq,Bulgariq

View user's profile Send private message

can spi_read() return 16bit value
PostPosted: Sun Jul 15, 2012 11:13 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jul 15, 2012 11:54 am     Reply with quote

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: 19245

View user's profile Send private message

PostPosted: Sun Jul 15, 2012 1:19 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jul 16, 2012 3:41 am     Reply with quote

May be you mean:
Code:
x = make16(hi,lo);
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: 19245

View user's profile Send private message

PostPosted: Mon Jul 16, 2012 4:10 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jul 19, 2012 10:43 am     Reply with quote

Oh I see! Thank you Ttelmah!
JosedeJesusC



Joined: 29 Mar 2013
Posts: 24

View user's profile Send private message

PostPosted: Tue Apr 02, 2013 11:13 am     Reply with quote

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: 9125
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Apr 02, 2013 11:40 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Apr 03, 2013 4:51 pm     Reply with quote

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: 9125
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Apr 03, 2013 5:32 pm     Reply with quote

'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: 19245

View user's profile Send private message

PostPosted: Thu Apr 04, 2013 12:32 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Apr 04, 2013 7:40 am     Reply with quote

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: 19245

View user's profile Send private message

PostPosted: Thu Apr 04, 2013 8:18 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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