Interface SRAM with arduino due micro. without using external bus interface

Dear Sir,

Please tell me how to connect & interface SRAM with arduino due microcontroller without using external bus interface. I have assign I/O my own to interface with SRAM memory.

I am using atmel studio 6.2 IDE. Do we need to enable any peripheral for that. What kind of register we need to programme for that.

Can you please tell me how to interface memory device from arduino due microcontroller. I urgently need that code.

Regards
Monika

Hi Monika,

Hm, reading your question.. I don't completely understand what you mean. But I guess you want to interface external SRAM IC's without the need for any additional bus interface IC's. If this is so:

You can use the SPI on the Due to interface with external SRAM chips. What I do is use the 23LC1024 from Microchip: http://www.microchip.com/wwwproducts/Devices.aspx?product=23LC1024 . This chip is very easy to use, and the manual is great! I attached 4 of them to the Due, giving me 512 kByte of external SRAM.

You can use the main SPI on the Due, which is easiest. And you can just start by using programmed I/O. Just poke and peek those SPI hardware registers from your main program. Eventually I started using the DMA Controller, which is fast and completely offloads the CPU!

If you have already used up the SPI, you can use one of the USARTs in SPI mode. This may be used in conjunction with the PDC DMA controller, which also yields excellent results.

If you need any more information or code, just let me know..

Cheers,
Pieter

Dear Sir,

Yes I want to interface external SRAM IC's without the need for any additional bus interface provided in due broad. I am not using SPI interface too.I have configured GPIO port of due to interface with memory. attaching my code, but what i am seeing that i am reading port in place of memory.

Do i need to configure PMC register too to access i/p line information.
Reading the I/O line levels requires the clock of the PIO controller to be enabled, otherwise
PIO_PDSR reads the levels present on the I/O line at the time the clock was disabled.

I have written code for interfacing external memory device (HM62V16100I) with arduino due micro controller.
I am writing 10 different data (from a to j) on 10 different address location.
& I wanted to read the same data (from a to j) when I am doing the read operation from memory.

But what i am seeing only the last data (j) is coming 10 times.(may be i am reading the ports).

How to read external memory device.Do we need to enable something(some register). I am not using external bus interface, I have assign I/O my own to interface with external memory.

I am not sure port register that i have used is correct.

can you please tell me how to interface external memory device from arduino due microcontroller. I urgently need that code.

/*********************************************IO

SIGNALS********************************************

LIBS SIGNAL#######

PB15----LIBS_DATA(INPUT TO uC)

PB12----TC_SERIAL_DATA(OUTPUT)

PA0----TC_TRP_PULSE(OUTPUT)

PB13----TC_SERIAL_CLOCK(OUTPUT)

PB25----DH_DATA_READ_ENABLE(OUTPUT)

PB26----DH_MODE(OUTPUT)

PB27----DH_CLOCK(OUTPUT)

PB16----LIBS_DATA_READY(INPUT)

PB14----LIBS_ON_OFF(INPUT)

SRAM memory ADDRESS#####

PC1----SRAM ADDRESS:AD0(OUTPUT)

PC2----SRAM ADDRESS:AD1(OUTPUT)

PC3----SRAM ADDRESS:AD2(OUTPUT)

PC4----SRAM ADDRESS:AD3(OUTPUT)

PC5----SRAM ADDRESS:AD4(OUTPUT)

PC6----SRAM ADDRESS:AD5(OUTPUT)

PC7----SRAM ADDRESS:AD6(OUTPUT)

PC8----SRAM ADDRESS:AD7(OUTPUT)

PC9----SRAM ADDRESS:AD8(OUTPUT)

PC12----SRAM ADDRESS:AD9(OUTPUT)

PC13----SRAM ADDRESS:AD10(OUTPUT)

PC14----SRAM ADDRESS:AD11(OUTPUT)

PC15----SRAM ADDRESS:AD12(OUTPUT)

PC16----SRAM ADDRESS:AD13(OUTPUT)

PC17----SRAM ADDRESS:AD14(OUTPUT)

PC18----SRAM ADDRESS:AD15(OUTPUT)

PC19----SRAM ADDRESS:AD16(OUTPUT)

PC21----SRAM ADDRESS:AD17(OUTPUT)

PC22----SRAM ADDRESS:AD18(OUTPUT)

PC23----SRAM ADDRESS:AD19(OUTPUT)

SRAM memory DATA#####

PD0----SRAM DATA:D0(IN/OUTPUT)

PD1----SRAM DATA:D1(IN/OUTPUT)

PD2----SRAM DATA:D2(IN/OUTPUT)

PD3----SRAM DATA:D3(IN/OUTPUT)

PD4----SRAM DATA:D4(IN/OUTPUT)

PD5----SRAM DATA:D5(IN/OUTPUT)

PD6----SRAM DATA:D6(IN/OUTPUT)

PD7----SRAM DATA:D7(IN/OUTPUT)

PD8----SRAM DATA:D8(IN/OUTPUT)

PD9----SRAM DATA:D9(IN/OUTPUT)

PD10----SRAM DATA:D10(IN/OUTPUT)

PC24----SRAM DATA:D11(IN/OUTPUT)

SRAM memory Control lines#####

PC28----SRAM CONTROL:WE bar(OUTPUT)

PC25----SRAM CONTROL:OE bar(OUTPUT)

PA19----SRAM CONTROL:UB bar(OUTPUT)

PA20----SRAM CONTROL:LB bar(OUTPUT)


*****/

