Go Down

Topic: Interface SRAM with arduino due micro. without using external bus interface (Read 468 times) previous topic - next topic

monika_mahajan_123

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

earx

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

monika_mahajan_123

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

earx

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

monika_mahajan_123

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



earx

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..

monika_mahajan_123

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

earx


Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy