Reply by Onur Yildirim 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.

Beginning Microcontrollers with the MSP430

Reply by Onur Yildirim 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 Matt Sabino 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 Onur Yildirim 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 w.se...@... 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 Onur Yildirim November 21, 20052005-11-21
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;
}