#include <asf.h>

/*******************************FUNCTIONS FOR

UART*****************************************************/
void uart_ini(void);
void uart_tx(unsigned char DATA);
unsigned char uart_rx(void);

unsigned char LIBS_DATA[88625];// this memory location used to store the LIBS data
//unsigned char LIBS_DATA[88835];// this memory location used to store the LIBS data
union int_char // this union is used to convert int val to two char or two char to int
{
unsigned int ival;
unsigned char cval[2];
}conv;

unsigned long cycle_count=0;
unsigned long data_cycle=0;
unsigned long data_count=0;
unsigned long pulsenum=0;
unsigned long r;
unsigned char chr=0;
unsigned long t=0;
unsigned long DATA0_10=0,DATA24=0,DATA_12=0;
unsigned long ADD=0,ADD1_9=0,ADD12_19=0,ADD21_23=0;
unsigned long ADD_TEMP=0;
unsigned long count=0;
int main (void)
{
//unsigned int p;
sysclk_init();// system clock enable
board_init();// board function enable

/********************************POAR C I/O

configuration******************************/
/********************************prg for o/p address

lines*****************************/
/********************************PC24 as i/o lines initially made as

o/p***************/
REG_PIOC_WPMR=0x50494F00;
REG_PIOC_PER=0x13EFF3FE; //0x12EFF3FE;
REG_PIOC_PDR=0xEC100C01; //0xED100C01;
REG_PIOC_OER=0x13EFF3FE; //0x12EFF3FE
REG_PIOC_ODR=0xEC100C01; //0xED100C01;
REG_PIOC_IDR=0xFFFFFFFF;
REG_PIOC_OWER=0x13EFF3FE; //0x12EFF3FE
REG_PIOC_PUDR=0x13EFF3FE;
REG_PIOC_PUER=0x00000000;
REG_PIOC_CODR=0x13EFF3FE;
// clear all output pin

/******************************** I/O configuration as per new

console**********/
REG_PIOB_WPMR=0x50494F00;
REG_PIOB_PER =0x0E01F000;
REG_PIOB_PDR=0xF1FE0FFF;
REG_PIOB_OER=0x0E003000;
REG_PIOB_ODR=0xF1FFCFFF;
REG_PIOB_IDR=0xFFFFFFFF;
REG_PIOB_OWER=0x0E003000;
REG_PIOB_PUDR=0x0E003000;
REG_PIOB_PUER=0x0001C000;
REG_PIOB_CODR=0x0E003000;// clear all output pin

REG_PIOA_WPMR=0x50494F00;
REG_PIOA_PER =0x00188000;
REG_PIOA_PDR=0x00008000; //**
REG_PIOA_OER=0x00180000;
REG_PIOA_ODR=0x00008000; //**
REG_PIOA_IDR=0xFFFFFFFF;
REG_PIOA_OWER=0x00180000;
REG_PIOA_PUDR=0x00180000;
REG_PIOA_PUER=0x00008000; //**
REG_PIOA_CODR=0x00180000;// clear all output pin

/********************************POAR C I/O

configuration******************************/
/********************************prg for I/O lines initially made as

o/p*****************************/
REG_PIOD_WPMR=0x50494F00;
REG_PIOD_PER=0x000007FF;
REG_PIOD_PDR=0xFFFFF800;
REG_PIOD_OER=0x000007FF;
REG_PIOD_ODR=0xFFFFF800;
REG_PIOD_IDR=0xFFFFFFFF;
REG_PIOD_OWER=0x000007FF;
REG_PIOD_PUDR=0x000007FF;
REG_PIOD_PUER=0x00000000;
REG_PIOD_CODR=0x000007FF;

uart_ini();// uart function initialization

while(1)
{

chr=uart_rx();

if(chr=='n')
{

chr=uart_rx();
chr=0;
t = 1 ;
}
if (t == 1) {
ADD= 0x00000000; //(write opeation)
chr = 'a';
REG_PIOC_SODR|=0x02000000 ; //memory OE bar (for read

& write)
REG_PIOC_SODR|=0x10000000 ; //memory WE bar (for writing)
for (cycle_count=0;cycle_count<10; cycle_count++) {

for(r=0;r<10000;r++);

/write into memory start****/
ADD1_9=(ADD&0x000001FF)<<1;
ADD12_19=(ADD&0x0001FE00)<<3;
ADD21_23=(ADD&0x000E0000)<<4;

REG_PIOC_ODSR=(ADD1_9|ADD12_19|ADD21_23); //Addressing processing

REG_PIOC_CODR|=0x10000000 ; //memory WE bar (for writing)

REG_PIOD_ODSR= chr; //data i/p-o/p

REG_PIOC_SODR|=0x10000000 ; //memory WE bar (for writing)

chr ++;

ADD ++;

}

ADD= 0x00000000;
/******make i/O lines as i/p (read opeation) *****************/
REG_PIOD_OER=0x00000000;
REG_PIOD_ODR=0xFFFFFFFF;

for (cycle_count=0;cycle_count<10; cycle_count++) {

ADD1_9=(ADD&0x000001FF)<<1;
ADD12_19=(ADD&0x0001FE00)<<3;
ADD21_23=(ADD&0x000E0000)<<4;

REG_PIOC_ODSR=(ADD1_9|ADD12_19|ADD21_23);

for(r=0;r<10000;r++);
REG_PIOC_CODR|=0x02000000 ;//memory OE bar (for read & write)

conv.ival=REG_PIOD_ODSR; //data i/p-o/p

REG_PIOC_SODR|=0x20000000 ; //memory WE bar (for reading)

ADD ++;

uart_tx=conv.cval[1];
uart_tx=conv.cval[0];
conv.cval[1]=0;
conv.cval[0]=0;
conv.ival=0;

} t = 0;

}

}
}

