FM 发射模块QN8027软件android 5.1实现分析

FM 发射模块QN8027软件android 5.1实现分析

一,kernel层中的驱动:(主要为厂家提供,主要配置对应的I2C口线)

由三个文件组成:

1,  Makefile   /*驱动的编译文件,让该驱动被编译到内核中去*/

2,  qn8027.c   /*驱动的源文件,厂家提供,具体实现不分析,这里主要关注如何与JAVA层的通讯*/

3,  qn8027.h  /*驱动头文件,厂家提供。定义通讯的IO*/

 

Makefile文档:

include $(srctree)/drivers/misc/mediatek/Makefile.custom

 

obj-y += qn8027.o

 

 

qn8027.c文档:

#include

#include

#include

#include

#include

#include

#include

#include

 

//#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

#include

#include

#include

#include

#include

 

#include

#include

#include

 

#include

#include"cust_gpio_usage.h"

 

#include"qn8027.h"

 

staticsize_t qn8027_iic_log_on = false;

#defineQN8027_IIC_LOG(fmt, arg...) \

        do { \

                if (qn8027_iic_log_on){printk("[qn8027]%s,#%d ", __func__, __LINE__); printk(fmt, ##arg);}\

        }while (0)

       

#defineQN8027_IIC_FUNC()       \

    do { \

        if(qn8027_iic_log_on)printk("[qn8027] %s\n", __func__); \

    }while (0)

                

/*----------------------------------------------------------------------------*/

// qn8027device information

/*----------------------------------------------------------------------------*/

#defineMAX_TRANSACTION_LENGTH 8

#defineQN8027_DEVICE_NAME           "FMtransmitter"

#defineQN8027_I2C_SLAVE_ADDR        0x58

#defineIIC_BUSNUM              2

 

#defineGPIO_EN_QN8027_PIN          (GPIO31 |0x80000000)

/*EINT_AMP Y23 */

#defineGPIO_SPEAKER_EN_PIN                         (GPIO88| 0x80000000)

 

staticbool QN8027_FLAG = FALSE;

externbool accdet_plug_state();

/*----------------------------------------------------------------------------*/

staticint qn8027_i2c_probe(struct i2c_client *client, const struct i2c_device_id*id);

staticint qn8027_i2c_remove(struct i2c_client *client);

staticstruct i2c_client *qn8027_i2c_client = NULL;

staticconst struct i2c_device_id qn8027_i2c_id[] = {{QN8027_DEVICE_NAME,0},{}};

staticstruct i2c_board_info __initdata i2c_qn8027 = {I2C_BOARD_INFO(QN8027_DEVICE_NAME, (QN8027_I2C_SLAVE_ADDR>>1))};

 

externvoid set_pwm(int vol);

/*----------------------------------------------------------------------------*/

structi2c_driver qn8027_i2c_driver = {                      

    .probe = qn8027_i2c_probe,                                   

    .remove = qn8027_i2c_remove,                                                   

    .driver = { .name = QN8027_DEVICE_NAME,},

    .id_table = qn8027_i2c_id,                                                    

};

structqn8027_i2c_data {

      struct i2c_client *client;

        uint16_t addr;

        int use_reset;  //use RESET flag

        int use_irq;            //use EINT flag

        int retry;

};

 

staticstruct qn8027_i2c_data *obj_i2c_data = NULL;

 

boolqn8027_status()

{

return QN8027_FLAG;

}

EXPORT_SYMBOL(qn8027_status);

 

/*----------------------------------------------------------------------------*/

intqn8027_i2c_read(u16 addr, u32 *data)

{

    u8 rxBuf[1] = {0};

    int ret = 0;

    struct i2c_client *client = qn8027_i2c_client;

    u8 lens;

 

    client->addr = (client->addr &I2C_MASK_FLAG);

    client->timing = 400;

    client->ext_flag = I2C_WR_FLAG;

        rxBuf[0] = addr;

        lens = 1;

       

        ret = i2c_master_send(client,&rxBuf[0], (1 << 8) | lens);

    if (ret < 0)

    {

               QN8027_IIC_LOG("qn8027_i2c_read reg[0x%X] fail, Error code [0x%X]\n", addr, ret);

        return -EFAULT;

    }

        //ret = i2c_master_recv(client,&rxBuf[0], 0x1);

       

   *data = rxBuf[0];

        QN8027_IIC_LOG("qn8027_i2c_readreg[0x%X] = 0x%X\n", addr, rxBuf[0]);

    return 0;

}

/*----------------------------------------------------------------------------*/

EXPORT_SYMBOL_GPL(qn8027_i2c_read);

/*----------------------------------------------------------------------------*/

 

intqn8027_i2c_write(u16 addr, u32 data)

{

    struct i2c_client *client =qn8027_i2c_client;

    u8 buffer[8];

        u8 write_data[2] = {0};

    int ret = 0;

       

    struct i2c_msg msg =

    {

        .addr = client->addr &I2C_MASK_FLAG,

        .flags = 0,

        .len = 2,

        .buf = write_data,

        .timing = 400,

    };

 

        write_data[0] = addr;

    write_data[1] = data;

       

        //ret = i2c_master_send(client,write_data, 0x2);

    ret = i2c_transfer(client->adapter,&msg, 1);

    if (ret < 0)

    {

               QN8027_IIC_LOG("qn8027_write reg[0x%X] fail, Error code [0x%X]\n", addr, ret);

        return -EFAULT;

    }

        QN8027_IIC_LOG("[QN8027]qn8027_i2c_write reg[0x%X] = 0x%X\n", addr, data);

    return 0;

}

 

/*----------------------------------------------------------------------------*/

EXPORT_SYMBOL_GPL(qn8027_i2c_write);

 

voidqn8027_reg_init()

{

        qn8027_i2c_write(0x00, 0x81);

        msleep(20);

        //qn8027_i2c_write(0x03, 0x50);

        qn8027_i2c_write(0x04, 0x32);

        qn8027_i2c_write(0x00, 0x41);

        qn8027_i2c_write(0x00, 0x01);

        msleep(20);

        //qn8027_i2c_write(0x18, 0xe4);

        //qn8027_i2c_write(0x1b, 0xf0);

        qn8027_i2c_write(0x01, 0x00); //sendrate 88.8M

        qn8027_i2c_write(0x02, 0xb9);

        qn8027_i2c_write(0x00, 0x21);

}

 

staticvoid start_transfer()

{

        qn8027_i2c_write(0x00, 0x81);

        msleep(20);

        qn8027_i2c_write(0x04, 0x32);

        qn8027_i2c_write(0x00, 0x41);

        qn8027_i2c_write(0x00, 0x01);

        msleep(20);

        qn8027_i2c_write(0x01, 0x00); //sendrate 88.8M

        qn8027_i2c_write(0x02, 0xb9);

        qn8027_i2c_write(0x00, 0x21);

}

 

staticvoid stop_transfer()

{

        qn8027_i2c_write(0x00, 0x81);

        msleep(20);

}

 

staticvoid set_transfer_rate(int freq)

{

        int freqH;

        int freqL;

        if(freq < 760 || freq > 1080)

        {

                printk("fmtrans: the freqis not right\n");

        }

        else

        {

                freq = (freq - 760)*10 / 5;

                if(freq > 0xff)

                {

                        freqH = 0x20 |(freq>>8 & 0x3);

                        freqL = freq&0xff;

                        printk("set thefreqL 0x%x\n", freqL);

                        qn8027_i2c_write(0x01,freqL);

                        printk("set thefreqH 0x%x\n", freqH);

                        qn8027_i2c_write(0x00,freqH);

                }

                else

                {

                        qn8027_i2c_write(0x01,freq);

                        qn8027_i2c_write(0x00,0x20);

                }

        }

}

 

staticint qn8027_open(struct inode *inode, struct file *file)

{

        file->private_data =qn8027_i2c_client;

        return nonseekable_open(inode, file);

}

 

staticint qn8027_release(struct inode *inode, struct file *file)

{

        file->private_data = NULL;

        return 0;

}

 

staticlong qn8027_ioctl(struct file *file, unsigned int cmd, unsigned long arg)/*IOCTL        接口,用于接受和处理上层发送过来的IO命令。注意具体命令格式和参数要对应。*/

{

        struct i2c_client *client = (structi2c_client*)file->private_data;

        void __user *data;

        int freq = 0;

        printk("jimmy: qn8027_ioctl cmd =%d\n", cmd);

        switch(cmd)

        {

                caseFMTRANS_IOCTL_START:/*开启FM发送模块的命令*/

                                                //mt_set_gpio_mode(GPIO_SPEAKER_EN_PIN,GPIO_MODE_00);

                                                //mt_set_gpio_dir(GPIO_SPEAKER_EN_PIN,GPIO_DIR_OUT);

                                                //mt_set_gpio_out(GPIO_SPEAKER_EN_PIN,GPIO_OUT_ZERO);

                                                QN8027_FLAG= TRUE;

                                                set_pwm(0);/*本地声音静音处理*/

                                                msleep(200);

                                                /*下面是控制QN8027的上电*/

                                                mt_set_gpio_mode(GPIO_EN_QN8027_PIN,GPIO_MODE_00);

                                                mt_set_gpio_dir(GPIO_EN_QN8027_PIN,GPIO_DIR_OUT);

                                                mt_set_gpio_out(GPIO_EN_QN8027_PIN,GPIO_OUT_ONE);

                                                msleep(200);                                       

                        start_transfer();/*I2C写入对应寄存器,让QN8027工作起来,具体寄存器不讨论,可以看datasheet,或者直接找FAE就好了*/

                                                 printk("FMTRANS_IOCTL_START:QN8027_FLAG =%d\n", QN8027_FLAG);

                        break;

                case FMTRANS_IOCTL_STOP:                                                

                        stop_transfer();

                                                msleep(200);

                                               QN8027_FLAG= FALSE;

                                                mt_set_gpio_mode(GPIO_EN_QN8027_PIN,GPIO_MODE_00);

                                                mt_set_gpio_dir(GPIO_EN_QN8027_PIN,GPIO_DIR_OUT);

                                                mt_set_gpio_out(GPIO_EN_QN8027_PIN,GPIO_OUT_ZERO);

                                                msleep(200);

                                                //if(!accdet_plug_state())

                                                {

                                                         //mt_set_gpio_mode(GPIO_SPEAKER_EN_PIN,GPIO_MODE_00);

                                               //mt_set_gpio_dir(GPIO_SPEAKER_EN_PIN,GPIO_DIR_OUT);

                                               //mt_set_gpio_out(GPIO_SPEAKER_EN_PIN,GPIO_OUT_ONE);

                                               set_pwm(100);

                                                }

                                                printk("FMTRANS_IOCTL_STOP:QN8027_FLAG= %d\n", QN8027_FLAG);

                        break;

                case FMTRANS_IOCTL_SET_RATE:

                        /*

                        data = (void __user*)arg;

                       copy_from_user(&freq, data, sizeof(freq));

                        */

                        __get_user(freq, (int*)arg);

                        printk("get therate %d\n", freq);

                       set_transfer_rate(freq);

                        break;

                default :

                        break;

        }

        return 0;

}

 

staticstruct file_operations qn8027_fops = {

        .owner = THIS_MODULE,

        .open = qn8027_open,

        .release = qn8027_release,

        .unlocked_ioctl = qn8027_ioctl,

};

 

staticstruct miscdevice qn8027_device = {

        .minor = MISC_DYNAMIC_MINOR,

        .name = "fmtransmitter",

        .fops =&qn8027_fops,

};

 

/*----------------------------------------------------------------------------*/

// IICProbe

/*----------------------------------------------------------------------------*/

staticint qn8027_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)/*I2C设备对应的probe,设备注册成功后会调用。*/

{            

    int ret = -1;

    struct qn8027_i2c_data *obj;

   

    QN8027_IIC_FUNC();

     

    obj =kzalloc(sizeof(*obj), GFP_KERNEL);

        if (obj == NULL) {

                ret = -ENOMEM;

               QN8027_IIC_LOG(QN8027_DEVICE_NAME ": Allocate ts memoryfail\n");

                return ret;

    }

    obj_i2c_data = obj;

          client->timing = 400;

    obj->client = client;

    qn8027_i2c_client = obj->client;

    i2c_set_clientdata(client, obj);

 

        if(misc_register(&qn8027_device))/*关键的地方,注册了一个misc类型的device,注册成功后,会在 /dev目录下生产一个对应的设备文件,后面就是通过这个设备文件,用IOCTL的方式来实现kennel成的驱动与JAVA层进行通信的,中间还经过了JNI层的转换*/

        {

                ret = -ENOMEM;

               QN8027_IIC_LOG(QN8027_DEVICE_NAME ": misc_register error!\n");

                return ret;

        }

 

        //qn8027_reg_init();

 

    QN8027_IIC_LOG("MediaTek QN8027 i2cprobe success\n");

 

    return 0;

}

/*----------------------------------------------------------------------------*/

 

staticint qn8027_i2c_remove(struct i2c_client *client)

{

    QN8027_IIC_FUNC();

    qn8027_i2c_client = NULL;

    i2c_unregister_device(client);

    kfree(i2c_get_clientdata(client));

        misc_deregister(&qn8027_device);

    return 0;

}

 

intg_reg_value_qn8027=0;

staticunsigned int reg_address = 0;

staticssize_t show_qn8027_access(struct device *dev,struct device_attribute *attr,char *buf)

{

        qn8027_i2c_read(reg_address,&g_reg_value_qn8027);

        printk("[show_qn8027_access]0x%x\n", g_reg_value_qn8027);

        return sprintf(buf,"0x%x=0x%x\n", reg_address, g_reg_value_qn8027);

}

staticssize_t store_qn8027_access(struct device *dev,struct device_attribute *attr,const char *buf, size_t size)

{

        int ret=0;

        char *pvalue = NULL;

        unsigned int reg_value = 0;

 

        printk("[store_qn8027_access]\n");

 

        if(buf != NULL && size != 0)

        {

                printk("[store_qn8027_access] buf is %sand size is %d \n",buf,size);

                reg_address =simple_strtoul(buf,&pvalue,16);

 

                if(size > 5)

                {

                        reg_value =simple_strtoul((pvalue+1),NULL,16);

                       printk("[store_qn8027_access] write qn8027 reg 0x%x with value 0x%x!\n",reg_address,reg_value);

                       qn8027_i2c_write(reg_address, reg_value);

                }

        }

        return size;

}

 

staticstruct kobj_attribute reg_attribute = {

        .attr = {.name ="qn8027_reg", .mode = 0666},

        .show = show_qn8027_access,

        .store = store_qn8027_access,

};

 

/*----------------------------------------------------------------------------*/

staticint __init qn8027_init(void)/*驱动模块的入口*/

{

    QN8027_IIC_FUNC();

   

    i2c_register_board_info(IIC_BUSNUM,&i2c_qn8027, 1);/*设置I2C的口线*/

    if(i2c_add_driver(&qn8027_i2c_driver)) /*如名字,把qn8027_i2c_driver加入到i2c的驱动中去*/

    {

        QN8027_IIC_LOG("unable to addqn8027 i2c driver.\n");

        return -1;

    }

        sysfs_create_file(kernel_kobj,®_attribute.attr);

/*增加一个node节点,主要是方便用adb命令对寄存器进行调试*/

    return 0;

}

/*----------------------------------------------------------------------------*/

staticvoid __exit qn8027_exit(void)

{

    i2c_del_driver(&qn8027_i2c_driver);

}

/*----------------------------------------------------------------------------*/

 

 

module_init(qn8027_init);

module_exit(qn8027_exit);

 

qn8027.h文档:/*定义IO口命令,FMTRANS这个定义为0x58,不知道为什么。好像是定义的这个器件的地址。估计只是为了区分开别的设备,定义一个值而已吧*/

#include

 

#defineFMTRANS                                        0x58

#defineFMTRANS_IOCTL_START                    _IO(FMTRANS, 0x01)     

#defineFMTRANS_IOCTL_STOP                     _IO(FMTRANS, 0x02)     

#define FMTRANS_IOCTL_SET_RATE          _IOW(FMTRANS,0x03, int)

 

二,JNI层的实现:

Android.mk   /*编译文件,主要生产一个的libfm_qn8027_jni.so库,让JAVA层调用*/

fm_qn8027.cpp    /*JNI具体的转换文件*/

fm_qn8027.h    /*头文件,与kernel层的想对应*/

 

Android.mk文档:

LOCAL_PATH:=$(call my-dir)

include$(CLEAR_VARS)

 

LOCAL_MODULE_TAGS:= optional

LOCAL_CERTIFICATE:= platform

 

LOCAL_SRC_FILES:=\

         fm_qn8027.cpp

 

LOCAL_SHARED_LIBRARIES:= \

    libandroid_runtime \

    libnativehelper \

    libcutils \

    libutils \

    liblog \

    libhardware      

        

LOCAL_C_INCLUDES+= \

    $(JNI_H_INCLUDE) \

    libcore/include \

 

        

LOCAL_MODULE:=libfm_qn8027_jni

ALL_DEFAULT_INSTALLED_MODULES+= $(LOCAL_MODULE)

 

include $(BUILD_SHARED_LIBRARY)

 

fm_qn8027.cpp文档:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

#include"fm_qn8027.h"

 

#ifdefLOG_TAG

#undefLOG_TAG

#endif

#defineLOG_TAG "QN8027_control"

 

usingnamespace android;

 

//#defineFMTRANS_IOCTL_START         0x5801

//#defineFMTRANS_IOCTL_STOP          0x5802

//#defineFMTRANS_IOCTL_SET_RATE      0x40045803

 

staticint fm_fd;

staticint jni_pid;

staticint fm_status;

//MutexmLock;

 

// mustbe kept in sync with the values in WindowManager

enumFmControlType {

         FM_START = 0,

         FM_STOP = 1,

         FM_SET_RATE = 2

};

enumFmControlStatus {

         UNKNOW = 0,

         FM_S_START = 1,

         FM_s_STOP = 2

        

};

staticjint qn8027_init(JNIEnv *env, jobject thiz)

{

         ALOGD("qn8027_init --->");

         return 0;

}

 

staticjint qn8027_finish(JNIEnv *env, jobject thiz)

{

         ALOGD("qn8027_finish--->");

         return 0;

}

staticjint qn8027_open(JNIEnv *env, jobject thiz)

{

         fm_fd = open(DEVICE_NAME,O_RDWR);        //打开设备

         if(fm_fd < 0)

         {

                   ALOGE("qn8027_open fm_fd= %d", fm_fd);

         }

         return fm_fd;

}

staticjint qn8027_close(JNIEnv *env, jobject thiz)

{

         jint ret;

    ret = close(fm_fd);

         return ret;

}

staticjint qn8027_start(JNIEnv *env, jobject thiz)

{

         jint ret;

         ret = ioctl(fm_fd,FMTRANS_IOCTL_START);

         if (ret < 0)                                                                                                                                                                                                             

         {

                   ALOGE("qn8027_start ret= %d", ret);

                   return ret;

         }

         return 0;

}

staticjint qn8027_stop(JNIEnv *env, jobject thiz)

{

         jint ret;

         ret = ioctl(fm_fd, FMTRANS_IOCTL_STOP);

         if (ret < 0)                                                                                                                                                                                                            

         {

                   ALOGE("qn8027_stop ret =%d", ret);

                   return ret;

         }

         return 0;

}

 

staticjint qn8027_set_rate(JNIEnv *env, jobject thiz, jint a)

{

         static jint set_rate = 0;

         jint ret;

         set_rate = a;             //760 <= set_rate <= 1080      

         ALOGD("--->set_rate = %d",set_rate);

         ret = ioctl(fm_fd,FMTRANS_IOCTL_SET_RATE, &set_rate);

         if (ret < 0)                                                                                                                                                                                                            

         {

                   ALOGE("qn8027_set_rateret = %d", ret);

                   return ret;

         }

         return 0;

}

 

//com/hcn/fmemitter

staticconst char *classPathName = "com/hcn/fmemitter/MainActivity";

/*增加的具体方法*/

static JNINativeMethod methods[] = {

//  {"add","(II)I", (void*)add },

  {"FmInit","()I", (void*)qn8027_init },

 {"FmFinish", "()I", (void*)qn8027_finish},

  {"FmOpen","()I", (void*)qn8027_open },

  {"FmClose","()I", (void*)qn8027_close},

  {"FmStart","()I", (void*)qn8027_start },

  {"FmStop","()I", (void*)qn8027_stop },

// {"FmStatus", "()I", (void*)qn8027_status },

 {"FmSetRate", "(I)I", (void*)qn8027_set_rate },

};

 

/*

 * Register several native methods for oneclass.

 */

staticint registerNativeMethods(JNIEnv* env, const char* className,

    JNINativeMethod* gMethods, int numMethods)

{

    jclass clazz;

 

    clazz = env->FindClass(className);

    if (clazz == NULL) {

        ALOGE("Native registration unableto find class '%s'", className);

        return JNI_FALSE;

    }

    if (env->RegisterNatives(clazz,gMethods, numMethods) < 0) {

        ALOGE("RegisterNatives failed for'%s'", className);

        return JNI_FALSE;

    }

 

    return JNI_TRUE;

}

 

/*

 * Register native methods for all classes weknow about.

 *

 * returns JNI_TRUE on success.

 */

staticint registerNatives(JNIEnv* env)

{

/*注册一个本地的方法,classPathName就是需要增加这些方法的class*/

  if (!registerNativeMethods(env,classPathName,

                 methods, sizeof(methods) /sizeof(methods[0]))) {

   return JNI_FALSE;

  }

 

  return JNI_TRUE;

}

 

 

//----------------------------------------------------------------------------

 

/*

 * This is called by the VM when the sharedlibrary is first loaded.

 */

 

typedefunion {

    JNIEnv* env;

    void* venv;

}UnionJNIEnvToVoid;

 

jintJNI_OnLoad(JavaVM* vm, void* reserved)/*JNI的入口,具体流程待学习*/

{

    UnionJNIEnvToVoid uenv;

    uenv.venv = NULL;

    jint result = -1;

    JNIEnv* env = NULL;

   

    ALOGI("JNI_OnLoad");

 

    if (vm->GetEnv(&uenv.venv,JNI_VERSION_1_4) != JNI_OK) {

        ALOGE("ERROR: GetEnvfailed");

        goto bail;

    }

    env = uenv.env;

 

    if (registerNatives(env)!= JNI_TRUE) {

        ALOGE("ERROR: registerNativesfailed");

        goto bail;

    }

   

    result = JNI_VERSION_1_4;

    

bail:

    return result;

}

 

fm_qn8027.h文档:

#ifndef__QN8027_H__

#define__QN8027_H__

 

#include

#include

 

#defineFMTRANS                     0x58

#defineFMTRANS_IOCTL_START         _IO(FMTRANS,0x01)

#defineFMTRANS_IOCTL_STOP          _IO(FMTRANS,0x02)

#defineFMTRANS_IOCTL_SET_RATE     _IOW(FMTRANS,0x03, unsigned int)

 

#defineDEVICE_NAME "/dev/fmtransmitter"

 

 

#endif

 

三,JAVA层的调用:

加载LIB,然后申明这个接口为本地的方法。后面就可以当做内部函数来调用了。

 static

  {

   System.loadLibrary("fm_qn8027_jni");

  }

 

 private static native int FmClose();

 

 private static native int FmFinish();

 

 private static native int FmInit();

 

 private static native int FmOpen();

 

 private static native int FmSetRate(int paramInt);

 

 private static native int FmStart();

 

 private static native int FmStop();


四,FM发送对应sh命令的制作。

 

Android.mk    /*编译文档*/

fmtest.c    /*命令的实现*/

 

Android.mk文档:

LOCAL_PATH:= $(call my-dir)

include$(CLEAR_VARS)

 

LOCAL_SRC_FILES:= fmtest.c

 

LOCAL_SHARED_LIBRARIES:= \

        libcutils

 

LOCAL_CERTIFICATE:= platform

LOCAL_MODULE:= fmtest

include $(BUILD_EXECUTABLE)

 

 

fmtest.c文档:

/*************************************************************************

        > File Name: fmtest.c

        > Created by JinQuan, Time: Fri 19Jun 2015 02:05:57 PM CST

 ************************************************************************/

#include

#include

#include

#include

#include

 #include

 

 #define FMTRANS                     0x58

 #define FMTRANS_IOCTL_START         _IO(FMTRANS, 0x01)

 #define FMTRANS_IOCTL_STOP          _IO(FMTRANS, 0x02)

 #define FMTRANS_IOCTL_SET_RATE      _IOW(FMTRANS,0x03, unsigned int)

 /*

 fmtest cmd:

 0: stop

 1: start

 other: set rate

关闭FM发射adb命令:

Fmtest /dev/fmtransmitter 0

打开FM发送:

Fmtest /dev/fmtransmitter 1

设置FM发送的频率:例如频率为90.0MHZ

Fmtest /dev/fmtransmitter 2 900

 */

 int main(int argc, char **argv)

 {

         int fd;

         int ret;

         int cmd = argv[2][0];

 

         if(argc < 2)

         {

                 printf("please entercmd\n");

                 return 0;

         }

//               fd = open("/dev/tty",O_RDWR | O_NOCTTY | O_NDELAY);

                   printf("1-->>%s\n",argv[0]);

                   printf("2-->>%s\n",argv[1]);

//               fd =open("/dev/ttyMT1", O_RDWR );

                   fd = open(argv[1], O_RDWR );

//         fd =open("/dev/fmtransmitter", O_RDONLY);

         if(fd <=0 )

         {

                 printf("open deviceserror!fd=%d\n",fd);

                 return -1;

         } else {

                             printf("open success!fd=%d\n",fd);

                    }

                    sleep(5);

         switch(cmd)

         {

                 case '0':

                         printf("FMTRANS_IOCTL_STOP\n");

                         ret = ioctl(fd,FMTRANS_IOCTL_STOP);

                         printf("ioctlreturn is %d\n", ret);

                         break;

                 case '1':

                        printf("FMTRANS_IOCTL_START\n");

                         ioctl(fd, FMTRANS_IOCTL_START);

                         break;

                 case '2':

                         if(argc < 3)

                         {

                                 printf("parameter notright\n");

                                 return -1;

                         }

                         int freq =strtoul(argv[3], 0, 0);

                        printf("FMTRANS_IOCTL_SET_RATE %d\n", freq);

                         ioctl(fd,FMTRANS_IOCTL_SET_RATE, &freq);

                         break;

                 default:

                         break;

         }

 

         close(fd);

         return 0;

 }

 

 

你可能感兴趣的:(实例应用分析)