EmbeddedRelated.com

Additive White Gaussian Noise Generator

Dr Cagri Tanriover March 3, 20131 comment Coded in C
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define PI 3.1415926536

double AWGN_generator()
{/* Generates additive white Gaussian Noise samples with zero mean and a standard deviation of 1. */
 
  double temp1;
  double temp2;
  double result;
  int p;

  p = 1;

  while( p > 0 )
  {
	temp2 = ( rand() / ( (double)RAND_MAX ) ); /*  rand() function generates an
                                                       integer between 0 and  RAND_MAX,
                                                       which is defined in stdlib.h.
                                                   */

    if ( temp2 == 0 )
    {// temp2 is >= (RAND_MAX / 2)
      p = 1;
    }// end if
    else
    {// temp2 is < (RAND_MAX / 2)
       p = -1;
    }// end else

  }// end while()

  temp1 = cos( ( 2.0 * (double)PI ) * rand() / ( (double)RAND_MAX ) );
  result = sqrt( -2.0 * log( temp2 ) ) * temp1;

  return result;	// return the generated random sample to the caller

}// end AWGN_generator()

Stepper motor controller for precise movement

Amit Karna March 2, 20131 comment Coded in C++ for the x86
/*
 * IBM-PC Parallel Printer Port Data & Status Registers
 * ====================================================
 *        7   6   5   4   3   2   1   0   I/O Port
 *      +---+---+---+---+---+---+---+---+ ========
 * Data | C8| C7| C6| C5| C4| C3| C2| C1| Base = 278/378/3BC Hex
 *      +---+---+---+---+---+---+---+---+           +---+
 */
#include<sys/io.h>
#include<unistd.h>
#include<stdlib.h>
#include<math.h>	//for floor()
#include<iostream>
using namespace std;

#define BASEPORT 0x378 //SPP - Standard Parallel port base address

class stepper
{
	private:
		long delay;	//delay betn each step
		float pi;	//constant
		float acf, lcf;	//angle and length correction factors in percentage
		float r, c;	// radius and circumerence of wheel
		float ns;		
		int nfsc, nhs;	
		float residue;
		// number of total steps, full step cycles and number of half steps
		float step_rating;	//number of steps per revolution
		float speed;	//speed of stepper in cm/sec
		float l,w;	//length and width of robocar	
	public:
		stepper(float spd);
	
		void specification();
		
		void length2steps(float len, int& nfsc, int& nhs);//conversion
		void angle2steps(float angle, int& nfsc, int& nhs);//conversion
		void move(int nfsc, int nhs, int leftw, int rightw); //move
				
		void fwd(float len);	//length in cm
		void bkwd(float len);	//length in cm
			
		void righturn(float degree, int degree_of_freedom);	//number of degree turns
		void lefturn(float degree, int degree_of_freedom);	//  -- do --
};

stepper:: stepper(float spd=7)
{	
	speed=spd;
	l=18;		//length of car
	w=17-2;		//width of car
	acf=-2;		//angle correction factor in percentage
	lcf=-4;		//angle correction factor in percentage
	pi=3.14159;	//costant
	step_rating=200.5;	//step rating
	r=3.448;		//radius of wheel in cm
	c=2*pi*r;	//circumference
	residue=0;
	//speed being in cm/s
	delay=long(1/(step_rating/c*speed)*1000*1000);	//in microsecond
}

void stepper::specification()
{	
	cout<<"\n\n\n\t\tF R O N T I E R\n";
	cout<<"\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
	cout<<"\n\n\nDesigned by: Amit Kumar Karna";
	cout<<"\n\n\nMission: Vitrubio, Technozion'06 @ NIT Warangal";
	cout<<"\n\n\nROBOCAR specifications...";
	cout<<"\nDimensions = "<<l<<"cm x"<<w<<"cm";
	cout<<"\nWheel Dia = "<<2*r<<"cm";
	cout<<"\nStepper motor:  12V-0.33A \t"<<step_rating<<" steps/revolution";
	cout<<"\nLength n Angle correction factors: "<<lcf<<"% & "<<acf<<"% respectively";
	cout<<"\nSpeed selected : "<<speed<<"cm/sec";
	cout<<"\ndelay between each step = "<<delay/1000.0<<"ms";
	cout<<endl<<endl<<endl;
}