void uart_ini(void)
{
REG_PIOA_WPMR =0x50494F00;
REG_PIOA_PER|=0x00000c00;
REG_PIOA_PDR|=0x00000300;
REG_PIOA_OER|=0x00000200;
REG_PIOA_PUDR|=0x00000200;
REG_PIOA_PUER|=0x00000100;
REG_PIOA_ODR|=0x00000100;
REG_PIOA_ABSR=0x00000000;
REG_UART_CR=0x00000000;
REG_UART_CR=0x00000050;
REG_UART_MR=0x00000800;
REG_UART_IER=0x00000000;
REG_UART_IDR=0xFFFFFFFF;
REG_UART_BRGR=0x0000002E;
//REG_UART_BRGR =0x00000017;
}
void uart_tx(unsigned char DATA)
{
while(!(REG_UART_SR&0x00000002));
REG_UART_THR=DATA;
}

unsigned char uart_rx(void)
{
unsigned char DATA;
while(!(REG_UART_SR&0x00000001));
DATA=(unsigned char)REG_UART_RHR;
return DATA;
}

Regards
Monika

ok, quite a different situation from what i imagined. i thought this was a design question. apparently you already have the SRAM IC and code for it.

this is most likely the problem:

conv.ival=REG_PIOD_ODSR;

should probably be:

conv.ival=REG_PIOD_PDSR;

you were reading from the output, not the input. also, you should enable the inputs for this port using PIO_PER (0xFFFFFFFF) and PIO_ODR (0xFFFFFFFF). and for writing you should do the reverse.

from what i can see:

REG_PIOC_CODR|=0x10000000;

is not very useful.

the CODR and SODR registers don't have to be ORred. they can just be written to if you want to set/clear a bit.

it should be:
REG_PIOC_CODR=0x10000000;

hope this helps!

cheers,

Pieter

