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 CCS Technical Support

driver for SPI FRAM CY15B104Q
Goto page 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

driver for SPI FRAM CY15B104Q
PostPosted: Thu Oct 17, 2019 2:03 pm     Reply with quote

Hi,
Do you know if drivers library provided with ccsinfo contain driver compatible with SPI FRAM CY15B104Q.
If not I will write my own and share with you.

Thank you and Kind Regards
micro_debugger
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Thu Oct 17, 2019 2:18 pm     Reply with quote

Normally FRAM's are reverse compatible with equivalent SPI EEPROM
drivers. I've used several without problems. However the issue here will
be there is not a 4Mbit SPI EEPROM driver in the library. The existing
1MBit driver will need to simply have the size increased, and a couple
of extra bits of address output.
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Thu Oct 17, 2019 2:41 pm     Reply with quote

Thank you !
You are faster than light Very Happy
When finished it will share.
MikeW



Joined: 15 Sep 2003
Posts: 184
Location: Warrington UK

View user's profile Send private message

PostPosted: Fri Oct 18, 2019 12:00 am     Reply with quote

this might help

https://www.silabs.com/community/wireless/zigbee-and-thread/knowledge-base.entry.html/2017/06/16/extending_the_spifla-0SnN
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Oct 18, 2019 1:41 am     Reply with quote

OK. Sat down this morning and modified an SPI EEPROM driver. Think this
should be very close to right (but untested, not even compiled). If it works
we can transfer it to the code library.
Code:

//Base attempt at a CY15B104Q FRAM driver

#ifndef __CY15B104Q__ //ensure only loads once
#define __CY15B104Q__

#include <stdint.h>

#ifndef FRAM_SELECT_PIN
 #define FRAM_SELECT_PIN    PIN_B4
#endif

#ifndef FRAM_CLK_PIN
 #define FRAM_CLK_PIN       PIN_C3
#endif

#ifndef FRAM_SDI_PIN
 #define FRAM_SDI_PIN       PIN_A4      //MOSI
#endif

#ifndef FRAM_SDO_PIN
 #define FRAM_SDO_PIN       PIN_A9      //MISO
#endif

#ifndef FRAM_SIZE
 #define FRAM_SIZE          524288       //4Mbit 500Kbytes
#endif

#ifndef FRAM_SPI_BAUD
 #define FRAM_SPI_BAUD      16000000    //16 MHz
#endif

//Optionally, write protect and hold pins can also be defined.

#ifndef FRAM_STREAM
 #use spi(MASTER, MODE=0, CLK=FRAM_CLK_PIN, DO=FRAM_SDI_PIN, DI=FRAM_SDO_PIN, BITS=8, BAUD=FRAM_SPI_BAUD, STREAM=FRAM_STREAM)
 
 #define FRAM_xfer(x)       spi_xfer(FRAM_STREAM, x)
#else
//Handle where somebody has called with an already defined stream
//ensure transfers are byte sized.
 #define FRAM_xfer(x)       spi_xfer(FRAM_STREAM, x, 8)
#endif


///////////////////////////////////////////////////////////////////////////////

typedef uint32_t FRAM_ADDRESS;

//Command list
typedef enum
{
   FRAM_CMD_WRSR=0x01,
   FRAM_CMD_WRITE,
   FRAM_CMD_READ,
   FRAM_CMD_WRDI,
   FRAM_CMD_RDSR,
   FRAM_CMD_WREN,
   FRAM_CMS_FSTRD=0xB,
   FRAM_CMD_SLEEP=0xB9,
   FRAM_CMD_RDID=0x9F
} FRAM_CMD;

typedef struct
{
   uint8_t ManufactureCode;   //should be 0x80
   uint8_t FamDenCode;        //should be 0x26
   uint8_t[7] ManID;       //should be 0x‭7F7F7F7F7F7FC2‬ - ID is 0xC2 rest fillers
} FRAM_ID;

////////////////////////////////// Prototypes /////////////////////////////////

void init_ext_FRAM(void);
uint8_t read_ext_FRAM(FRAM_ADDRESS Address);
void write_ext_FRAM(FRAM_ADDRESS Address, uint8_t Data);
void ext_FRAM_read_id(FRAM_ID *Id);

void ext_FRAM_write_enable(int1 Enable=TRUE);
void read_block_FRAM(FRAM_ADDRESS Address, BYTE * buffer, uint16_t count);