void stepper::length2steps(float len, int& nfsc, int& nhs)//conversion
{
	ns=step_rating/c*len+residue;
	nfsc=int(ns/4);
	nhs=int(floor((ns-nfsc*4)/0.5));	//rounding
	if(nhs==8)	//may result after rounding
		nhs=7;
	residue=ns-(nfsc*4+nhs*0.5);
}

void stepper::angle2steps(float angle, int& nfsc, int& nhs)//conversion
{
	float arclen=(pi*w)/360.0*angle;
	length2steps(arclen, nfsc, nhs);
}

void stepper::move(int nfsc, int nhs, int leftw, int rightw) //move	
{
   int i;
   int cnt;
   outb(0x00, BASEPORT);
   if(leftw==1 && rightw==1)
   {	
	for(i=0; i<nfsc; i++)
	{
		outb(0x59, BASEPORT);
		usleep(delay);
		outb(0x6A, BASEPORT);
		usleep(delay);
		outb(0xA6, BASEPORT);
		usleep(delay);
		outb(0x95, BASEPORT);
		usleep(delay);
		if(i%50==0 && i!=0)
			outb(0x81, BASEPORT);	//one half step - as a compensation
	}
	//sequence after 5 i.e. 0100 is 1 for half step
	//sequence after 9 i.e. 1001 is 8 for half step
       for(i=0; i<1; i++)	//dummy loop to use break;
       {
	cnt=0;
	if(nhs==0)
		break;	
	outb(0x81, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0xA9, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x28, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x6A, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x42, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x56, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x14, BASEPORT);
	if(++cnt==nhs)
		break;	
	//max of 7 half steps only possible
       }
   }
   else if(leftw==-1 && rightw==-1)
   {
	for(i=0; i<nfsc; i++)
	{
		outb(0x95, BASEPORT);
		usleep(delay);
		outb(0xA6, BASEPORT);
		usleep(delay);
		outb(0x6A, BASEPORT);
		usleep(delay);
		outb(0x59, BASEPORT);
		usleep(delay);
		if(i%50==0 && i!=0)
			outb(0x81, BASEPORT);	//one half step - as a compensation
	}
	//sequence after 5 i.e. 0100 is 1 for half step
	//sequence after 9 i.e. 1001 is 8 for half step
       for(i=0; i<1; i++)	//dummy loop
       {
	cnt=0;
	if(nhs==0)
		break;	
	outb(0x81, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0xA9, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x28, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x6A, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x42, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x56, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x14, BASEPORT);
	if(++cnt==nhs)
		break;	
       }
   }   
   else if(leftw==-1 && rightw==1)	//left turn 2 wheels
   {
	
	for(i=0;i<nfsc;i++)
	{
		outb(0x99, BASEPORT);
		usleep(delay);
		outb(0xAA, BASEPORT);
		usleep(delay);
		outb(0x66, BASEPORT);
		usleep(delay);
		outb(0x55, BASEPORT);
		usleep(delay);
	}
	//sequence after 5 i.e. 0100 is 1 for half step
	cnt=0;
      for(i=0; i<1; i++)
      {
	if(nhs==0)
		break;	
	outb(0x11, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x99, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x88, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0xAA, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x22, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x66, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x44, BASEPORT);
	if(++cnt==nhs)
		break;	
	//max of 7 half steps only possible
      }
   }
   else if(leftw==1 && rightw==-1)	//right turn with 2 wheels
   {
	for(i=0;i<nfsc;i++)
	{
		outb(0x55, BASEPORT);
		usleep(delay);
		outb(0x66, BASEPORT);
		usleep(delay);
		outb(0xAA, BASEPORT);
		usleep(delay);
		outb(0x99, BASEPORT);
		usleep(delay);
	}
	//sequence after 5 i.e. 0100 is 1 for half step
	cnt=0;
      for(i=0; i<1; i++)
      {
	if(nhs==0)
		break;	
	outb(0x44, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x66, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x22, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0xAA, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x88, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x99, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x11, BASEPORT);
	if(++cnt==nhs)
		break;	
	//max of 7 half steps only possible
      }
   }
   else if(leftw==0 && rightw==1) //left turn with one wheel
   {
	
	for(i=0;i<nfsc;i++)
	{
		outb(0x09, BASEPORT);
		usleep(delay);
		outb(0x0A, BASEPORT);
		usleep(delay);
		outb(0x06, BASEPORT);
		usleep(delay);
		outb(0x05, BASEPORT);
		usleep(delay);
	}
	//sequence after 5 i.e. 0100 is 1 for half step
	cnt=0;
      for(i=0; i<1; i++)
      {
	if(nhs==0)
		break;	
	outb(0x01, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x09, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x08, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x0A, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x02, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x06, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x04, BASEPORT);
	if(++cnt==nhs)
		break;	
	//max of 7 half steps only possible
      }
   }
   else if(leftw==1 && rightw==0) //right turn with one wheel
   {
	for(i=0;i<nfsc;i++)
	{
		outb(0x50, BASEPORT);
		usleep(delay);
		outb(0x60, BASEPORT);
		usleep(delay);
		outb(0xA0, BASEPORT);
		usleep(delay);
		outb(0x90, BASEPORT);
		usleep(delay);
	}
	//sequence after 5 i.e. 0100 is 1 for half step
	cnt=0;
      for(i=0; i<1; i++)
      {
	if(nhs==0)
		break;	
	outb(0x40, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x60, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x20, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0xA0, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x80, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x90, BASEPORT);
	if(++cnt==nhs)
		break;
	outb(0x10, BASEPORT);
	if(++cnt==nhs)
		break;	
	//max of 7 half steps only possible
      }
   }
   outb(0x00, BASEPORT);
}		

