Skip to main content

Interfacing M45PE16 SPI Flash to ATMEGA32



       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

Popular posts from this blog

128 x 64 Graphics LCD Display Interfacing with ATMEGA32 Library from Scratch

            Yes I am diving little into traditional stuff, still its interesting to try something from scratch. While working on some hi-tech stuff where we mostly don't care about writing something from scratch as its time consuming. Now a days platforms like arduino are concentrating on Application, they are not meant to use to understand the hardware peripheral. In fact I never tried it though ;). I know there are lots of example available online regarding this graphics LCD. This LCD I selected is HDG128x64F, which is more or less what is conventionally used, but I found some differences as in column addressing method. I got datasheet about HDG128x64F here , where I can only find some commands which are more or less similar to that of 16x2 LCD except RAM addressing method. To start working on this I preferred using Proteus Simulation software to make it more flexible in terms of Hardware. Note - This software I tried with Proteus not on actual hardware. Put comment belo

How to interface USB modem to ARM board (for android or linux)

How to interface 3G usb modem to any ARM (Android / linux ported) Board.  Hi I am now going to provide quick steps to interface the 3G usb modem to linux/ Android SBC which i have tried during my try which is successful one . More and more USB devices when plugged in for the first time they act like a flash storage and start installing the driver from there. After installation (and on every consecutive plugging) the driver switches the mode internally, the storage device vanishes (in most cases), and a new device (like an USB modem) shows up.       Few modems (Huawie) most of time they do not need to switch from mass storage to usb modem mode. When you connect that modem to USB port then it will be detected as ttyUSB (3 ttyUSB ports are detected). Otherwise you need to switch the mode of usb modem by using usb_modeswitch utility (I am giving examples of idea modem / reliance modem which are from Huawei and a dlink 3G modem which requires usb modeswitch). Follow the steps to