pwm code and explain about this , how we can run on mini 2440

vineet kumar tiwari
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>

#define PWM_IOCTL_SET_FREQ    1
#define PWM_IOCTL_STOP      0

#define  ESC_KEY    0x1b

static int getch(void)
{
  struct termios oldt,newt;
  int ch;

  if (!isatty(STDIN_FILENO)) {
    fprintf(stderr, "this problem should be run at a terminal\n");
    exit(1);
  }
  // save terminal setting
  if(tcgetattr(STDIN_FILENO, &oldt) < 0) {
    perror("save the terminal setting");
    exit(1);
  }

  // set terminal as need
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  if(tcsetattr(STDIN_FILENO,TCSANOW, &newt) < 0) {
    perror("set terminal");
    exit(1);
  }

  ch = getchar();

  // restore termial setting
  if(tcsetattr(STDIN_FILENO,TCSANOW,&oldt) < 0) {
    perror("restore the termial setting");
    exit(1);
  }
  return ch;
}

static int fd = -1;
static void close_buzzer(void);
static void open_buzzer(void)
{
  fd = open("/dev/pwm", 0);
  if (fd < 0) {
    perror("open pwm_buzzer device");
    exit(1);
  }

  // any function exit call will stop the buzzer
  atexit(close_buzzer);
}

static void close_buzzer(void)
{
  if (fd >= 0) {
    ioctl(fd, PWM_IOCTL_STOP);
    close(fd);
    fd = -1;
  }
}

static void set_buzzer_freq(int freq)
{
  // this IOCTL command is the key to set frequency
  int ret = ioctl(fd, PWM_IOCTL_SET_FREQ, freq);
  if(ret < 0) {
    perror("set the frequency of the buzzer");
    exit(1);
  }
}
static void stop_buzzer(void)
{
  int ret = ioctl(fd, PWM_IOCTL_STOP);
  if(ret < 0) {
    perror("stop the buzzer");
    exit(1);
  }
}

int main(int argc, char **argv)
{
  int freq = 1000 ;
  
  open_buzzer();

  printf( "\nBUZZER TEST ( PWM Control )\n" );
  printf( "Press +/- to increase/reduce the frequency of the BUZZER\n" ) ;
  printf( "Press 'ESC' key to Exit this program\n\n" );
  
  
  while( 1 )
  {
    int key;

    set_buzzer_freq(freq);
    printf( "\tFreq = %d\n", freq );

    key = getch();

    switch(key) {
    case '+':
      if( freq < 20000 )
        freq += 10;
      break;

    case '-':
      if( freq > 11 )
        freq -= 10 ;
      break;

    case ESC_KEY:
    case EOF:
      stop_buzzer();
      exit(0);

    default:
      break;
    }
  }
}

gothicbeast
As you must already be aware this code gives you a terminal interface
(visible on the telnet/minicom session for your board) to control the
buzzer frequency.

The code:

This is user space program which in turn makes use of a device driver (pre
compiled and supplied in the linux image that you have used to bring up /
program the board)

You can see the device driver code at drivers/char/mini6410_pwm.c under
your linux source code directory

This device driver is designed so that it creates a node (entry) at
/dev/pwm

func: getch(void) :
The user space program (the code you have posted) simply sets up the
terminal to derive command line arguments at run time. These arguments are 
chars used to determine if the buzzer frequency is to be increased or
decreased (chars used here are '+' for increase, '-' for decrease and 'ESC'
for stopping)

func: open_buzzer(void) :
This just opens the file /dev/pwm/ for further use and returns error if
resource is busy or inaccessible.

func: close_buzzer(void) :
closes the same file after use is over 

func: set_buzzer_freq(int freq) :
This functions takes the frequency at which the buzzer is to be rung, as an
argument and informs the device driver, the same, using the ioctl call. fd
is the file descriptor for /dev/pwm, the macro is a predefined enumeration,
the device driver recognizes for driving the concerned out pin at set pwm
(frequency) and freq is the frequency to be set.

func: stop_buzzer(void) :
stops the buzzer

main function drives the super-loop using switch case, including i/o from
terminal, ringing the buzzer, varying the frequency according to the user
input and also exiting when ESC is pressed.

Re: How to run this on mini2440
The code can be cross compiled using your cross gcc tool chain (supplied
with your arm board or else obtainable from this site:
http://www.friendlyarm.net/dl.php?file=arm-linux-gcc-4.4.3.tgz

The object file created can be ported to your board using pendrive or nfs.
This executable should run directly on the board's terminal.

r@wboom
hello there,
i searched the pwm in /dev folder but i didn,t see any pwm file in this...
as i make the gui for this it shows that fd<0....
***************************************************************
#include "hello.h"
#include <qlabel.h>
#include <qpushbutton.h>
#include <qtimer.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/fs.h>
#include <errno.h>
#include <string.h>
#include <qobject.h>
#include <fstream>
#include <linux/i2c-dev.h>
#include <string.h>            
#include <stdio.h>                        
#include <linux/fs.h>
#include <termios.h>
#include <stdint.h>
#include <getopt.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
# include <time.h>
# include <string.h>
# include <sys/time.h>
#define PWM_IOCTL_SET_FREQ      1  
#define PWM_IOCTL_STOP          0  

int freq=10;
int ret;
int fd=-1;
HelloForm::HelloForm( QWidget* parent, const char* name, WFlags fl)
          :HelloBaseForm(parent, name, fl)
    {
    connect(PushButton33,SIGNAL(clicked()),this,SLOT(start()));
    connect(PushButton30,SIGNAL(clicked()),this,SLOT(stop()));
    connect(PushButton31,SIGNAL(clicked()),this,SLOT(plus()));
    connect(PushButton32,SIGNAL(clicked()),this,SLOT(minus()));
}
HelloForm::~HelloForm()
{

}
void HelloForm::start()
{

int fd = open("/dev/pwm", 0);
  if (fd < 0) {
    status->setText("open pwm_buzzer device");
    }
else{
status->setText("start");
}
 ioctl(fd, PWM_IOCTL_SET_FREQ, freq);
pwm->setText(QString::number(freq));
//close(fd);
}

void HelloForm::stop()
{
int ret = ioctl(fd, PWM_IOCTL_STOP);
  if(ret < 0) {
    perror("stop the buzzer");
    //exit(1);
    }
    
    }


void HelloForm::plus()
{
 //int fd = open("/dev/pwm",0);
if(freq<20000)
{
freq+=10;
}
if(ret<0)
{
status->setText("set the ferq");
exit(1);
}
ioctl(fd,PWM_IOCTL_SET_FREQ,freq);
pwm->setText(QString::number(freq));
//close(fd);
}

void HelloForm::minus()
{
//int fd=open("/dev/pwm",0);
if(freq>11)
{
freq-=10;
}
int ret=ioctl(fd,PWM_IOCTL_SET_FREQ,freq);
if(ret<0)
{
status->setText("set the ferq");
//exit(1);
}
pwm->setText(QString::number(freq));
//close(fd);
}
**********************************************************