void stepper::fwd(float len=0)
{
	float tlen=len;
	if(len==0)
		return;
	tlen=tlen+tlen*lcf/100;
	length2steps(tlen, nfsc, nhs);
	cout<<"\nMoving forward by "<<len<<"cms... \t[\t"<<nfsc<<"  "<<nhs<<"  ]"<<endl;
	move(nfsc, nhs, 1, 1);//leftw=1 & rightw=1
}

void stepper::bkwd(float len=0)
{
	float tlen=len;
	if(len==0)
		return;
	tlen=tlen+tlen*lcf/100;
	length2steps(tlen, nfsc, nhs);
	cout<<"\nMoving backward by "<<len<<"cms... \t[\t"<<nfsc<<"  "<<nhs<<"  ]"<<endl;
	move(nfsc, nhs, -1, -1);//leftw=-1 & rightw=-1
}

void stepper::lefturn(float angle, int dof=2)	//degree of freedom
{
	float tangle=angle;
	tangle=tangle*2/dof;
	tangle=tangle+tangle*acf/100;
	angle2steps(tangle, nfsc, nhs);
	cout<<"\nTaking left turn by "<<angle<<"degrees... [\t"<<nfsc<<"  "<<nhs<<"  ]"<<endl;
	if(dof==1)
		move(nfsc, nhs, 0, 1);	//leftwheel=off, rightwheel=on
	else
		move(nfsc, nhs, -1, 1);
}

void stepper::righturn(float angle, int dof=2)
{
	float tangle=angle;
	tangle=tangle*2/dof;
	tangle=tangle+tangle*acf/100;
	angle2steps(tangle, nfsc, nhs);
	cout<<"\nTaking right turn by "<<angle<<"degrees... [\t"<<nfsc<<"  "<<nhs<<"  ]"<<endl;
	if(dof==1)
		move(nfsc, nhs, 1, 0); //leftwheel=on, rightwheel=off
	else
		move(nfsc, nhs, 1, -1);
}

