Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| learn:courses:unit-4-lab4c:start [2017/03/20 20:21] – created Martha | learn:courses:unit-4-lab4c:start [2022/10/04 11:38] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Lab 4c: Communications - SPI Protocols ====== | + | ====== Lab 4c: Communications - SPI Serial |
| + | [[{}/ | ||
| + | [[{}/ | ||
| + | [[{}/ | ||
| === Download This Document === | === Download This Document === | ||
| - | * {{ : | + | {{ : |
| + | |||
| + | |||
| + | ===== 1. Objectives ===== | ||
| + | - Learn how to configure an SPI channel on the PIC32MX370 processor. | ||
| + | - Learn the difference between software and hardware handshaking. | ||
| + | - Learn how to communicate with an SPI FLASH memory device. | ||
| + | |||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 2. Basic Knowledge ===== | ||
| + | - How to configure I/O pins on a Microchip PIC32 PPS microprocessor. | ||
| + | - How to configure the Analog Discovery 2 to display logic traces. | ||
| + | - How to implement code reuse that integrates previously developed processor code into new application projects. | ||
| + | |||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3. Equipment List ===== | ||
| + | ==== 3.1. Hardware ==== | ||
| + | - [[https:// | ||
| + | - Workstation computer running Windows 10 or higher, MAC OS, or Linux | ||
| + | - 2 [[https:// | ||
| + | |||
| + | In addition, we suggest the following instruments: | ||
| + | - [[https:// | ||
| + | |||
| + | ==== 3.2. Software ==== | ||
| + | The following programs must be installed on your development work station: | ||
| + | |||
| + | - [[http:// | ||
| + | - [[http:// | ||
| + | - [[http:// | ||
| + | - [[https:// | ||
| + | - [[http:// | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 4. Project Takeaways ===== | ||
| + | - Understanding of requirements and implementations of synchronous communications. | ||
| + | - Understanding of the SPI protocol. | ||
| + | - How to generate instruction sets for controlling SPI devices. | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 5. Fundamental Concepts ===== | ||
| + | Serial Peripheral Interface (SPI) is a master-slave interface bus commonly used to send data between microcontrollers and small peripherals such as analog-to-digital converters, instrumentation sensors, and solid state memory devices. It uses a separate clock, send and receive data lines, and a device select signal. The PIC32MX370 has built-in hardware circuits to support two SPI channels. Since SPI and I< | ||
| + | |||
| + | ==== 5.1. Software Handshaking ==== | ||
| + | We can see the application of hardware handshaking for synchronizing data transfers for both the asynchronous UART that used start and stop bits, and synchronous I< | ||
| + | |||
| + | We will see that the flash memory device used on the Basys MX3 board requires command strings to place the device in different operating modes and to read device internal registers for determining status. Since SPI is a synchronous communications protocol, the clock signal manages the hardware element of the device synchronization. | ||
| + | |||
| + | |||
| + | ==== 5.2. SPI Communications ==== | ||
| + | The [[http:// | ||
| + | |||
| + | SPI is a [[http:// | ||
| + | |||
| + | SPI requires four wires for full-duplex operation and supports only one master but multiple slave devices. The master writes data to the slave using the Master Out Slave In (MOSI) line. The slave devices are able to send data to the master over the Master In Slave Out (MISO) line. Other than the clock signal, all handshaking is handled by an explicit slave select (SS) or chip select (CS) signal. | ||
| + | |||
| + | Figures 5.1 and 5.2 illustrate the two common SPI bus connection configurations. Figure 5.1 shows that the multiple slave devices share SCK, MOSI, and MISO signals. For this connection configuration, | ||
| + | |||
| + | Figure 5.2 shows a daisy-chain configuration where slave devices share both the SCK and SS signals, and the MOSI and MISO signals are routed through a series of slave devices. Using this configuration, | ||
| + | |||
| + | |||
| + | {{ : | ||
| + | //Figure 5.1. Parallel multiple slave SPI bus configuration with individual device select signals.// | ||
| + | |||
| + | {{ : | ||
| + | //Figure 5.2. Daisy chain multiple slave SPI bus configuration with a common device select signal.// | ||
| + | |||
| + | When the microprocessor is connected to a slave device that has both input and output capability using SPI, as data is clocked out of the master, data is also clocked in from the slave device. This results in efficient data transfers for some slave devices. The loosely defined SPI interface requires careful consideration of the slave clock-data timing, as well as using a microprocessor that can be configured to support various timing requirements. Figure 5.3 shows the clock-data timing for the four SPI operating modes. The clock polarity (CPOL) controls the idle level of the SCK output from the master. If CPOL is high, then the idle level of SCK is high. The clock phase (CPHA) specifies when the data is to be changed or written to MOSI by the master and to MISO by the slave device. For example, when CPHA is low, the data signal (MISO for master and MOSI for the slave) is sampled by the receiving device when SCK makes a transition from the idle level to the active level. | ||
| + | |||
| + | {{ : | ||
| + | //Figure 5.3. SPI timing modes.// | ||
| + | |||
| + | |||
| + | Figure 5.4 shows the PIC32 settings for clock edge (CKE) and clock polarity (CKP). Table 5.1 provides the correlation between the conventional definitions of SPI mode CPHA and CPOL to those CKE and CKP settings. (Note: There is an apparent error in the Microchip table shown in Fig. 5.4. Both CKE and CKP should be equal to 1 for the fourth case of the SCK timing diagrams.) It is important to match the master processor operation to what the slave device is expecting. For some designs, it is possible for different slave devices to expect the master to operate in modes that are not the same. The PIC32 operating modes can be changed during program execution, but the modes should not be changed when the processor is actively clocking data on the SPI bus. | ||
| + | |||
| + | **Table 5.1. SPI SCK operational modes.** | ||
| + | |||
| + | ^ SPI Mode ^ Active Level ^ Sample Transition | ||
| + | | 0 (or 0,0) | High | Idle to Active | ||
| + | | 1 (or 0,1) | High | Active to Idle | 0 | 1 | 0 | 0 | | ||
| + | | 2 (or 1,0) | Low | Idle to Active | ||
| + | | 3 (or 1,1) | Low | Active to Idle | 1 | 1 | 1 | 0 | | ||
| + | |||
| + | {{ : | ||
| + | //Figure 5.4. PIC32 SPI control setting to specify the sample timing (Reproduced from Microchip PIC32 Family Reference Guide Section 23, Fig. 23-7).// | ||
| + | |||
| + | SPI master-slave communications can be operated in either simplex or full-duplex modes. Simplex communications occur when the slave device can only send or receive data. Regardless of which device, master or slave, is sending the data, the master always provides the SCK signal. Although the phase and sample timing can differ between devices using SPI, the data is always active high (a high level represents a logical 1). | ||
| + | |||
| + | Data is sent and received by transferring the most significant bit (MSB) on the first clock pulse. We will define a transfer transaction as the exchange of data while the SS signal is continuously asserted in the active state (usually a low level.) For a specific transaction, | ||
| + | |||
| + | A data bit is shifted into the receiving device at the same time as the data bit is shifted out. Hence, once a word of data has been sent, the device has also received the next word. The SPI uses SCK clock edges to implement each bit transfer. At one SCK edge, each data sends a bit of data on the send line. The opposite clock edge a half of SCK clock cycle later, a data bit on the receive line is clocked into the receiving device. The specific clock edges are specified by the SPI mode of operation. The SCK signal can be asymmetrical as long as the period of the high or low state is greater than the inverse of two times the maximum data rate. | ||
| + | |||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 6. Problem Statement ===== | ||
| + | You are to develop a software system that allows the PIC32MX370 to write an arbitrary number of 8-bit bytes to an arbitrary address location in the SPI flash memory device. You must be able to read back this stored data and determine if the data read matches the data written. | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 7. Background Information ===== | ||
| + | ==== 7.1. PIC32MX370 SPI I/O ==== | ||
| + | Figure 7.1 shows the signal connections to the S25FL132K flash memory IC. Table 7.1 lists the PIC32MX370 processor pins that these signals are connected to. The PIC32 processor pin for the SPI_CE signal is configured as a digital output pin, as shown in Listing B.1. To implement the wiring configuration shown in Fig. 7.1, processor I/O pins PORT F:2 and PORTF:7 are mapped to SPI1T and SPI1R respectively using the first two statements in Listing B.2 in Appendix B. The PIC32MX370 PORTF:6 has a fixed assignment to SCK1. | ||
| + | |||
| + | {{ : | ||
| + | //Figure 7.1. SPI flash memory IC schematic diagram.// | ||
| + | |||
| + | **Table 7.1. SPI Flash Memory to PIC32MX370 connection table.** | ||
| + | |||
| + | ^ Function | ||
| + | | Chip Enable | ||
| + | | Serial Clock | SPI_SCK – 6 | PORT F Pin 6 – SCK1 | | ||
| + | | Flash Serial Input | SPI_SI – 5 | PORT F Pin 2 – SPI1R (MOSI) | ||
| + | | Flash Serial Output | ||
| + | |||
| + | |||
| + | ==== 7.2. Interface with SPI Flash Memory ==== | ||
| + | Using the SPI initialization shown in Listing B.2, the PIC32 processor is configured for SPI Mode 0 operation. Figure 7.2 shows that the bit output is held constant when the clock pulse makes a positive transition. Figure 7.2 also shows that the bit rate is 1 MHz. | ||
| + | |||
| + | {{ : | ||
| + | //Figure 7.2. SPI Bit timing for Mode 0 configuration.// | ||
| + | |||
| + | |||
| + | As Fig. A.2 shows, the same SPIxSR serial shift buffer is used for input and output, thus requiring the common SCKx clock signal. Hence, when a byte of data is shifted out of the SDOx pin, data is also being shifted into the SPIxSR from the SDIx pin. In other words, to receive SPI serial data, you must send SPI serial data. | ||
| + | |||
| + | Listing B.3 shows the function that can be used to send, receive, or exchange a byte of data using SPI communications. In most cases, when the SPI master is sending header data to the slave, the master SPI ignores the data received on the SDIx pin. Similarly, as the master continues to send non-consequential data during a SPI slave read operation, the slave SPI discards the data sent to it. The SPI master clock must be generated for both sending and receiving. | ||
| + | |||
| + | === 7.2.1. SPI Flash Memory Software === | ||
| + | We will use the S25FL132K SPI FLASH 132 MB memory device that is populated on the Basys MX3 processor board to demonstrate SPI device communications. The characteristics of this FLASH device are not representative of all control protocol used by SPI silicon devices. The FLASH memory device has command and status/ | ||
| + | |||
| + | Each device transaction is started with a command from the PIC32 processor. The command set of the S25FL132K Flash Memory is fully controlled through the SPI bus. Commands are initiated with the falling edge of Chip Select (CS#). The first byte of data clocked into the SI input provides the instruction code. Data on the SI input is sampled on the rising edge of clock with most significant bit (MSB) first. | ||
| + | |||
| + | Commands vary in length from a single byte to several bytes. Each command begins with an instruction code and may be followed by address bytes, a mode byte, read latency (dummy/ | ||
| + | |||
| + | Since the data sheet for this Flash memory device is quite daunting, excerpts from that manufacturers data sheets are shown in Table 7.2 through 7.5 with the commands highlighted that can be used to implement basic FLASH memory management. | ||
| + | |||
| + | The highlighted commands in Table 7.2 allow for reading basic device identification parameters. Each command is sent to the device followed by zero to five read bytes. It is recommended that the “Release Power down/Device ID” command be sent as part of a Flash initialization process. Figure 7.3 shows the screen capture for the SPI transaction of this command. For the S25FL132K Flash part, the device ID is 21 or 0x15 as demonstrated in Fig. 7.3. | ||
| + | |||
| + | **Table 7.2. Command Set (ID and Security Commands)**((S25FL132K and S25FL164K Data Sheet, [[http:// | ||
| + | |||
| + | ^ Command Name ^ BYTE 1 (Instruction) | ||
| + | | Deep Power-down | ||
| + | | Release Power Down / Device ID | ABh | Dummy | Dummy | Dummy | Device ID< | ||
| + | | Manufacturer / Device ID< | ||
| + | | JEDEC ID | 9Fh | Manufacturer | ||
| + | | Read SFDP Register / Read Unique ID Number | ||
| + | | Read Security Registers< | ||
| + | | Erase Security Registers< | ||
| + | | Program Security Registers< | ||
| + | |||
| + | {{ : | ||
| + | //Figure 7.3. Release Power Down/Read Device ID SPI transaction.// | ||
| + | |||
| + | The flash memory status register, SR0, has two volatile bits, bits 0 and 1, that indicate the current operational status of the memory chip. When WEL (bit 1) is set high, the device can be written to erase or program. The Page Program command (0x02) allows from one byte to 256 bytes (a page) of data to be programmed at previously erased (0xFF) memory locations. A Write Enable command must be executed before the device will accept the Page Program Command (Status Register bit WEL= 1). The command is initiated by driving the CS# pin low then shifting the instruction code “02h,” followed by a 24-bit address (A23-A0) and at least one data byte, into the SI pin. The CS# pin must be held low for the entire length of the command while data is being sent to the device. Refer to section 8 of the Flash Memory data sheet (Reference 5) for additional information. | ||
| + | |||
| + | **Table 7.3. Command set (Configuration, | ||
| + | |||
| + | ^ Command Name ^ BYTE 1 (Instruction) | ||
| + | | Read Status Register - 1 | 05h | SR1[7: | ||
| + | | Read Status Register - 2 | 35h | SR2[7: | ||
| + | | Read Status Register - 3 | 33h | SR3[7: | ||
| + | | Write Enable | ||
| + | | Write Disable | ||
| + | | Write Status Registers | ||
| + | | Set Burst with Wrap | 77h | Xxh | Xxh | Xxh | SR3[7: | ||
| + | | Set Block / Pointer Protection **(S25FL132K / S25FL164K)** | ||
| + | | Page Program | ||
| + | | Sector Erase (4 kB) | 20h | A23-A16 | ||
| + | | Block Erase (64 kB) | D8h | A23-A16 | ||
| + | | Chip Erase | C7h / 60h | ||
| + | | Erase / Program Suspend | ||
| + | | Erase / Program Resume | ||
| + | |||
| + | **Table 7.4. Status Register 0 bit definitions.** | ||
| + | ^ Bits ^ Field Name ^ Function | ||
| + | | 7 | SRP0 | Status Register Protect 0 | Non-volatile and Volatile versions | ||
| + | | 6 | SEC | Sector / Block Protect | ||
| + | | 5 | TB | Top / Bottom Protect | ||
| + | | 4 | BP2 | Block Protect Bits | ::: | 0 | 000b = No protection | ||
| + | | 3 | BP1 | ::: | ::: | 0 | ::: | | ||
| + | | 2 | BP0 | ::: | ::: | 0 | ::: | | ||
| + | | 1 | WEL | Write Enable Latch | Volatile, Read only | 0 | 0 = Not Write Enabled, no embedded operation can start\\ 1= Write Enabled, embedded operation can start | | ||
| + | | 0 | BUST | Embedded Operation Status | ||
| + | |||
| + | |||
| + | Any number of bytes can be read from the flash device starting at any address. As Table 7.5 illustrates, | ||
| + | |||
| + | **Table 7.5. Command Set (Read Commands).** | ||
| + | ^ Command Name ^ BYTE 1 (Instruction) | ||
| + | | Read Data | 03h | A23-A16 | ||
| + | | Fast Read | 0Bh | A23-A16 | ||
| + | | Fast Read Dual Output | ||
| + | | Fast Read Quad Output | ||
| + | | Fast Read Dual I/O | BBh | A23-A8< | ||
| + | | Fast Read Quad I/O | EBh | A23-A0, M7-M0< | ||
| + | | Continuous Read Mode Reset< | ||
| + | |||
| + | {{ : | ||
| + | //Figure 7.4. SPI Flash Read Byte command and three-byte address followed by reading data ' | ||
| + | |||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 8. Lab 4c ===== | ||
| + | ==== 8.1. Requirements ==== | ||
| + | 1. The PIC32MX370 UART channel 4 must operate at 38400 BAUD with no parity.\\ | ||
| + | 2. Two buffers must be created of size 1024 bytes.\\ | ||
| + | 3. Generate a 550-byte data set using the following code:\\ | ||
| + | < | ||
| + | #define nBytes 550 | ||
| + | for(i=0; i< | ||
| + | { | ||
| + | wrBuffer[i] = (BYTE) (' | ||
| + | } | ||
| + | </ | ||
| + | 4. Whenever the push button, BTNR, is pressed, 550 bytes of data must be written to the flash starting at address 100 (0x64). The following sequence must be executed: | ||
| + | * 4K bytes of flash memory must be erased starting at address 0. | ||
| + | * You must verify that the memory space that will be programmed has been erased (data value set to 0xFF). | ||
| + | * The preset data stream must be programmed into the flash memory at the starting address. | ||
| + | * A message is sent to the workstation terminal stating that the programming has completed. | ||
| + | 5. All bytes in a receive buffer must be initialized to 0.\\ | ||
| + | 6. 550 bytes of flash memory starting at address 100 must be read and each byte compared to the original data set.\\ | ||
| + | 7. If all the bytes compare, the message “No memory error!” is sent to the terminal.\\ | ||
| + | 8. If any byte does not compare, the message “Error at address ###: ## written - ## read” where ‘’### | ||
| + | 9. Steps 4 through 8 must be repeated once each second.\\ | ||
| + | |||
| + | |||
| + | ==== 8.2. Design Phase ==== | ||
| + | - Develop a data flow diagram for the software components needed for the requirements of Lab 4c. | ||
| + | - Schematic diagrams: Provide a block diagram of the equipment used for Lab 4c. | ||
| + | - Flow diagrams: Provide a complete software control flow diagram for lab 4c. | ||
| + | |||
| + | |||
| + | ==== 8.3. Construction Phase ==== | ||
| + | - Create a new project named Lab4c. | ||
| + | - Add C program files for configuring the processor and initializing the I/O for the switches and LEDs on Basys MX3 board. | ||
| + | - And C program files developed for previous labs that provide an interface to the UART. | ||
| + | - Develop a file containing the all SPI functions listed Appendix B. | ||
| + | - Using the primitive control function listed Appendix B, complete the requirements for Lab4c using the call graphs provided in Fig. 8.1 and Fig. 8.2. | ||
| + | - Download the completed functional project to the PIC32MX370 processor and test by running the project. | ||
| + | |||
| + | {{ : | ||
| + | //Figure 8.1. Call map for SPI FLash Write Page.// | ||
| + | |||
| + | {{ : | ||
| + | //Figure 8.2. Call map for SPI Flash Erase.// | ||
| + | |||
| + | |||
| + | ==== 8.4. Testing ==== | ||
| + | - Executing the program must result in the message “No memory error!” being sent to the terminal once each second. | ||
| + | |||
| + | |||
| + | ==== 8.5. SPI Design Challenge ==== | ||
| + | Replace the code in Listing B.7 for the function “SPIFLASH_WritePage” that uses software-intensive “for” loops with one that uses DMA. | ||
| + | |||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 9. Questions ===== | ||
| + | 1. Why does SPI normally have higher data transfer rates?\\ | ||
| + | |||
| + | 2. Is it necessary for the SPI SCK signal to have a 50% duty cycle?\\ | ||
| + | |||
| + | 3. Can text data be sent using SPI communications? | ||
| + | |||
| + | 4. Can SPI master be configured for only receiving data without transmitting data?\\ | ||
| + | |||
| + | 5. How many slave devices can be connected to the SPI bus?\\ | ||
| + | |||
| + | 6. What will happen to the SPI communications is an interrupt occurs in the middle of a transmission? | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 10. References ===== | ||
| + | - __Embedded Computing and Mechatronics with the PIC32 Microcontroller__, | ||
| + | - “PIC32MX330/ | ||
| + | - “Overview and Use of the PICmicro Serial Peripheral Interface”, | ||
| + | - Introduction to I²C and SPI protocols, [[http:// | ||
| + | - 16 Mbit (2 Mbyte), 32 Mbit (4 Mbyte), 64 Mbit (8 Mbyte) 3.0 V NVM, [[http:// | ||
| + | - S25FL132K and S25FL164K Data Sheet, [[http:// | ||
| + | - Implementing File I/O Functions Using Microchip’s Memory Disk Drive File System Library, [[http:// | ||
| + | |||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Appendix A: Lab 4 Parts Configuration ===== | ||
| + | {{ : | ||
| + | //Figure A.1. Unit 4 hardware and instrumentation configuration.// | ||
| + | |||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Appendix B: Allocating a Heap in MPLAB X ===== | ||
| + | ==== Listing B.1. Flash Memory SPI Initialization ==== | ||
| + | < | ||
| + | #define SPIFLASH_SEL | ||
| + | #define SPIFLASH_CS_TRIS | ||
| + | unsigned int flash_mem_init(void) | ||
| + | { | ||
| + | unsigned int bitrate; | ||
| + | |||
| + | bitrate = init_SPI1(); | ||
| + | SPIFLASH_CS_TRIS = 0; // Set FLASH select as output | ||
| + | SPIFLASH_SEL = 1; // Reset FLASH chip select | ||
| + | return bitrate; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Listing B.2. SPI Channel 1 Initialization for Master Mode ==== | ||
| + | < | ||
| + | #define MAX_SPI_CLK_FREQ | ||
| + | #define GetPeripheralClock() (GetSystemClock()/ | ||
| + | unsigned int init_SPI1(void) | ||
| + | { | ||
| + | unsigned int pbFreq; | ||
| + | unsigned int SPI_Clk_Freq; | ||
| + | unsigned int berg_val; | ||
| + | |||
| + | // Map PPS pins to SDI1 | ||
| + | SDI1R = 0x0F; // Map SDI1 to RF7 - Input (MISO)) | ||
| + | RPF2R = 0x08; // MAP SDO1 to RF2 - Output (MOSI)) | ||
| + | // SCK1 has fixed assignment to RF6 | ||
| + | |||
| + | // Initialize the direction of the SPI interface signals. | ||
| + | // is not assigned in this initialization since the pin assignment can be | ||
| + | // hardware dependent. | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | // Peripheral Bus Frequency = System Clock / PB Divider | ||
| + | // PB Frequency can be maximum 40 MHz * | ||
| + | | ||
| + | // Compute proper BERG value for specified SPI bit rate | ||
| + | | ||
| + | // Compute actual SPI bit rate | ||
| + | | ||
| + | |||
| + | // Enable SPI1, Set to Master Mode & Set CKE bit 1 for SPI MODE 0 | ||
| + | // Serial output data changes on transition from Active clock state to Idle | ||
| + | // clock state. Idle clock state is low. | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Listing B.3. SPI Channel 1 Byte Transaction ==== | ||
| + | < | ||
| + | BYTE spiXfer(BYTE data_out) | ||
| + | { | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Listing B.4. FLASH Transfer Bytes ==== | ||
| + | < | ||
| + | void SPIFLASH_TrasferBytes(int nBytes, unsigned char *pbRdData, | ||
| + | unsigned char *pbWrData) | ||
| + | { | ||
| + | int i; | ||
| + | | ||
| + | for(i = 0; i< nBytes; i++) | ||
| + | { | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Listing B.5. FLASH Release Power Down and Read Device ID === | ||
| + | < | ||
| + | void SPIFLASH_ReleasePowerDownGetDeviceID(BYTE *rd) | ||
| + | { | ||
| + | BYTE wr[5] = {0}; | ||
| + | |||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Listing B.6. SPI Write Data to Flash ==== | ||
| + | < | ||
| + | int SPIFLASH_WriteData(int nBytes, BYTE *pbWrData, unsigned int flashAddr) | ||
| + | { | ||
| + | int error = 0; | ||
| + | unsigned int pageAddrS; | ||
| + | unsigned int pageAddrE; | ||
| + | unsigned int pageAddrL; | ||
| + | unsigned int pageBytes; | ||
| + | unsigned int nPages; | ||
| + | BYTE *dataPtr; | ||
| + | |||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | // Write data one page at a time until error or write is complete. | ||
| + | | ||
| + | { | ||
| + | | ||
| + | | ||
| + | { | ||
| + | | ||
| + | } | ||
| + | | ||
| + | // Program one full page (256 bytes) or partial page within page boundaries | ||
| + | error |= SPIFLASH_WritePage(pageBytes, | ||
| + | | ||
| + | | ||
| + | } | ||
| + | |||
| + | | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Listing B.7. SPI Write Page Data to Flash ==== | ||
| + | < | ||
| + | static int SPIFLASH_WritePage(int nBytes, unsigned char *pbWrData, | ||
| + | | ||
| + | { | ||
| + | BYTE wr_hdr[5] = {0}; // Used for command and address | ||
| + | BYTE rd_hdr[5] = {0}; | ||
| + | BYTE tmpBuffer1[256]; | ||
| + | unsigned int pageAddr; | ||
| + | int error = 0; // Process error | ||
| + | BYTE chk_flag = 0xFF; // Check erased flag | ||
| + | int i; // General index | ||
| + | BYTE FLASHStatus; | ||
| + | |||
| + | // Test page constraint | ||
| + | | ||
| + | { | ||
| + | error = 1; // Write beyond page boundary | ||
| + | | ||
| + | | ||
| + | { | ||
| + | |||
| + | // Read existing page contents | ||
| + | | ||
| + | |||
| + | // Check for memory erased | ||
| + | | ||
| + | | ||
| + | { | ||
| + | | ||
| + | } | ||
| + | | ||
| + | { | ||
| + | error = 1; | ||
| + | | ||
| + | } | ||
| + | |||
| + | | ||
| + | | ||
| + | |||
| + | // Poll Status Register 1 until WEL bit is set and BUSY flag is reset. | ||
| + | do { | ||
| + | | ||
| + | } while(FLASHStatus != SPIFLASH_WEL_STATUS_BIT); | ||
| + | |||
| + | // Setup write header | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | | ||
| + | | ||
| + | { | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | { | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | |||
| + | | ||
| + | |||
| + | | ||
| + | do { | ||
| + | | ||
| + | } while(FLASHStatus != 0); // Wait until write is complete | ||
| + | |||
| + | } | ||
| + | | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | [[{}/ | ||
| + | [[{}/ | ||
| + | [[{}/ | ||
| + | [[{}/ | ||
| + | [[{}/ | ||

