As many people need some sort of storage in their embedded project, they prefer to use SPI flash. Hence I decided to try this interfacing with ATMEGA32 microcontroller. This SPI flash is 16Mb flash, works on SPI interface. You can reuse below code if you want to integrate this flash to your project.
I tested this code using proteus simulation, you can also test and comment.
Features of M45PE16-
16Mb of page-erasable Flash memory
Page size: 256 bytes
Sector erase: 512Kb
75 MHz clock frequency (MAX)
In current interfacing I only did Page Write/ Read API's. The SPI needs to configure in Mode 0, and Master at Microcontroller side as given in code below. The result or Page read bytes are displayed over terminal using UART.
Code-
M45PE16.c
/*
*
*
* Created on: Apr 18, 2014
* Author: Shrenik Shikhare
* File: M45PE16.c
* Discription: Interfacing M45PE16 SPI Flash to ATMEGA32
* Copyrights(C)-April 2014
*/
//#define F_CPU 100000UL
#ifndef __M45PE16_H__
#define M45PE16_H_
#define WREN 0X06
#define WRDI 0X04
#define RDID 0X9F
#define RDSR 0X05
#define READ 0X03
#define FAST_READ 0X0B
#define PW 0X0A
#define PP 0X02
#define PE 0XDB
#define SE 0XD8
#define DP 0XB9
#define RDP 0XAB
#define PAGE_SIZE 256
#define NUM_OF_SECTORS 32
#define NUM_OF_PAGES_IN_SECTOR 256
#define FLASH_chipSelectHigh() (PORTB|=(1<<4))
#define FLASH_chipSelectLow() (PORTB&=~(1<<4))
#define waitForTransferComplete() while(!(SPSR&(1<<SPIF)))
#endif /* M45PE16_H_ */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//#include "m45pe16.h"
#define byte unsigned char
#define word unsigned int
void USART_Init( unsigned int Baudrate )
{
UBRRH=0x00;
UBRRL = (unsigned char)Baudrate; // Set the baud rate
UCSRB = 0x18; // enable transmitter and reciever
UCSRC = 0x86; // set as 8 bit data, no parity bit and 1 stop bit.
}
void putChar( byte uData )
{
while ((UCSRA & 0x20) == 0x00); // Wait until the transmit buffer is empty
UDR = uData; // As soon as the buffer is empty, put the data in UDR
}
void printString(char *uData)
{
while(*uData)
putChar(*uData++);
}
//Configure SPI
void ConfigSPI(void)
{
//Make SS,MOSI,SCK Pins as Output
DDRB|=(1<<4)|(1<<5)|(1<<7);
//Enable SPI as Master, Mode 0, and fOsc/4 SPI CLK
SPCR|=(1<<SPE)|(1<<MSTR)|(1<<SPR0);
//Set SPI Status Register to Zero
SPSR=0x00;
}
//@brief - FLASH_TXByte function will send a data byte on SPI bus
void FLASH_TXByte(uint8_t uData)
{
FLASH_chipSelectLow();
SPDR = uData;
waitForTransferComplete();
FLASH_chipSelectHigh();
}
//@brief - FLASH_PageWrite function will start saving uData on flash from pageAddress
void FLASH_PageWrite(uint32_t pageAddress,uint8_t *uData, uint8_t sizeData)
{
uint8_t iterator;
FLASH_TXByte(WREN);
_delay_ms(10);
FLASH_chipSelectLow();
SPDR = PP;
waitForTransferComplete();
SPDR = (uint8_t)pageAddress;waitForTransferComplete();
SPDR = (uint8_t)(pageAddress>>8);waitForTransferComplete();
SPDR = (uint8_t)(pageAddress>>16);waitForTransferComplete();
for(iterator = 0; iterator < sizeData; iterator++)
{
SPDR = uData[iterator];
waitForTransferComplete();
}
FLASH_chipSelectHigh();
}
//@brief - FLASH_PageRead function will read data from the provided input pageAddress and store in uData
void FLASH_PageRead(uint32_t pageAddress,uint8_t *uData, uint8_t sizeData)
{
uint8_t iterator;
FLASH_TXByte(WREN);
_delay_ms(10);
FLASH_chipSelectLow();
SPDR = READ;
waitForTransferComplete();
SPDR = (uint8_t)pageAddress;waitForTransferComplete();
SPDR = (uint8_t)(pageAddress>>8);waitForTransferComplete();
SPDR = (uint8_t)(pageAddress>>16);waitForTransferComplete();
for(iterator = 0; iterator < sizeData; iterator++)
{
SPDR=0xf0;waitForTransferComplete();
uData[iterator] = SPDR;
//waitForTransferComplete();
}
FLASH_chipSelectHigh();
}
int main(void)
{
byte WriteSampleBuff[10];// = {1,2,5,7,8,9,3,56,5,6};
byte ReadSampleBuff[10];
byte i;
USART_Init(12);
printString("SPI Flash example code LIbrary\r\n");
//Write data to flash
for(i=0;i<10;i++){ WriteSampleBuff[i]=i; }
ConfigSPI();
sei();
_delay_ms(1000);
//Read data from flash
FLASH_PageWrite(0x0000001F,WriteSampleBuff,10);
_delay_ms(1000);
FLASH_PageRead(0x0000001F,ReadSampleBuff,10);
printString("The stored data = \r\n");
for(i=0;i<10;i++){
putChar(ReadSampleBuff[i]+'0');
printString("\r\n");
PORTA=ReadSampleBuff[i];
_delay_ms(500);
}
while(1);
}
Following is the screenshot of proteus project.
I hope this will be helpful for those who wants to incorporate SPI flash in their projects.
Thanks,
Shrenik.
Comments
Post a Comment