main()
{
	system("clear");
	if(ioperm(BASEPORT,3,1))
	{
		cout<<"\nThe parallel port accessing error!";
		exit(1);
	}
	float speed; 		//in cm/s
	float len, la, ra;	//in cm
	float angle;
	long wait=10000;
	
	//cout<<"\nEnter speed in cm/s (eg. 10cm/s) : ";
	//cin>>speed;	

	speed=10;
	stepper sm(speed);	 

	sm.specification();
	cout<<"\nScanning the problem...";usleep(wait);
	cout<<"...";usleep(wait);cout<<"...";usleep(wait);cout<<"...";cout<<"Done!";
	cout<<"\n\n\nStarting the voyage...\n\n\n";
	
	float l1=20, l2=28.284;
	float a1=45, a2=90, a3=135;

	int i;
	
	for(i=0; i<3; i++)
	{
		sm.fwd(l1);
		usleep(wait);
		sm.lefturn(a3);
		usleep(wait);
		sm.fwd(l2);
		usleep(wait);
		sm.righturn(a3);
	}
}

base64 Encoding

March 1, 20132 comments Coded in C
#include <string.h>
#include <stdint.h>

//This is a helper function to convert a six-bit value to base64
char base64_encode_six(uint8_t six_bit_value){
	uint8_t x;
	char c;
	x = six_bit_value & ~0xC0; //remove top two bits (should be zero anyway)
	if( x < 26 ){
		c = 'A' + x;
	} else if ( x < 52 ){
		c = 'a' + (x - 26);
	} else if( x < 62 ){
		c = '0' + (x - 52);
	} else if( x == 62 ){
		c = '+';
	} else if (x == 63 ){
		c = '/';
	} else {
		printf("ERROR IN BASE 64\n");
		c = 'A';
	}
	return c;
}

//This is the function for encoding in base64
void base64_encode(char * dest, const char * src){
	int bits;
	int i;
	int j;
	int k;
	int len;
	uint8_t six_bits[4];
	len = strlen(src);

	k = 0;
	//We need to encode three bytes at a time in to four encoded bytes
	for(i=0; i < len; i+=3){
		//First the thress bytes are broken down into six-bit sections
		six_bits[0] = (src[i] >> 2) & 0x3F; 
		six_bits[1] = ((src[i] << 4) & 0x30) + ((src[i+1]>>4) & 0x0F);
		six_bits[2] = ((src[i+1] << 2) & 0x3C) + ((src[i+2]>>6) & 0x03);
		six_bits[3] = src[i+2] & 0x3F;
		//now we use the helper function to convert from six-bits to base64
		for(j=0; j < 4; j++){
			dest[k+j] = base64_encode_six(six_bits[j]);
		}
		k+=4;
	}

	//at the end, we add = if the input is not divisible by 3
	if( (len % 3) == 1 ){
		//two equals at end
		dest[k-2] = '=';
		dest[k-1] = '=';
	} else if ( (len %3 ) == 2 ){
		dest[k-1] = '=';
	}

	//finally, zero terminate the output string
	dest[k] = 0;
}

Graphics in source code