Dear Sir,

Thanks for quick reply.

REG_PIOD_ODSR is write/read register for that reason i am using for write as well as for read.

I have tried with REG_PIOD_PDSR too like below but results are similar.

if(REG_PIOC_PDSR & 0x01000000) //PC24
{
conv.ival=(conv.ival|1)<<1;
} else {
conv.ival=(conv.ival|0)<<1;
}

if(REG_PIOD_PDSR & 0x00000400) //PD10
{
conv.ival=(conv.ival|1)<<1;
} else {
conv.ival=(conv.ival|0)<<1;
}
if(REG_PIOD_PDSR & 0x00000200) //PD9
{
conv.ival=(conv.ival|1)<<1;
} else {
conv.ival=(conv.ival|0)<<1;
}
if(REG_PIOD_PDSR & 0x00000100) //PD8
{
conv.ival=(conv.ival|1)<<1;
} else {
conv.ival=(conv.ival|0)<<1;
}
if(REG_PIOD_PDSR & 0x00000080) //PD7
{
conv.ival=(conv.ival|1)<<1;
} else {
conv.ival=(conv.ival|0)<<1;
}
if(REG_PIOD_PDSR & 0x00000040) //PD6
{
conv.ival=(conv.ival|1)<<1;
} else {
conv.ival=(conv.ival|0)<<1;
}
if(REG_PIOD_PDSR & 0x00000020) //PD5
{
conv.ival=(conv.ival|1)<<1;
} else {
conv.ival=(conv.ival|0)<<1;
}
if(REG_PIOD_PDSR & 0x00000010 ) //PD4
{
conv.ival=(conv.ival|1)<<1;
} else {
conv.ival=(conv.ival|0)<<1;
}
if(REG_PIOD_PDSR & 0x00000008) //PD3
{
conv.ival=(conv.ival|1)<<1;
} else {
conv.ival=(conv.ival|0)<<1;
}
if(REG_PIOD_PDSR & 0x00000004) //PD2
{
conv.ival=(conv.ival|1)<<1;
} else {
conv.ival=(conv.ival|0)<<1;
}
if(REG_PIOD_PDSR & 0x00000002 ) //PD1
{
conv.ival=(conv.ival|1)<<1;
} else {
conv.ival=(conv.ival|0)<<1;
}
if(REG_PIOD_PDSR & 0x00000001) //PD0
{
conv.ival=(conv.ival|1);
} else {
conv.ival=(conv.ival|0);
}

Yes I am enabling the port as i/p(read time) using

REG_PIOD_OER=0x00000000;
REG_PIOD_ODR=0xFFFFFFFF; //disable the o/p

for port as i/p(write time) using

REG_PIOD_OER=0xFFFFFFFF; //enable the o/p
REG_PIOD_ODR=0x00000000;

PIO_PER is already enable once(both for write & read) :1: Enables the PIO to control the corresponding pin (disables peripheral control of the pin).

why we need to make PIO_PER as 0x00000000 for write operation, Can you please explain.

I will correct REG_PIOC_CODR|=0x10000000 & REG_PIOC_SODR|=0x10000000 to REG_PIOC_CODR=0x10000000 & REG_PIOC_SODR=0x10000000; & get back to you shortly.

Regards
Monika

PDSR vs ODSR: Atmel's own code:

uint32_t pio_get(Pio *p_pio, const pio_type_t ul_type,
 const uint32_t ul_mask)
{
 uint32_t ul_reg;

 if ((ul_type == PIO_OUTPUT_0) || (ul_type == PIO_OUTPUT_1)) {
 ul_reg = p_pio->PIO_ODSR;
 } else {
 ul_reg = p_pio->PIO_PDSR;
 }

 if ((ul_reg & ul_mask) == 0) {
 return 0;
 } else {
 return 1;
 }
}

meaning, if a pin is configured as input, they do read from PIO_PDSR, otherwise the if statement would be useless and you will just read back the output.

this code is from the pio.c file from Atmel. it contains a lot more code, which should be useful to you. but i think you already very close to your goal and maybe only 1 or 2 register assignments are missing..

Thank you so much, my code is working after putting all efforts. I went for an workshop from past 4 days, so today morning i tried this code using PIO_PDSR in place of PIO_ODSR & what is seeing is my code is working. I am able to write/read properly into memory. I am very happy.

from monika

hi Monika,

that's great news!

cheers,

pieter