Getting strange warning with 2 of 3 identical right shift?

Hi guys,

I'm a pretty confused newbie right now. Not sure what happened with my code but it was working flawlessly until (???) happened - then I started getting weird results on the serial monitor and noticed 2 warnings when my code compile, which I didn't notice before, I'm wondering if that could explain the mess.

My code is pretty simple, it reads/erase/write bytes from/to an EEPROM chip (Winbond W25Q16BV).

I have 3 'address' variables, declared and initilialized as follow:

void loop()
{
unsigned long read_address;
unsigned long erase_address;
unsigned long write_address;

...some code...

erase_address = 0;
erase_eeprom(erase_address);
write_address = 0;
write_eeprom(write_address);
read_address = 0;
read_eeprom(read_address);

...more code...
}

void erase_eeprom(unsigned long address)
{
  ...
  spi((byte)address>>16);  //MSB
  spi((byte)address>>8); 
  spi((byte)address);        //LSB
  ...
}
void write_eeprom(unsigned long address)
{
  ...
  spi((byte)address>>16);  //MSB
  spi((byte)address>>8); 
  spi((byte)address);        //LSB
  ...
}
void read_eeprom(unsigned long address)
{
  ...
  spi((byte)address>>16);  //MSB
  spi((byte)address>>8); 
  spi((byte)address);        //LSB
  ...
}

All 3 functions handles the unsigned long address pretty much the same way, but I'm getting right shift warnings on the erase and write function and I can't figure out why:

W25Q16BV_readv2.ino: In function 'void sector_erase(long unsigned int)':
W25Q16BV_readv2.ino:174: warning: right shift count >= width of type
W25Q16BV_readv2.ino: In function 'void write_eeprom(long unsigned int, byte)':
W25Q16BV_readv2.ino:186: warning: right shift count >= width of type

As far as I know, an unsigned long is 4bytes/32bits... why would I get this warning when right shifting 16 bits ?
And why am I getting the warning only on those 2, but not the read_eeprom function?

A byte is 8 bits wide.
What do you think happens to it, if you shift it right sixteen bits?

Yeah... I get it now - I guess I really misunderstood using a typecast and shifting at the same time, thanks for clearing that up. I must have added this at some point and can't remember.

I'm still confused why I'm not getting the same warning on the read_eeprom() function though...

EDIT....
Actually, I just figured out where I failed... it was supposed to be:

spi((byte)(address>>16));
...

Is that really your code?
Why have you put a semicolon at the end of the function definitions?

Not really the code, typed in by hand in my post... beginner mistake, I don't usually put semi-colon at the end of my function declaration :wink:

I made some edits to avoid further confusion... thanks.

typed in by hand in my post.

why not post your actual code?

RicThot:
Not really the code, typed in by hand in my post

For future reference, when posting code it's always best to post code that actually compiles and shows the problem. (If the sections of code that were represented by ... were not needed to show the problem, you could have simply left out the elided code completely.)

I sent the email from a different computer - Here's the full code:

#include <stdio.h>

//Pins 
#define MOSI 11
#define MISO 12
#define CLK  13
#define CS	 10

//opcodes
#define WRITE 0x02    //page program
#define READ  0x03    //read data
#define WREN  0x06    //write enable
#define ERASE 0x20		//erase 4k sector

void setup()
{
  Serial.begin(115200);

  pinMode(MOSI, OUTPUT);
  pinMode(MISO, INPUT);
  pinMode(CLK, OUTPUT);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);  //disable device

  //Set SPI Control Register:
  SPCR = (1<<SPE)|(1<<MSTR);
  
  Serial.println("\nSetup done...\n");
  delay(10);
}

void loop()
{
  byte data[256]  = {0xff,0xff,0xff,0xff,0xff,..stripped for display purpose...,0xc9};
  char byte_buffer[1];
  char szBuffer[8];
  byte eeprom_data;
  unsigned long read_address;
  unsigned long erase_address;
  unsigned long write_address;
  int iBytes = 1;
  
  //Erase a 4K sector - required for successful writing
  address = 0; //0x00000000
  Serial.println("\nErasing 4K sector... ");
  sector_erase(erase_address);
  Serial.println("Done erasing...\n");
  delay(1000);
  
  //Writing to eeprom
  Serial.println("\nWriting data");
  address = 0;
  write_eeprom(write_address, data);
  Serial.println("Done writing...\n");
  delay(1000);
  
  //Reading EEPROM
  address = 0;  //Start address of device memory
  Serial.println("Reading EEPROM...\n");
  sprintf(szBuffer, "%#08lx  ", address);
  Serial.print(szBuffer);
  
  for (int i=0; i<256; i++)  //read 256 bytes, for testing purposes
  {
    if (iBytes > 32) //Printing to serial monitor in rows of 32 bytes
    {
      Serial.print("\n");
      sprintf(szBuffer, "%#08lx  ", address);
      Serial.print(szBuffer);
      iBytes = 1;
    }
    delay(1);
  }
  Serial.println("\n\nDone reading...");
  delay(1);
  
  exit(0);
}

char spi_transfer(volatile byte data)
{
  delay(1);
  SPDR = data;                
  while (!(SPSR & (1<<SPIF)));
  return SPDR;                
}

byte read_eeprom(unsigned long EEPROM_address)
{
  //read EEPROM data
  byte data;
  digitalWrite(CS, LOW);            
  spi_transfer(READ);                        
  spi_transfer((byte)(EEPROM_address>>16));  //address bits 23-16
  spi_transfer((byte)(EEPROM_address>>8));   //address bits 15-8
  spi_transfer((byte)(EEPROM_address));      //address bits 7-0
  data = spi_transfer(0xFF);                 
  digitalWrite(CS, HIGH);
  return data;
}

void write_enable()
{
  digitalWrite(CS, LOW);
  spi_transfer(WREN);
  digitalWrite(CS, HIGH);
  delay(10);
}

void sector_erase(unsigned long erase_address)
{
  write_enable();
  digitalWrite(CS, LOW);
  spi_transfer(ERASE);
  spi_transfer((byte)(erase_address>>16));	//address bits 23-16
  spi_transfer((byte)(erase_address>>8));   //address bits 15-8 
  spi_transfer((byte)(erase_address));      //address bits 7-0  
  digitalWrite(CS, HIGH);
  delay(10);
}

void write_eeprom(unsigned long address, byte data[])
{
  write_enable();
  digitalWrite(CS, LOW);
  spi_transfer(WRITE);
  spi_transfer((byte)(address>>16));
  spi_transfer((byte)(address>>8));
  spi_transfer((byte)(address));  
  for (int i=0; i<256; i++)
  {
    spi_transfer(data[i]);
    delay(1);
  }
  digitalWrite(CS, HIGH);
  delay(10);
}