Ricky Bennett February 28, 20132 comments Coded in C
// This enum defines the value of each of the 256 possible combinations of
// underlines and Os in 8 bits.
enum
{
   ________,_______O,______O_,______OO,_____O__,_____O_O,_____OO_,_____OOO,
   ____O___,____O__O,____O_O_,____O_OO,____OO__,____OO_O,____OOO_,____OOOO,
   ___O____,___O___O,___O__O_,___O__OO,___O_O__,___O_O_O,___O_OO_,___O_OOO,
   ___OO___,___OO__O,___OO_O_,___OO_OO,___OOO__,___OOO_O,___OOOO_,___OOOOO,
   __O_____,__O____O,__O___O_,__O___OO,__O__O__,__O__O_O,__O__OO_,__O__OOO,
   __O_O___,__O_O__O,__O_O_O_,__O_O_OO,__O_OO__,__O_OO_O,__O_OOO_,__O_OOOO,
   __OO____,__OO___O,__OO__O_,__OO__OO,__OO_O__,__OO_O_O,__OO_OO_,__OO_OOO,
   __OOO___,__OOO__O,__OOO_O_,__OOO_OO,__OOOO__,__OOOO_O,__OOOOO_,__OOOOOO,
   _O______,_O_____O,_O____O_,_O____OO,_O___O__,_O___O_O,_O___OO_,_O___OOO,
   _O__O___,_O__O__O,_O__O_O_,_O__O_OO,_O__OO__,_O__OO_O,_O__OOO_,_O__OOOO,
   _O_O____,_O_O___O,_O_O__O_,_O_O__OO,_O_O_O__,_O_O_O_O,_O_O_OO_,_O_O_OOO,
   _O_OO___,_O_OO__O,_O_OO_O_,_O_OO_OO,_O_OOO__,_O_OOO_O,_O_OOOO_,_O_OOOOO,
   _OO_____,_OO____O,_OO___O_,_OO___OO,_OO__O__,_OO__O_O,_OO__OO_,_OO__OOO,
   _OO_O___,_OO_O__O,_OO_O_O_,_OO_O_OO,_OO_OO__,_OO_OO_O,_OO_OOO_,_OO_OOOO,
   _OOO____,_OOO___O,_OOO__O_,_OOO__OO,_OOO_O__,_OOO_O_O,_OOO_OO_,_OOO_OOO,
   _OOOO___,_OOOO__O,_OOOO_O_,_OOOO_OO,_OOOOO__,_OOOOO_O,_OOOOOO_,_OOOOOOO,
   O_______,O______O,O_____O_,O_____OO,O____O__,O____O_O,O____OO_,O____OOO,
   O___O___,O___O__O,O___O_O_,O___O_OO,O___OO__,O___OO_O,O___OOO_,O___OOOO,
   O__O____,O__O___O,O__O__O_,O__O__OO,O__O_O__,O__O_O_O,O__O_OO_,O__O_OOO,
   O__OO___,O__OO__O,O__OO_O_,O__OO_OO,O__OOO__,O__OOO_O,O__OOOO_,O__OOOOO,
   O_O_____,O_O____O,O_O___O_,O_O___OO,O_O__O__,O_O__O_O,O_O__OO_,O_O__OOO,
   O_O_O___,O_O_O__O,O_O_O_O_,O_O_O_OO,O_O_OO__,O_O_OO_O,O_O_OOO_,O_O_OOOO,
   O_OO____,O_OO___O,O_OO__O_,O_OO__OO,O_OO_O__,O_OO_O_O,O_OO_OO_,O_OO_OOO,
   O_OOO___,O_OOO__O,O_OOO_O_,O_OOO_OO,O_OOOO__,O_OOOO_O,O_OOOOO_,O_OOOOOO,
   OO______,OO_____O,OO____O_,OO____OO,OO___O__,OO___O_O,OO___OO_,OO___OOO,
   OO__O___,OO__O__O,OO__O_O_,OO__O_OO,OO__OO__,OO__OO_O,OO__OOO_,OO__OOOO,
   OO_O____,OO_O___O,OO_O__O_,OO_O__OO,OO_O_O__,OO_O_O_O,OO_O_OO_,OO_O_OOO,
   OO_OO___,OO_OO__O,OO_OO_O_,OO_OO_OO,OO_OOO__,OO_OOO_O,OO_OOOO_,OO_OOOOO,
   OOO_____,OOO____O,OOO___O_,OOO___OO,OOO__O__,OOO__O_O,OOO__OO_,OOO__OOO,
   OOO_O___,OOO_O__O,OOO_O_O_,OOO_O_OO,OOO_OO__,OOO_OO_O,OOO_OOO_,OOO_OOOO,
   OOOO____,OOOO___O,OOOO__O_,OOOO__OO,OOOO_O__,OOOO_O_O,OOOO_OO_,OOOO_OOO,
   OOOOO___,OOOOO__O,OOOOO_O_,OOOOO_OO,OOOOOO__,OOOOOO_O,OOOOOOO_,OOOOOOOO,
};

