Continue to Site

Welcome to

Welcome to our site! is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Really simple bitshift not working on AVR32

Not open for further replies.


Member level 1
Mar 9, 2008
Reaction score
Trophy points
Activity points

I have an AVR32 which needs to send 21 bit words (miniumum) to a CPLD.

I intend to use the SPI bus for this and have managed to set it all up, with a word size of 11 bit.

The idea is I take an integer, take the top 11 bits, shift it left 11 places, take the top 11 bits again, then send the two values in the reverse order I got them (the SPI sends data LSB first).

However my program is not working and I can't figure out why not, looking at the SPI output on a scope the LSBs (the first 21 bits sent) are always zero.

My test value is 0xFFFFFFFF so I should have to do a 16 bit shift before the value of the lower word starts dropping below its maximum surely?

Here is my code:
	spi_status_t 	response;
	unsigned short 	word_high = (data & 0xFFE0);
	data = data << 11; //shift left by 11 places to get next 11 bit word.
	unsigned short  word_low = (data & 0xFFE0);

	response = spi_write( spi, word_low);

	if( response == SPI_OK )
	{	while( spi_writeEndCheck(spi) == 0){}
		return spi_write( spi, word_high);
		return response;

The uC I am using is an Atmel AVR32 UC3B. The architecture is big-endian.

Can anyone see any obvious mistakes?

I assume 'unsigned short' is 16-bits?

If data is 0xffffffff, (64-bits)
word_high = (unsigned short)(data & 0xffe00000);

data <<= 11;

word_low = (unsigned short)(data & 0xffe00000);


    Points: 2
    Helpful Answer Positive Rating
Hi btbass,

I made the changes as you suggested (while kicking myself hard for the 0xffe0/0xffe00000 mistake) but now both shorts show a value of 0 in the debugger.

When I alter the mask to read 0xFFE0000F the short takes a value of 15.

I am sure my device is big-endian, page 5 of this document from Atmel certainly says so:, yet what with the SPI bus pushing data out LSB first (when I was sure the datasheet diagrams showed MSB first) im starting to doubt it.

Is it possible that my device could be big-endian, yet when type-casting to a smaller type the (device/compiler?) starts at the highest address (LSBs)?

EDIT: OK, I just thought what would be the result if every programming language in the world truncated the LSBs instead of the MSBs when doing a downsizing typecast (for starters half of anything I ever wrote wouldnt work!) so I think ill go alter my program before I make myself look any more stupid!

Thank you!

Im sure the compiler should take care of the endiness?
Another approach is

word_high = (uint16_t)(0xffe0 & (data >> 16));
word_low = (uint16_t)(0xffe0 & data);

Hi btbass,

I think it must do. I was just confused because I was picturing the typecast truncating the 16 LSBs (I still don't know where I got that idea from).

Now I mask off all but them, shift out that value, right shift 11 places and do the same again, looking at the scope it appears to work.

The other point of confusion was the order the SPI bus uses, it is MSB first unlike I gathered before due to my previous mistake.

It appears to send data MSB first but truncates the MSBs of the value, so cuts off the top 5 bits but sends the rest MSB first when I have a word size of 11.

Now I just wish I hadn't modified my CPLD program to accept LSB first....

Thanks for your help, I dont know how long I would have been floundering around for!

Not open for further replies.

Part and Inventory Search

Welcome to