[PIC] setting pre and post scalar values for Fsck in SPI.

Status
Not open for further replies.

Raady Here

Full Member level 5
Joined
Jun 8, 2013
Messages
242
Helped
26
Reputation
52
Reaction score
26
Trophy points
28
Location
India
Visit site
Activity points
1,571
PIC24EP512GP806
MPLAB8.8V

Hi,

I am interfacing s25FL032P flash memory with my pic through SPI. how to calculate and set SCK required to use.

For normal read mode in S25FL032P speed is 40Mhz clock speed. For setting prescalar bits in SPIxCON1 of PIC24 how do I calculate the what prescalar values i need to choose so that operation is at clock 40 Mhz.

I am using a oscillator 10 Mhz, clock init is
PLLFBD = 22; // M = 48
CLKDIVbits.PLLPOST = 0; // N1 = 2
CLKDIVbits.PLLPRE = 0; // N2 = 2

Fosc = Fin*(M/(N1*N2));
Fosc = 120 Mhz.


what are values to be set
SPI1CON1bits.SPRE = ; // Secondary prescalar bits.
SPI1CON1bits.PPRE = ; // Primary Prescalar bits.

many have taken 2:1 and 4:1 respectively , how do I know what is the sck ?


Code:
void Config_SPI(void)
{
	SCK 	= 0; // SCK as output
	SDO 	= 0; // SDO as output
	SDI 	= 1; // SDI as input
	WP 		= 0; // WP as O/P
	//HOLD 	= 0; // HOLD as O/P
	CS		= 0; // CHIP SELECT as O/P
}

void Init_SPI(void)
{
	Config_SPI();					// Configuration for SPI Modules.
	// SPI Status Control Registers
	SPI1STATbits.SPIEN		= 0;	// Disable the SPI Module.
	SPI1STATbits.SPISIDL	        = 0;	// Continue the Operation in Idle Mode.
	SPI1STATbits.SRMPT		= 0;	// SPI shift register is not empty.
	SPI1STATbits.SPIROV		= 0;	// No overflow has occured.
	SPI1STATbits.SRXMPT        = 0;	// RX FIFO not empty
	SPI1STATbits.SISEL		= 3;	// Buffer Interrupt Mode - Interrupt when SPI receive buffer is full.
	SPI1STATbits.SPITBF		= 0;	// Transmit has started, SPIx transmit buffer is empty.	
	SPI1STATbits.SPIRBF		= 0;	// Receive is incomplete, SPIx Receive buffer is empty.

	// SPI Control Regsiter 1
	SPI1CON1bits.DISSCK		= 0; 	// Internal SPI clock is enabled.
	SPI1CON1bits.DISSDO	= 0;	// SDO is controller by module.
	SPI1CON1bits.MODE16	= 1;	// 1 - 16 bit , 0 - 8 bit mode
	SPI1CON1bits.SMP		= 1;	// Input data is sampled at end of data output time.
	SPI1CON1bits.CKE		= 0;	// Clock Edge Selected 
	SPI1CON1bits.SSEN		= 0;	// SSx pin is not used by module, pin is controller by port function.
	SPI1CON1bits.CKP		= 0;	// Idle when clock is low level, active state is high level
	SPI1CON1bits.MSTEN		= 1;	// Master Mode enable bits.
	SPI1CON1bits.SPRE		= 0;	// Secondary prescalar bits.
	SPI1CON1bits.PPRE		= 0;	// Primary Prescalar bits.

	SPI1CON2bits.FRMEN		= 0;	// Framed SPI Support -> 1 - enabled, 0 - disabled.	
/*

*/
}
Regards,
Raady.
 
Last edited:

First off, a value of PLLFBD=22 will give a multiplication (the M value) of 24, not 48. (Also it is typically referred to as PLLDIV by most people and also in the data sheet. I know that the PLLDIV fields are the only used bits in that register, but that need not be true for other (future) devices in the family.)
Therefore, the output of the VCO itself will be 120MHZ which is right at the bottom end of the valid range. It also means that the Fosc will be 60MHz.
Also the SPI peripheral is driven by the Fp clock which is Fosc divided by 2, so in your case it would be 30MHz.
The data sheet warns against using both the primary and secondary prescalars at 1:1. Therefore the fastest you can drive the SCK will be with PPRE = 0 (1:1) and SPRE = 6 (1:2) which will therefore be at 15MHz.
You can get high SCK frequencies by taking the system (Fosc) higher but it has a maximum of 120MHz (140MHZ is you can guarantee a lower working temperature). With that, you can get an Fp of 70MHz and therefore a maximum SCK of 35MHz.
HOWEVER, the data sheet (Table 32-34) lists the maximum SCK as 15MHz, and 9MHz under some specific conditions - that you happen to be using (SMP=1)!
If you use SPI #2 then things are a bit better (as it is hard wired to the devices pins - the other SPI peripherals go via PPS which slows them down a bit) but not by much.
Another consideration is how fast the CPU can handle the I/O via the SPI peripheral. At best, you can get about 70MIPS out of the CPU. If the SCK is set at (say) 10MHz then you will only get 1 byte every 800nSec, and that represents about 56 instructions. If you take the ISR overheads into account, you can just about max-out the CPU just supporting the SPI transfers.
I would suggest that you look at driving the SPI with DMA if this is possible, especially if you are using the page I/O operations to read/write multiple bytes.
By the way, I see that you are setting MODE16 to 1 (16-bit transfers). Looking at te data sheet for the memory I see that commands are 8 bits in length and addresses are 24 bits which means that you can get away with that. However the unit of data for the memory is a byte which means that you will be forcing yourself to always write 2 bytes at a minimum. I would suggest that you use byte mode (8 bits) and let the DMA do the work for you.
Susan
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…