// These macros use the above enum to build the image in a source file.

#define G8(n0)                (n0)     //!< Build a byte image line

#define G16(n1, n0)           (((n1) << 8) | (n0))
                                       //!< Build a halfword image line

#define G32(n3, n2, n1, n0)                                                   \
      ((G16 ((n3), (n2)) << 16) | G16 ((n1), (n0)))
                                       //!< Build a word image line

#define G64(n7, n6, n5, n4, n3, n2, n1, n0)                                   \
      ((G32 ((n7), (n6), (n5), (n4)) << 32) | G32 ((n3), (n2), (n1), (n0)))
                                       //!< Build a long image line

=====

Example using the letter A in Arial Black 21 font:

Old code:

{
      19,                              // A
      0x00040000, 0x00078000, 0x0007F000, 0x0007FC00,
      0x0007FF80, 0x0003FFF0, 0x0000FFFC, 0x0000FFFE,
      0x0000F1FE, 0x0000F03E, 0x0000F1FE, 0x0000FFFE,
      0x0000FFFC, 0x0003FFF0, 0x0007FF80, 0x0007FC00,
      0x0007F000, 0x00078000, 0x00040000
};

New code:

{
      19,                              // A
      G32 (________,_____O__,________,________),
      G32 (________,_____OOO,O_______,________),
      G32 (________,_____OOO,OOOO____,________),
      G32 (________,_____OOO,OOOOOO__,________),
      G32 (________,_____OOO,OOOOOOOO,O_______),
      G32 (________,______OO,OOOOOOOO,OOOO____),
      G32 (________,________,OOOOOOOO,OOOOOO__),
      G32 (________,________,OOOOOOOO,OOOOOOO_),
      G32 (________,________,OOOO___O,OOOOOOO_),
      G32 (________,________,OOOO____,__OOOOO_),
      G32 (________,________,OOOO___O,OOOOOOO_),
      G32 (________,________,OOOOOOOO,OOOOOOO_),
      G32 (________,________,OOOOOOOO,OOOOOO__),
      G32 (________,______OO,OOOOOOOO,OOOO____),
      G32 (________,_____OOO,OOOOOOOO,O_______),
      G32 (________,_____OOO,OOOOOO__,________),
      G32 (________,_____OOO,OOOO____,________),
      G32 (________,_____OOO,O_______,________),
      G32 (________,_____O__,________,________),
};

Binary numbers

Ricky Bennett February 28, 2013 Coded in C
// The following macros build values in binary.  Nybbles are separated by
// commas for readability.  If a non-binary digit is used, a compiler error
// will result.  Here are some examples of the usage of the binary macros:
//
//    B4 (0110) = 0x06
//    B8 (0101,0101) = 0x55
//    B16 (1010,1010, 0101,0101) = 0xAA55
//    B32 (1000,0000, 1111,1111, 1010,1010, 0101,0101) = 0x80FFAA55
//
// For maximum readability, the bytes should be separated by spaces and there
// should be no spaces between nybbles, as shown above.  Note that an enum
// isn't used because MISRA-C generates errors otherwise.

#define b0000   0u
#define b0001   1u
#define b0010   2u
#define b0011   3u
#define b0100   4u
#define b0101   5u
#define b0110   6u
#define b0111   7u
#define b1000   8u
#define b1001   9u
#define b1010  10u
#define b1011  11u
#define b1100  12u
#define b1101  13u
#define b1110  14u
#define b1111  15u

#pragma diag_suppress = Pm120
#define B4(n0)                (b##n0)  //!< Build a nybble in binary
#pragma diag_default = Pm120

#define B8(n1, n0)            ((B4 (n1) << 4u) | B4 (n0))
                                       //!< Build a byte in binary

#define B16(n3, n2, n1, n0)                                                   \
      ((B4 (n3) << 12) | (B4 (n2) << 8) | (B4 (n1) << 4) | B4 (n0))
                                       //!< Build a halfword in binary

