looking to write shiftout function in GCC

I am trying to do what arduino SHIFTOUT function does, but not sure how to code the following line in gcc :
“digitalWrite(dataPin, !!(val & (1 << (7 - i))));”

 void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
 { 
      uint8_t i; 

      for (i = 0; i < 8; i++)  { 
            if (bitOrder == LSBFIRST) 
                  digitalWrite(dataPin, !!(val & (1 << i))); 
            else      
                  digitalWrite(dataPin, !!(val & (1 << (7 - i)))); 
                  
            digitalWrite(clockPin, HIGH); 
            digitalWrite(clockPin, LOW);            
      } 
}

The Arduino IDE uses gcc as its compiler so in that sense the line is already being used in gcc.
Can you explain what you want to do in more detail ?

I want to implement serial data interface outside Arduino IDE and looking to do what digitalwrite does using general C commands.
I will be interfacing a Nokia 5510 display to atmega1284 in an non arduino enviornment.
or let me ask this question in another way. how would you implemenet SHIFTOUT function without using digitalwrite function ?
Since digitalwrite sends bit by bit info using lower gcc commands one should be able to achieve that and thats what iam looking for.

regards

It sounds like what you need are the port manipulation commands http://arduino.cc/en/Reference/PortManipulation
The ports are chip specific but here is a simple example that runs on a Uno

void setup() 
{  
  DDRB = B00100000;  //set pin 13 as output
}

void loop() 
{
  PORTB = B00100000;  //pin 13 HIGH
  delay(1000);
  PORTB = B00000000;  //pin 13 LOW
  delay(1000);
}

hi !
no I know how to turn bits on and off . I am looking for what the SHIFTOUT code is doing if you look at my posted code above you will see its doing much more than just turning bit on or off . its using some function Digitalwrite in a specific way

its using some function Digitalwrite in a specific way

It's using it to turn some pins off and on!

let me ask this question in another way. how would you implemenet SHIFTOUT function without using digitalwrite

I'd just add the required libs to the IDE I was going to use or something like "make" gcc on its own.

Mark

C Code Example (1)
void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
/* Enable SPI, Master, set clock rate fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
void SPI_MasterTransmit(char cData)
{
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
;
}

Example from AtMega328 data sheet

aliyesami:
hi !
no I know how to turn bits on and off . I am looking for what the SHIFTOUT code is doing if you look at my posted code above you will see its doing much more than just turning bit on or off . its using some function Digitalwrite in a specific way

As Paul said, all digitalWrite() does is turn bits on/off in a port register.
The Arduino pin # passed to the digitalWrite() function
is used to lookup the h/w port and h/w bit associated with that Arduino Pin #
so the underlying code can turn on/off that bit in the port register.
When the bit is 1 the associated output pin is high and when 0
it is low.


Lots of bad and incorrect terminology going on in this thread.
There are no "commands" in C
That isn't how the language works.
Things like digitalWrite() are functions that are called.
They are not are not part of gcc (which is the compiler) or the
C, or C++ language.
They are implented by other library code that comes with the Arduino IDE.


The problem with trying to implment something like digitalWrite() yourself
is that digitalWrite()/digitalRead() use the concept of a pin#.
That is an Arduino thing.
A pin # is not part of the actual hardware inside in the microcontroller
so it really has no meaning outside of the Arduino environment.
The microcontroller uses registers and bits.
So the first big stumbling block you have is that when not using digitalWrite()/digitalRead()
and writing your own code to control the microcontroller registers directly, you can't use Arduino pin #s.
Because of that, the semantics are totally different.
You now have to know which register and which bit to set/clear.
Once you know which register and which bit to set/clear, then you just
set/clear the appropriate bit in the register.
How you get that register and bit is up to you.
A few options:
You can look it up based on a pin# like digitalWrite()/digitalRead() does.
You can hard hard code it, perhaps with defines.

The Arduino enviroment hides all that by providing a pin # based API instead.
The cost of that is that there has to be a lookup to map between a pin # and
register and bit.
The way the Arduino core code was written, that lookup happens
at run time every single time the call to digitalWrite()/digitalRead() is done
so there is considerable overhead compared to directly setting/clearing
a bit in port register.

The benefit of an interface like that is that it is much simpler from a user
perspective, and the code becomes fairly portable across different processors.

--- bill

You need to define how closely your desired code needs to duplicate the functionality of the arduino function.
Does it need to abstract the pins used as “pin numbers” ala arduino, or can you make do with port names and bit numbers?
Does it need to support variable pins/ports/bits, or will you always write to a particular, constant, set of pins?
Here’s an obvious translation that may or may not do what you want, and requires that you have the various uppercase symbols defined somewhere else.

void shiftOut(uint8_t bitOrder, uint8_t val)
{ 
  uint8_t i; 

  for (i = 0; i < 8; i++)  { 
    if (bitOrder == LSBFIRST)  {
      if (val & (1 << i))
	DATAPORT |= 1<<DATABIT;
      else
	DATAPORT &= ~1<<DATABIT;
    } else {      
      if (val & (1 << (7 - i))) {
	if (val & (1 << i))
	  DATAPORT |= 1<<DATABIT;
	else
	  DATAPORT &= ~1<<DATABIT;
      }
    }
    CLOCKPORT |= 1<<CLOCKBIT;
    CLOCKPORT &= ~1<<CLOCKBIT;
  }
}

BTW, I really hate how the current code extracts the individual bits. You should change that too.

westfw:
BTW, I really hate how the current code extracts the individual bits. You should change that too.

yeah, the implementation of that code is terrible from a performance perspective.
You can speed it up quite a bit if you break out the LSB MSB stuff first
and then have two different loops.
Then instead of the goofy bit mask shifts they do,
you shift the original value and look at fixed bit.
The direction of the shift and the bit to look at
depend on which loop you are in (the MSB or the LSB loop).

Even better is to lookup the port address and bit mask for the pin once up front
then use indirect port i/o using the address and bit mask during the actual shift out loop.
(you will have to mask interrupts during actual bit twiddling or the full shift operation)

Doing both together is probabaly enough performance for all but the most demanding
use cases.

Here is an example of code from a FIO utility that is used in an LCD library
that uses this technique.

fio_shiftOut (fio_register dataRegister, fio_bit dataBit,
fio_register clockRegister, fio_bit clockBit,
uint8_t value, uint8_t bitOrder)
{
	// # disable interrupts
	int8_t i;

	if(bitOrder == LSBFIRST)
	{
		for(i = 0; i < 8; i++)
		{
			ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
			{
				if(value & 1)
				{
					fio_digitalWrite_HIGH(dataRegister, dataBit);
				}
				else
				{
					fio_digitalWrite_LOW(dataRegister, dataBit);
				}
				value >>= 1;
				fio_digitalWrite_HIGH (clockRegister, clockBit);
				fio_digitalWrite_LOW (clockRegister,clockBit);
			}
		}

	}
	else
	{
		for(i = 0; i < 8; i++)
		{
			ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
			{
				if(value & 0x80)
				{
					fio_digitalWrite_HIGH(dataRegister, dataBit);
				}
				else
				{
					fio_digitalWrite_LOW(dataRegister, dataBit);
				}
				value <<= 1;
				fio_digitalWrite_HIGH (clockRegister, clockBit);
				fio_digitalWrite_LOW (clockRegister,clockBit);
			}
		}
	}
}

This code uses some custom types and other initalization functions (not shown), but
the code could be written to do the port and bit mask lookup in the function
to maintain 100% compability with the existing API and still provide a substantial
performance boost.

— bill