Hi, I have an AT45DB161 flash memory chip connected to our msp430F1611 running at 8Mhz. Here is the connection scheme. P5.1 -> SI P5.2 <- SO P5.3 -> SCLK P5.4 -> /CS P5.5 -> /RST P1.0 -> RDY-/BUSY After power up, initialize clocks and etc, AT45 is initialized with the fFlash_InitHW_Active(). The AT45 is reset with fFlash_Reset(). Then to check if the flash memory is ok, fFlash_RStatus_Once() is called. But this function returns an unexpected 0x00. I am sure there is a simple mistake in the software. I have checked the soldering and pin configuration but everything seems to be ok. If you can spot any mistakes in the below pasted code I would be grateful. Thanks in advance. Onur Yildirim. void fFlash_InitHW_Active(void) { P5OUT |= 0x30; // /CS and /RST high P5DIR |= 0x30; // /CS and /RST output P5SEL &= ~0x30; // P5.5 and P5.4 IO function P5DIR |= 0x0A; // P5.1(SIMO) and P5.3 (CLK) ouput P5DIR &= ~0x04; // P5.2(SOMI) input P5SEL |= 0x0E; // P5.1 P5.2 P5.3 UART functns U1CTL = 0x17; // 8bit SPI in master mode U1TCTL = 0x23; // SPI mode?, ACLK 3 pin mode U1BR0 = 2; // Clock divider=2 -> SPI clock = ACLK/2 U1BR1 = 0; U1MCTL = 0; ME2_bit.USPIE1 = 1; // enable SPI channel1 U1CTL_bit.SWRST = 0; // end reset IE2_bit.UTXIE1 = 0; // disable tx interrupt for now IE2_bit.URXIE1 = 0; // disable rx interrupt for now } void fFlash_Reset(void) { // ASSUMES 8MHz MCLK for 10 microsec delay // (more than 2.5 millisec if 32 kHz) // reset pulse (at least 10 microsec) P5OUT &= ~P5OUT_5; //set low for (volatile int i=0; i<20; i++) {}; P5OUT |= P5OUT_5; //set high for (volatile int i=0; i<20; i++) {}; } unsigned char fFlash_RStatus_Once(void) { // Reads status register from flash fFlash_CSHi(); fFlash_CSLo(); fFlash_W(kFlash_Cmnd_ReadStatus); // kFlash_Cmnd_ReadStatus = 0xB7 return fFlash_RW(0x00); } inline void fFlash_CSHi(void) { //programmed io , assume tx register empty P5OUT |= 0x10; // /CS high __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) return; } inline void fFlash_CSLo(void) { //programmed io , assume tx register empty P5OUT &= ~(0x10); // /CS high __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) return; } inline void fFlash_W(unsigned char outbyte) { // Writes a byte if TX register empty. // Does not wait for received byte. // Programmed IO, assume TX register empty. while (!(IFG2_bit.UTXIFG1)){}; // wait for txreg to empty U1TXBUF=outbyte; // write byte } inline unsigned char fFlash_RW(unsigned char outbyte) { // Programmed IO, assume TX register empty unsigned char res; while (!(U1TCTL_bit.TXEPT)){}; // wait for txshift empty wait for last data res = U1RXBUF; // get byte U1TXBUF = outbyte; // write byte return res; }
at45db read write not working
Started by ●November 21, 2005
Reply by ●November 21, 20052005-11-21
The data sheet says that opcode 0xD7 returns device status. Your code says
that 0xB7 returns status (albeit in a comment only)...
/Bill
> Hi,
>
> I have an AT45DB161 flash memory chip connected to our msp430F1611
> running at 8Mhz. Here is the connection scheme.
>
> P5.1 -> SI
> P5.2 <- SO
> P5.3 -> SCLK
> P5.4 -> /CS
> P5.5 -> /RST
>
> P1.0 -> RDY-/BUSY
>
> After power up, initialize clocks and etc, AT45 is initialized with
> the fFlash_InitHW_Active().
>
> The AT45 is reset with fFlash_Reset().
>
> Then to check if the flash memory is ok, fFlash_RStatus_Once() is
> called. But this function returns an unexpected 0x00.
>
> I am sure there is a simple mistake in the software. I have checked
> the soldering and pin configuration but everything seems to be ok.
>
> If you can spot any mistakes in the below pasted code I would be grateful.
>
> Thanks in advance.
> Onur Yildirim.
>
> void fFlash_InitHW_Active(void)
> {
> P5OUT |= 0x30; // /CS and /RST high
> P5DIR |= 0x30; // /CS and /RST output
> P5SEL &= ~0x30; // P5.5 and P5.4 IO function
>
> P5DIR |= 0x0A; // P5.1(SIMO) and P5.3 (CLK) ouput
> P5DIR &= ~0x04; // P5.2(SOMI) input
> P5SEL |= 0x0E; // P5.1 P5.2 P5.3 UART functns
>
> U1CTL = 0x17; // 8bit SPI in master mode
> U1TCTL = 0x23; // SPI mode?, ACLK 3 pin mode
> U1BR0 = 2; // Clock divider=2 -> SPI clock = ACLK/2
> U1BR1 = 0;
> U1MCTL = 0;
>
> ME2_bit.USPIE1 = 1; // enable SPI channel1
> U1CTL_bit.SWRST = 0; // end reset
>
> IE2_bit.UTXIE1 = 0; // disable tx interrupt for now
> IE2_bit.URXIE1 = 0; // disable rx interrupt for now
> }
>
> void fFlash_Reset(void)
> {
> // ASSUMES 8MHz MCLK for 10 microsec delay
> // (more than 2.5 millisec if 32 kHz)
> // reset pulse (at least 10 microsec)
>
> P5OUT &= ~P5OUT_5; //set low
> for (volatile int i=0; i<20; i++) {};
>
> P5OUT |= P5OUT_5; //set high
> for (volatile int i=0; i<20; i++) {};
> }
>
> unsigned char fFlash_RStatus_Once(void)
> {
> // Reads status register from flash
>
> fFlash_CSHi();
> fFlash_CSLo();
>
> fFlash_W(kFlash_Cmnd_ReadStatus); // kFlash_Cmnd_ReadStatus = 0xB7
>
> return fFlash_RW(0x00);
> }
>
> inline void fFlash_CSHi(void)
> {
> //programmed io , assume tx register empty
>
> P5OUT |= 0x10; // /CS high
>
> __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK)
> __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK)
> __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK)
> __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK)
> return;
> }
>
> inline void fFlash_CSLo(void)
> {
> //programmed io , assume tx register empty
>
> P5OUT &= ~(0x10); // /CS high
>
> __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK)
> __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK)
> __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK)
> __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK)
> return;
> }
>
> inline void fFlash_W(unsigned char outbyte)
> {
> // Writes a byte if TX register empty.
> // Does not wait for received byte.
> // Programmed IO, assume TX register empty.
>
> while (!(IFG2_bit.UTXIFG1)){}; // wait for txreg to empty
> U1TXBUF=outbyte; // write byte
> }
>
> inline unsigned char fFlash_RW(unsigned char outbyte)
> {
> // Programmed IO, assume TX register empty
>
> unsigned char res;
> while (!(U1TCTL_bit.TXEPT)){}; // wait for txshift empty wait for last
data
>
> res = U1RXBUF; // get byte
> U1TXBUF = outbyte; // write byte
> return res;
> }
>
>
>
> .
>
>
> Yahoo! Groups Links
>
>
>
>
Reply by ●November 21, 20052005-11-21
Hi Bill,
--- In msp430@msp4..., w.sell@c... wrote:
>
> The data sheet says that opcode 0xD7 returns device status. Your code says
that 0xB7 returns status (albeit in a comment only)...
>
> /Bill
Yes, you are most definetely correct but I checked that constants
value and it was set as 0xD7 in the header file. So I guess that was
only a wrongly typed comment.
Thank you very much for your time though.
Onur Yildirim.
Reply by ●November 21, 20052005-11-21
Onur, Perhaps you should modify your fFlash_RW function to read as follows: inline unsigned char fFlash_RW(unsigned char outbyte) { // Programmed IO, assume TX register empty unsigned char res; while (!(U1TCTL_bit.TXEPT)){}; // wait for txshift empty wait for last data U1TXBUF = outbyte; // write byte while( !(IFG2 & URXIFG1)) {}; //wait for rx data res = U1RXBUF; // get byte return res; } The response from the DataFlash comes through on the empty ( 0x00 ) byte being transmitted, so you want to read after it has been sent. HTH, Matt Sabino ----- Original Message ----- From: "Onur Yildirim" <onur.yildirim@onur...> To: <msp430@msp4...> Sent: Monday, November 21, 2005 1:29 PM Subject: [msp430] at45db read write not working > Hi, > > I have an AT45DB161 flash memory chip connected to our msp430F1611 > running at 8Mhz. Here is the connection scheme. > > P5.1 -> SI > P5.2 <- SO > P5.3 -> SCLK > P5.4 -> /CS > P5.5 -> /RST > > P1.0 -> RDY-/BUSY > > After power up, initialize clocks and etc, AT45 is initialized with > the fFlash_InitHW_Active(). > > The AT45 is reset with fFlash_Reset(). > > Then to check if the flash memory is ok, fFlash_RStatus_Once() is > called. But this function returns an unexpected 0x00. > > I am sure there is a simple mistake in the software. I have checked > the soldering and pin configuration but everything seems to be ok. > > If you can spot any mistakes in the below pasted code I would be grateful. > > Thanks in advance. > Onur Yildirim. > > void fFlash_InitHW_Active(void) > { > P5OUT |= 0x30; // /CS and /RST high > P5DIR |= 0x30; // /CS and /RST output > P5SEL &= ~0x30; // P5.5 and P5.4 IO function > > P5DIR |= 0x0A; // P5.1(SIMO) and P5.3 (CLK) ouput > P5DIR &= ~0x04; // P5.2(SOMI) input > P5SEL |= 0x0E; // P5.1 P5.2 P5.3 UART functns > > U1CTL = 0x17; // 8bit SPI in master mode > U1TCTL = 0x23; // SPI mode?, ACLK 3 pin mode > U1BR0 = 2; // Clock divider=2 -> SPI clock = ACLK/2 > U1BR1 = 0; > U1MCTL = 0; > > ME2_bit.USPIE1 = 1; // enable SPI channel1 > U1CTL_bit.SWRST = 0; // end reset > > IE2_bit.UTXIE1 = 0; // disable tx interrupt for now > IE2_bit.URXIE1 = 0; // disable rx interrupt for now > } > > void fFlash_Reset(void) > { > // ASSUMES 8MHz MCLK for 10 microsec delay > // (more than 2.5 millisec if 32 kHz) > // reset pulse (at least 10 microsec) > > P5OUT &= ~P5OUT_5; //set low > for (volatile int i=0; i<20; i++) {}; > > P5OUT |= P5OUT_5; //set high > for (volatile int i=0; i<20; i++) {}; > } > > unsigned char fFlash_RStatus_Once(void) > { > // Reads status register from flash > > fFlash_CSHi(); > fFlash_CSLo(); > > fFlash_W(kFlash_Cmnd_ReadStatus); // kFlash_Cmnd_ReadStatus = 0xB7 > > return fFlash_RW(0x00); > } > > inline void fFlash_CSHi(void) > { > //programmed io , assume tx register empty > > P5OUT |= 0x10; // /CS high > > __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) > __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) > __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) > __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) > return; > } > > inline void fFlash_CSLo(void) > { > //programmed io , assume tx register empty > > P5OUT &= ~(0x10); // /CS high > > __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) > __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) > __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) > __no_operation(); // minimum CS high time%0 nsec (about 2 MCLK) > return; > } > > inline void fFlash_W(unsigned char outbyte) > { > // Writes a byte if TX register empty. > // Does not wait for received byte. > // Programmed IO, assume TX register empty. > > while (!(IFG2_bit.UTXIFG1)){}; // wait for txreg to empty > U1TXBUF=outbyte; // write byte > } > > inline unsigned char fFlash_RW(unsigned char outbyte) > { > // Programmed IO, assume TX register empty > > unsigned char res; > while (!(U1TCTL_bit.TXEPT)){}; // wait for txshift empty wait for last data > > res = U1RXBUF; // get byte > U1TXBUF = outbyte; // write byte > return res; > }
Reply by ●November 22, 20052005-11-22
Hi Matt,
> Perhaps you should modify your fFlash_RW function
to read as follows:
>
> inline unsigned char fFlash_RW(unsigned char outbyte)
> {
> // Programmed IO, assume TX register empty
>
> unsigned char res;
> while (!(U1TCTL_bit.TXEPT)){}; // wait for txshift empty wait for last
> data
> U1TXBUF = outbyte; // write byte
>
> while( !(IFG2 & URXIFG1)) {}; //wait for rx data
> res = U1RXBUF; // get byte
>
> return res;
> }
>
> The response from the DataFlash comes through on the empty ( 0x00 ) byte
> being transmitted, so you want to read after it has been sent.
Thank you very much for the hint. I will try and get back as soon as possible.
Regards,
Onur Yildirim
Reply by ●November 23, 20052005-11-23
Hi,
It was just wrongly configured SPI situation. After correcting
configuration settings it seems to work well now.
Thanks anyway.
Onur
> > Perhaps you should modify your fFlash_RW
function to read as follows:
> >
> > inline unsigned char fFlash_RW(unsigned char outbyte)
> > {
> > // Programmed IO, assume TX register empty
> >
> > unsigned char res;
> > while (!(U1TCTL_bit.TXEPT)){}; // wait for txshift empty wait for
last
> > data
> > U1TXBUF = outbyte; // write byte
> >
> > while( !(IFG2 & URXIFG1)) {}; //wait for rx data
> > res = U1RXBUF; // get byte
> >
> > return res;
> > }
> >
> > The response from the DataFlash comes through on the empty ( 0x00 )
byte
> > being transmitted, so you want to read after it has been sent.