#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; } } }
pwm code and explain about this , how we can run on mini 2440
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.
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); } **********************************************************