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

driver for SPI FRAM CY15B104Q
Goto page Previous  1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Thu Oct 31, 2019 9:25 am     Reply with quote

Hardware corrected, now back on DSO and checking.
It is a real time debugging ;-)
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Thu Oct 31, 2019 11:04 am     Reply with quote

Working properly, cleaning up the source and release by tomorrow
BR
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Thu Oct 31, 2019 1:10 pm     Reply with quote

Reading speed for 1 byte is 450 ns, same with writing of one byte.
Ttelmah



Joined: 11 Mar 2010
Posts: 19221

View user's profile Send private message

PostPosted: Thu Oct 31, 2019 1:46 pm     Reply with quote

I'd have expected the write to be a bit slower than the read.
The block read should be much faster per byte.
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Thu Oct 31, 2019 2:56 pm     Reply with quote

It is an external memory for A/D data collection from 3 x 32 bits + time stamp.
Not super fast but OK. So, Block can also be used, but not expect to have it very much faster. I will test it and report. I have 2 FRAMs on this PCB, for such buffers - 1GB totally (expensive experience)
I must thank again you for your help, it was very significant input that forced me to make this part rapidly.
I tried the SPI with various speeds (16M, 32M as also 40M) always the same W/R speed, so the bottle neck is on the routine itself than in the FRAM.
Tomorrow I will clean up the routines, make them more generic and then release to library forum. Maybe I delay it for one more day as I will test more configurations and see if I can speed it up little bit.
Thank you again.
BR
Ttelmah



Joined: 11 Mar 2010
Posts: 19221

View user's profile Send private message

PostPosted: Fri Nov 01, 2019 12:36 am     Reply with quote

I hope I got close. Smile
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Fri Nov 01, 2019 6:25 pm     Reply with quote

Hi,
I'm trying to implement also to this external SPI memory a circular buffer,
seems that the well known implementation used in the EX_SISR code is not easy to implement. My data package is 22 bytes long. I need to store each time a record, and read time to time (like a fifo-circular buffer).
Have anyone an idea about how to implement circular buffer in SPI external memory ?
Thank you in advance.
BR
Ttelmah



Joined: 11 Mar 2010
Posts: 19221

View user's profile Send private message

PostPosted: Fri Nov 01, 2019 11:59 pm     Reply with quote

The basic circular buffer code can be used
All you need to do is declare your package as a struct. Then read and
write these structures as the entities stored. You will then simply have
to multiply the indexes used by the sizeof the structure to get the address
in the FRAM.
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Sat Nov 02, 2019 3:14 am     Reply with quote

I have had exactly the same idea and already testing this.
So, you confirmed that I'm in a good way.
Thank you and Kind Regards.
Ttelmah



Joined: 11 Mar 2010
Posts: 19221

View user's profile Send private message

PostPosted: Sat Nov 02, 2019 4:20 am     Reply with quote

Years ago, I wrote a set of macros for this type of thing. Dug back:
Code:

typedef struct
{
    int32 start_addr;
    int32 in;
    int32 out;
} buffer_def;

#define BUFFER_COUNT 0x4000 //my buffer supported 4000 entries
buffer_def data_ptr={0x1000, 0, 0}; //my buffer was in EEPROM starting 
//at 1000

struct
{
   int32 time;
   float value;
   int16 status;
} data; //The temporary record used.
int32 temp_addr;
int temp_ctr;

#define JOIN(x,y) x##y
//Macro to allow buffer register values to be built
//Macros all called with buffer name as first value
#define CLEAR_BUFFER(x) JOIN(x,.in)=join(x,.out)=0;
#define INC_IN(x) if(++JOIN(x,.in)>=BUFFER_COUNT) join(x,.in)=0
#define INC_OUT(x) if(++JOIN(x,.out)>=BUFFER_COUNT) join(x,.out)=0
#define IS_EMPTY(x) (JOIN(x,.in)==JOIN(x,.out))
//Here needs pointer to data record, and size as next two values
#define GET_NEXT(x,d,s) temp_addr=(JOIN(x,.out)*s); \
                           for (temp_ctr=0;temp_ctr<s;temp_ctr++) \
                               *((byte *)d+ctr)=read_ext_eeprom(temp_addr++); \
                           INC_OUT(x)