///////////////////////////////////// API /////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// init_ext_FRAM()
//
// Initializes the external FRAM's chip select, hold and write protect pins.
// Should be called before any other external FRAM functions are called.
// Also ensure block protection not enabled
//
// Parameters - None.
//
// Returns - Nothing.
///////////////////////////////////////////////////////////////////////////////
void init_ext_FRAM(void)
{
   output_high(FRAM_SELECT_PIN);
   output_drive(FRAM_SELECT_PIN);
   
  #ifdef FRAM_HOLD_PIN //optonal pins.
   output_high(FRAM_HOLD_PIN);
   output_drive(FRAM_HOLD_PIN);
  #endif
 
  #ifdef FRAM_WRITE_PROTECT_PIN
   output_high(FRAM_WRITE_PROTECT_PIN);
   output_drive(FRAM_WRITE_PROTECT_PIN);
  #endif
  ext_FRAM_write_enable(TRUE); //needs to be set before accessing the SR

  //Now this chip support block protection as well as the WREN bit
  //disable this for simplicity
  output_low(FRAM_SELECT_PIN);
     
  FRAM_xfer(FRAM_CMD_WRSR); 
  FRAM_xfer(0); //turn off protected address range
  output_high(FRAM_SELECT_PIN);
  ext_FRAM_write_enable(FALSE);
}

///////////////////////////////////////////////////////////////////////////////
// read_ext_FRAM()
//
// Reads a byte from the external FRAM from the specified address.
//
// Parameters:
//    Address - the address within the external FRAM to read.
//
// Returns:
//    uint8_t - the byte read from the external FRAM or 0x00 if Address
//              was invalid.
///////////////////////////////////////////////////////////////////////////////
uint8_t read_ext_FRAM(FRAM_ADDRESS Address)
{
   uint8_t Result;
   
   if(Address < FRAM_SIZE)
   {
     
      output_low(FRAM_SELECT_PIN);
     
      FRAM_xfer(FRAM_CMD_READ);
      FRAM_xfer(make8(Address, 2)); //top 3 bits of address
      FRAM_xfer(make8(Address, 1)); 
      FRAM_xfer(make8(Address, 0)); //LSB
      Result = FRAM_xfer(0);
     
      output_high(FRAM_SELECT_PIN);
   }
   else
      Result = 0;
   
   return(Result);
}

///////////////////////////////////////////////////////////////////////////////
// write_ext_FRAM()
//
// Writes a byte to the external FRAM to the specified address.  If an
// invalid address is specified nothing is written.
//
// Parameters:
//    Address - the address within the external FRAM to write.
//
//    Data - the byte to write to the specified address.
//
// Returns - Nothing.
///////////////////////////////////////////////////////////////////////////////
void write_ext_FRAM(FRAM_ADDRESS Address, uint8_t Data)
{
   if(Address < FRAM_SIZE)
   {
      //Enable writes, ext_FRAM_write_enable()
      ext_FRAM_write_enable(TRUE);
     
      output_low(FRAM_SELECT_PIN);
     
      FRAM_xfer(FRAM_CMD_WRITE);
      FRAM_xfer(make8(Address,2);
      FRAM_xfer(make8(Address, 1));
      FRAM_xfer(make8(Address, 0));
      FRAM_xfer(Data);
     
      output_high(FRAM_SELECT_PIN);
     
      //Disable writes
      ext_FRAM_write_enable(FALSE);
   }
}

///////////////////////////////////////////////////////////////////////////////
// ext_FRAM_read_id()
//
// Function for reading the external FRAM's identification.
//
// Parameters:
//    Id - pointer to FRAM_ID structure to return read identification to.
//
// Returns - Nothing.
///////////////////////////////////////////////////////////////////////////////
void ext_FRAM_read_id(FRAM_ID *Id)
{
   uint8_t count;
   BYTE * ptr;
   ptr=ID; //quicker than casting for every operation
   
   output_low(FRAM_SELECT_PIN);
   
   FRAM_xfer(FRAM_CMD_RDID);
   for (count=0;count<sizeof(FRAM_ID);count++)
      ptr[count]=FRAM_xfer[0]; //clock entire ID from chip
 
   output_high(FRAM_SELECT_PIN);
}

///////////////////////////


///////////////////////////////////////////////////////////////////////////////
// ext_FRAM_write_enable()
//
// Function use enable or disable write functions.
//
// Parameters:
//    Enable - if TRUE writes are enabled, if FALSE writes are disabled.
//
// Returns - Nothing.
///////////////////////////////////////////////////////////////////////////////
void ext_FRAM_write_enable(int1 Enable=TRUE)
{
   
   output_low(FRAM_SELECT_PIN);
   
   if(Enable)
      FRAM_xfer(FRAM_CMD_WREN); //set the WREN bit
   else
      FRAM_xfer(FRAM_CMD_WRDI);
   
   output_high(FRAM_SELECT_PIN);
}

///////////////////////////////////////////////////////////////////////////////
// read_block_FRAM()
//
// Function used to perform a block read from the chip
//
// Parameters:
//    Address - start address in the memory
//    buffer - pointer to RAM area to receive the data
//    count - number of bytes to read
//
// Returns - Nothing.
///////////////////////////////////////////////////////////////////////////////
read_block_FRAM(FRAM_ADDRESS Address, BYTE * buffer, uint16_t count) 
   if(Address < FRAM_SIZE)
   {
     
      output_low(FRAM_SELECT_PIN);
     
      FRAM_xfer(FRAM_CMD_FSTRD);
      FRAM_xfer(0); //dummy byte needed after this command
      while (count-->0)
         *(buffer++) = FRAM_xfer(0));
      //now transfer 'count' bytes ASAP
     
      output_high(FRAM_SELECT_PIN);
   }   
   return;