#define B32(n7, n6, n5, n4, n3, n2, n1, n0)                                   \
       ((B4 (n7) << 28) | (B4 (n6) << 24) | (B4 (n5) << 20) | (B4 (n5) << 16) \
      | (B4 (n3) << 12) | (B4 (n2) <<  8) | (B4 (n1) <<  4) | B4 (n0))
                                       //!< Build a word in binary

#define B64(nF, nE, nD, nC, nB, nA, n9, n8, n7, n6, n5, n4, n3, n2, n1, n0)   \
       ((B4 (nF) << 60) | (B4 (nE) << 56) | (B4 (nD) << 52) | (B4 (nC) << 48) \
      | (B4 (nB) << 44) | (B4 (nA) << 40) | (B4 (n9) << 36) | (B4 (n8) << 32) \
      | (B4 (n7) << 28) | (B4 (n6) << 24) | (B4 (n5) << 20) | (B4 (n5) << 16) \
      | (B4 (n3) << 12) | (B4 (n2) <<  8) | (B4 (n1) <<  4) |  B4 (n0))
                                       //!< Build a long in binary

Little Endian Converter Functions

Dr Cagri Tanriover February 18, 20131 comment Coded in C
unsigned short u16ToLittleEndian( unsigned short u16input )
{/* Use this function to convert a 16-bit number into little endian. */

  return( (u16input >> 8) ^ (u16input << 8) );

}// end u16ToLittleEndian()

unsigned long u32ToLittleEndian( unsigned long u32input )
{/* Use this function to convert a 32-bit number into little endian. */

  return( (u32input >> 24)
           ^ ( (u32input >> 8) & 0x000FF00 )
           ^ ( (u32input << 8) & 0x00FF0000 )
           ^ ( (u32input << 24) & 0xFF000000 )
         );

}// end u32ToLittleEndian()

Exponential Moving Average

February 13, 20133 comments Coded in C
//This macros defines an alpha value between 0 and 1
#define DSP_EMA_I32_ALPHA(x) ( (uint16_t)(x * 65535) )
 
int32_t dsp_ema_i32(int32_t in, int32_t average, uint16_t alpha){
  int64_t tmp0; //calcs must be done in 64-bit math to avoid overflow
  tmp0 = (int64_t)in * (alpha) + (int64_t)average * (65536 - alpha);
  return (int32_t)((tmp0 + 32768) / 65536); //scale back to 32-bit (with rounding)
}

//here is a function that uses the averaging code
int32_t my_avg_func(void){
     static int32_t average = 0;
     int32_t adc_value;    
     adc_value = read_the_adc_value();
     average = dsp_ema_i32(adc_value, average, DSP_EMA_I32_ALPHA(0.1));
     return average;
}

Binary Coded Decimal (BCD) - ASCII Converter

Dr Cagri Tanriover February 12, 2013 Coded in C
char bcdToAscii( unsigned char bcdNibble )
{
  char result;
	
  if( bcdNibble < 10 )
  {// valid BCD input. ( [0,9] is the valid range for BCD input. )
    result = (char)( bcdNibble + 48 );	// +48 is applicable to [0,9] input range.
  }// end if
  else
  {// invalid input
    result = '0';
  }// end else

  return( result );
	
}// end bcdToAscii()

unsigned char asciiToBcd( char asciiByte )
{/* Converts an input ASCII character (expected within the [ '0' - '9' ] range) into its BCD counterpart. */
	
  unsigned char result;

  if( 
      asciiByte >= '0'
      && asciiByte <= '9'
  )
  {// range check passed.
    result = (unsigned char)(asciiByte - 48);	// -48 offset gives the decimal value of the ASCII character.
  }
  else
  {// range check failed.
    result = 0;
  }// end else

  return( result );
	
}// end asciiToBcd()

Embedded Linux Frequency Meter

Fabiano Ferronato February 5, 2013 Coded in C for the TI OMAP 5912
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/arch/gpio.h>
#include <asm/arch/dmtimer.h>