//as above
#define ADD_ENTRY(x, d, s) temp_addr=(JOIN(x,.in)*s); \
                           for (temp_ctr=0;temp_ctr<s;temp_ctr++) \
                               write_ext_eeprom(temp_addr++, *((byte *)d+ctr)); \
                           INC_IN(x)

I stored the data_ptr record, into NVRAM (in a clock chip), so it didn't
matter updating it every time a record was added or retrieved.

Used as:

Fill up the 'data' variable. Then
ADD_ENTRY(data_ptr, &data, sizeof(data));

and
GET_NEXT(data_ptr, &data, sizeof(data));
to read the next record.

The macros then handle the buffers for you. I made them flexible since
I was actually storing three different record structures.

You can test if there is data in the buffer with 'IS_EMPTY(data_ptr)'
this returns true if the buffer is empty.
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Sun Nov 03, 2019 11:04 am     Reply with quote

micro_debugger wrote:
Reading speed for 1 byte is 450 ns, same with writing of one byte.

I made a mistake in measurements, 450 ns is for one bit, not for one byte
The maximum speed for one byte write (with SPI running at 15MHz - this is the max speed for dsPIC) is about 10us per byte writing to FRAM.
The max speed of SPI is the reason as we can not increase the speed of it. Also between each SPI write or read, about 900ns is loosed. I tried to make various tricks in order to increase the speed little bit (as in each write/read we loose about 5 us between all SPI calls (spi_xfer) but finally not working properly, with these improvements we I step down to about 8 us per write, and 7 us per byte read, but not working properly. The dsPIC is running with bout 67 MIPS (not 70 MIPS, as a special clocking is needed for my application)

Reading of a single byte is about 9us. However it is possible to read block, and then we have much higher speeds, 100 bytes is 172 us, 21 bytes is about 40 us
BR
Ttelmah



Joined: 11 Mar 2010
Posts: 19221

View user's profile Send private message

PostPosted: Sun Nov 03, 2019 11:29 am     Reply with quote

Er. You should be able to clock the SPI up to certainly 16.75MHz, possibly even
twice this. At 16.75MHz a byte should only take 0.5uSec to transfer. You will
find the spi_read and spi_write instructions are faster than spi_xfer.
Unfortunately, the spi_xfer includes the overhead for support for multi byte
transfers even if it is not used, and this costs significantly on the performance.
At your quoted processor speed I'd have expected it to take under 3uSec
to do the entire transfer. Your 450nSec, suggests you are only clocking the
SPI at just over 2MHz. Why?.
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Sun Nov 03, 2019 11:31 am     Reply with quote

checking again, and back soon to you.
I definitely prefer to have much faster FRAM due to my application, maybe I'm not doing something properly
Thank you for your kind answer
BR
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Sun Nov 03, 2019 11:37 am     Reply with quote

This is the setup of my clocking, and FRAM SPI
Code:

#include <33EP512MU810.h>

#build(stack=4096)
#use delay(clock=131072kHz, oscillator=30.72MHz, pll_wait, USB_FULL, AUX:clock=48MHz, crystal=16Mhz)

#define FRAM_HOLD_PIN         PIN_A14
#define FRAM_WP_PIN            PIN_A5
#define FRAM_SELECT_0         PIN_A15
#define FRAM_SELECT_1         PIN_A4
#define FRAM_CLK_PIN          PIN_F1
#define FRAM_SDI_PIN          PIN_D8      //MOSI PIN_G1 
#define FRAM_SDO_PIN          PIN_G1      //MISO PIN_F8
#define FRAM_SIZE             524288      //4Mbit 500Kbytes
#define FRAM_SPI_BAUD         15000000    //15 MHz

#pin_select SCK1OUT      =    FRAM_CLK_PIN           
#pin_select SDI1        =    FRAM_SDI_PIN                
#pin_select SDO1        =    FRAM_SDO_PIN                
#use spi(MASTER, SPI1, FORCE_HW, MODE=0, BITS=8, MSB_FIRST, BAUD=FRAM_SPI_BAUD, stream=FRAM_STREAM)


The used dsPIC can not have faster SPI than 15Mhz
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Sun Nov 03, 2019 11:48 am     Reply with quote

Yes, you are right, it is 2MHz, not 16.
Setting up again the DSO to measure again.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
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