#endif


Last edited by Ttelmah on Mon Oct 28, 2019 8:54 am; edited 1 time in total
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Sat Oct 19, 2019 6:23 pm     Reply with quote

Thank you very much for your work !!
I will have hardware this week, so test it and release to common library.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Oct 19, 2019 10:50 pm     Reply with quote

Look forward to hearing how you get on... Smile
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Sat Oct 26, 2019 3:52 pm     Reply with quote

Hi,
Just received assembled hardware and putting everything together.
Will keep you informed.
BR
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Sun Oct 27, 2019 2:38 pm     Reply with quote

Hi,
Not working, until now. Need to setup a protocol analyzer to see what is done inside, as with simple dso see it properly.
More news next 1-2 days.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sun Oct 27, 2019 11:30 pm     Reply with quote

What PIC are you using?. What pins?. What clock rate?.

OK I've just spotted one error. Made a one line change to the posted code.
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Thu Oct 31, 2019 6:37 am     Reply with quote

Sorry for my late replying.
Just was inside of the IC :-)
I'm using DSPIC33EP512MU810
but PCB received with bug, and now trying to solve it.
They used a wrong pin for SPI1, so the only solution was to use common PIN for SDO and SDI as software SPI is too slow for this.
BAUD=16000000

Code:
#define FRAM_HOLD_PIN      PIN_A14
#define FRAM_WP_PIN         PIN_A5
#define FRAM_SELECT_PIN    PIN_A15
#define FRAM_CLK_PIN       PIN_F1
#define FRAM_SDI_PIN       PIN_G1      //MOSI
#define FRAM_SDO_PIN       PIN_G1      //MISO
#define FRAM_SIZE          524288      //4Mbit 500Kbytes
#define FRAM_SPI_BAUD      16000000    //16 MHz

#pin_select REFCLK = PIN_G13   

/////////////// SPI Set-up START ////////////////
#pin_select SCK1OUT      =    PIN_F1            //DSP Pin 66
#pin_select SDI1        =    PIN_G1             //DSP Pin 68  MOSI1 DO PIN_G7     
#pin_select SDO1        =    PIN_G1             //DSP Pin 67 MISO1 DI PIN_G6     
#use spi(MASTER, SPI1, FORCE_HW, MODE=0, BITS=8, SAMPLE_RISE, MSB_FIRST, BAUD=16000000, stream=FRAM_STREAM)


Soon will be back to you with positive news (hope and wish).
BR
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Thu Oct 31, 2019 7:30 am     Reply with quote

That is going to give you major issues.
Problem is SDO drives the pin, so data can't be received on it from the chip.
You are going to see unwanted heating when both chips try to drive, and
going to have to change the TRIS explicitly in the code whenever data
actually wants to be read. I have a nasty suspicion it is not going to work.
Honestly better to cut the 'wrong' track and make a hardware bodge.
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Thu Oct 31, 2019 7:59 am     Reply with quote

OK. Thank you, taking my knife for action and microscope
soon back to you
micro_debugger



Joined: 08 Oct 2009
Posts: 73

View user's profile Send private message

PostPosted: Thu Oct 31, 2019 8:44 am     Reply with quote

Found that F8 is used as test point, so easy to solder a wire, as to 100 pins TQFP is very difficult to solder anything on pins, so isolated the FRAM SO, but pushing it up, and solder a bridge to F8, checking now.
BR
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Thu Oct 31, 2019 8:56 am     Reply with quote

I've learnt the 'delights' of making changes to SM chips. Found it worth
bringing anything I've not already debugged to a patch area near the chip
when laying out the PCB. Saves a lot of grief....
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 1, 2, 3  Next
Page 1 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