How to Mount an SPI FRAM Chip on the Forlinx OK3568-C Development Board?

Saving existing data and avoiding data loss when dealing with sudden power loss is crucial for users of fast storage and acquisition data products. There are many solutions to this problem, among which ferroelectric memory (FRAM) is a good choice. FRAM is a non-volatile memory with fast write speed, capable of storing data in a non-volatile manner while also allowing operations similar to RAM.

This article will utilize the Forlinx OK3568-C development board to introduce a solution that employs FRAM - using the SPI0 interface to connect the PB85RS2MC (FRAM) chip. The driver files and application files described in this article can be obtained by contacting Forlinx Embedded's technical support.

OK3568-C development board


To add an SPI device, the following steps need to be taken: Add a description to the device tree → corresponding device driver in the device tree description → device driver added to the kernel


Modify OK3568-linux-source/kernel/arch/arm64/boot/dts/rockchip/OK3568-C-common.dtsi
Modify the following:


Next, we will introduce the adaption process.

1 Driver

We searched the menuconfig for fm25, pb85, and other commonly used FRAM words but found that there is no similar driver. So we need to handwrite or port a driver. After searching through various websites, I found a driver for W25Q64. After comparing the various operation codes of PB85RS2MC with W25Q64, I noticed that they are quite similar. Therefore, I have decided to port the W25Q64 driver to PB85RS2MC.
According to the description in the PB85RS2MC chip manual, the various opcodes are:

Command Name

Command Description


WREN Write Enable Latch Commands 0000 0110B
WRDI Reset Enable Latch CommandWrite Enable Latch Commands 0000 0100B
READ Read Command 0000 0011B
WRITE Write Command 0000 0010B
RDID Read Device Serial Number Command 1001 1111B
FSTRD High-speed read command 0000 1011B
SLEEP Sleep command 1011 1001B
RDSR Read Status Register 0000 0101B
WRSR Write Status Register 0000 0001B

Therefore, the following opcodes are macro-defined in the driver to be used in the following drivers:

macro-defined driver

First, the initi and exit functions should be carried out in the driver, that is, the spidev _ init and spidev _ exit. The init function is to initialize the character device, register it, etc. The exit function is to release all the things we have registered when we exit. This must match the value of the compatible attribute in the device tree, otherwise the match will be unsuccessful. Furthermore, the driver and the device tree are matched by the value of the compatible attribute, which must be the same as the value of the compatible attribute in the device tree. Otherwise the match will be unsuccessful. The compatible value in the driver is shown below.

init and spidev

After the successful matching of the driver and the device tree, we have to execute the probe function, where the probe function performs some initialization and registration of the primary and secondary device numbers. We can determine whether the driver, and the device tree match successfully by whether it prints spi_probe success!

device tree

Check the read conditions in the PB85RS2MC chip manual, then read the data from the FRAM memory cell, which requires the READ opcode, any 24-bit address entered into the SI. The first spi_transfer structure is used to send the command cmd to the SPI device to prepare the device before reading the data, the second is to send the address to the SPI device, and the third is to receive the data read from the device.

PB85RS2MC chip manual

This code implements a synchronized read from the SPI device and copies the data to user space.

synchronized read

Check the write conditions from the PB85RS2MC chip manual, the WREN command is used to set the write enable latch. The WREN command is required to set the write enable latch before the write operation (WRITE command), and the WRITE command writes data to the FRAM memory cell array. The WRITE opcode, any 24-bit address, and 8-bit write data are input to the SI.

The following code implements the function of sending a write enable command to the SPI device.

SPI device

This code implements synchronized writing of data to SPI devices. It sends the write enable command first and then sends the address information and data.

address information and data

The following code writes data synchronously to the SPI device by copying user-space data to the device's transmit buffer and calling the spidev_sync_write function to write the data to the SPI device.

copying user-space data

2 Applications

To write data to an SPI device, call lseek to change the location of the written data so that data can be written throughout the SPI device, e.g. . /writeframAPP /dev/pb85rs 0 forlinx

(0 is the address to write to, forlinx is what to write)

RK3568 SPI device

To read data from an SPI device, call lseek to change the location of the read data so that it can be read throughout the SPI device, e.g. . /readframAPP /dev/pb85rs 0

(0 is the address of the data to be read)


3 Actual Test

(1) First copy fram.ko, readframAPP, writefram APP to any folder in OK3568-C development board.

OK3568-C development board

(2) Load the fram.ko module with insmod, spi_probe success! shows that the driver matches the device tree successfully.

spi_probe success

(3) Look under /dev/ to see if there is a pb85rs device.

pb85rs device

(4) Use . /writeframAPP /dev/pb85rs 1500 forlinx
Write data to the device, 1500 is the address and forlinx is what to write.

pb85rs 1500 forlinx

(5) Use . /readframAPP /dev/pb85rs 1500

(1500 is the address of the data to be read)

pb85rs 1500

4 Power Failure Test

Re-reading the PB85RS2MC after a day of power loss revealed that the data was still there. The power-off data retention characteristics of the PB85RS2MC ferroelectric memory chip are verified.


At this point, we have completed adding a new SPI ferroelectric memory chip to the OK3568-C development board!