/*
The prescaler is enabled when TCLR bit 5 is set (PRE). The 2n division ratio value
(PTV) can be configured in the TCLR register.

Each internal interrupt source can be independently enabled/disabled in the interrupt
enable register TIER.

When the interrupt event has been issued, the associated interrupt status bit is set
in the timer status register (TISR). The pending interrupt event is reset when the 
set status bit is overwritten by a 1.

The timer rate is defined by:
-Value of the prescaler fields (PRE and PTV of TCLR register)
-Value loaded into the timer load register (TLDR)

timer rate = (0xFFFF FFFF – TLDR + 1) x timer clock period x clock divider (PS)

PTV + 1)
PS = 2
*/

static unsigned long freq , ct, round;

extern struct omap_dm_timer * frequencimeter; // timer reserved to measure frequency

static irqreturn_t gpio4_freqmeter_irq_handler(int irq, void *arg);

static int __init freqmeter_init(void)
{
	int r;
	round = 0; freq = 0 ; ct = 0;
	printk(KERN_DEBUG "Init driver Freqmeter.\n");

	/* request gpios*/
	/* GPIO - P20_1610_GPIO4 */
	if ( omap_request_gpio(4) < 0 ) printk(KERN_ERR "Error init GPIO4 (freqmeter).\n");
	
	/* entrada */
	omap_set_gpio_direction(4,1); /* in */

	r = request_irq(OMAP_GPIO_IRQ(4), gpio4_freqmeter_irq_handler, IRQF_TRIGGER_RISING, "freqmeter", gpio4_freqmeter_irq_handler);
	if ( r < 0 ) {
		printk(KERN_ERR "freqmeter: request_irq() failed.\n");
		return r;
	}
	
	printk(KERN_DEBUG "freqmeter initialized.\n");
	return 0;
}

static irqreturn_t gpio4_freqmeter_irq_handler(int irq, void *arg)
{
	// dummy: 	no interrupt? freq = 0Hz
	//		only one int? freq = 0Hz  
	
	/**	there is interference?: lread INT again
		should be in same logic level */
	if ( omap_get_gpio_datain(4) )
	{
		if(round > 0)
		{
			if(round == 50)
			{
				
				ct = omap_dm_timer_read_counter(frequencimeter);
				omap_dm_timer_stop(frequencimeter);
				ct /= 50;
				freq = 1200000000/(ct +1);
				
				printk("freq = %d\n",(freq/*-8*/));
				round = 0xFFFFFFFF;
				ct = 0;
				freq = 0;
			}
		}
		else			// first read
		{
			freq = 0;
			
			printk(KERN_DEBUG "Iniciou o freqmeter");
			omap_dm_timer_write_counter(frequencimeter,0x0);
			omap_dm_timer_start(frequencimeter);
		}
		round++;
	}
		
	return IRQ_HANDLED;
}

asmlinkage long sys_freq_read(void)
{
	
	return freq;
}

static void __exit freqmeter_cleanup(void)
{
	free_irq(OMAP_GPIO_IRQ(4), NULL);
	omap_free_gpio(4);
}

module_init(freqmeter_init);
module_exit(freqmeter_cleanup);

MODULE_LICENSE("GPL");

Integer to ASCII

Dr. Maykel Alonso January 18, 20132 comments Coded in C
/***** integerToAscii.h *****/

#define BASE_OCTAL			8
#define BASE_DECIMAL			10
#define BASE_HEXADECIMAL		16

#define BUFFER_SIZE			32

char* integerToASCII(long int value, int base);

/***** integerToAscii.c *****/

char* integerToASCII(long int value, int base){
	
	int aux;
	static char buf[BUFFER_SIZE] = {0};

        int isNeg=0;
        if (value == 0) {
                buf[0]='0';
                return &buf[0];
        }
        if (value<0) {
                isNeg = 1;
                value *= -1;
        }	

	for(aux=BUFFER_SIZE; value && aux ; --aux, value /= base){	
		buf[aux] = "0123456789abcdef"[value % base];
	}

	if (isNeg)  {
		buf[aux] = '-';
		return &buf[aux];
	}

	return &buf[aux+1];
}