This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Precise Delay

Other Parts Discussed in Thread: TSC2004, TVP7002

Dear all,

I work with DM365 spectrum digital evaluation board.

I have to write device driver for UART on GPIO (Bit Bang), I all ready write the driver but during transmission , sometimes I get mistakes on the receive unit.

I check with oscilloscope, and I saw that sometimes dm365 transmits ~70usec delay (per bit) instead 52usec delay (per bit), and it destroy the character.

I think the problem is that, my driver in the low priority, and kernel leave the driver for a while, and come back after some time.

My question: how I can insure that kernel will not leave my driver during transmission character, I need to ensure .

The Transmit function: static void transmit_char(char data)

Thank

Alex

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/i2c.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/i2c/at24.h>
#include <linux/i2c/tsc2004.h>
#include <linux/leds.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <linux/input.h>
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>


#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_from/to_user */
#include <linux/jiffies.h>


#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/mux.h>
#include <mach/hardware.h>
#include <mach/dm365.h>
#include <mach/psc.h>
#include <mach/common.h>
#include <mach/i2c.h>
#include <mach/serial.h>
#include <mach/mmc.h>
#include <mach/mux.h>
#include <mach/nand.h>
#include <mach/keyscan.h>
#include <mach/gpio.h>
#include <mach/cputype.h>
#include <linux/videodev2.h>
#include <media/tvp514x.h>
#include <media/tvp7002.h>
#include <media/davinci/videohd.h>

static void transmit_char(char data);

static int gpio1_open(struct inode *inode, struct file *filp);
static int gpio1_release(struct inode *inode, struct file *filp);
static ssize_t gpio1_read(struct file *filp, char  __user *buf, size_t count, loff_t *f_pos);
static ssize_t gpio1_write(struct file *filp,const char __user *buf, size_t count, loff_t *f_pos);
static void gpio1_cleanup(void);
static int gpio1_init(void);
static void send_buffer(char *buffer, size_t count);
static char receive_func(void);

struct file_operations gpio1_fops = {
  read:  gpio1_read,
  write:  gpio1_write,
  open:  gpio1_open,
  release:  gpio1_release
};

/* Global variables of the driver */
/* Major number */
int memory_major = 60, buf_size;
/* Buffer to store data */
char *memory_buffer;


MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alex D.");

static int io30 = 1;
module_param(io30, int,0);
static int io31 = 1;
module_param(io31, int,0);
static int io32 = 1;
module_param(io32, int,0);
static int io33 = 1;
module_param(io33, int,0);

#define bit_time 52 // usec ~= 1/19200(bits/sec)
#define bit_time_half 26

#define GPIO30_TXEN 30
#define GPIO31_TX 31
#define GPIO32_RXEN 32
#define GPIO33_RX 33


static int gpio1_open(struct inode *inode, struct file *filp) {

  /* Success */
  return 0;
}

static int gpio1_release(struct inode *inode, struct file *filp) {
 
  /* Success */
  return 0;
}

 

static ssize_t gpio1_read(struct file *filp, char  __user *buf, size_t count, loff_t *f_pos)

}

static ssize_t gpio1_write( struct file *filp, const char __user  *buf, size_t count, loff_t *f_pos)
{
 
  printk("Hello Alex write\n");
 
  copy_from_user(memory_buffer,buf,count);
  send_buffer (memory_buffer,count);
  return count;
}


static void dm365evm_DCMC_UART422_configure(void)
{
 int ret = 0; 

// davinci_cfg_reg(DM365_GPIO30_UART422_TXEN);
 ret = gpio_request(30, "GPIO30_UART422_TXEN");
 if (ret < 0)  pr_warning("%s: gpio30-not good: %d\n",__func__, ret);
 else pr_warning("%s: gpio30 good: %d\n",__func__, ret);
 gpio_direction_output(30, 0);

// davinci_cfg_reg(DM365_GPIO31_UART422_TX);
 ret = gpio_request(31, "GPIO31_UART422_TX");
 if (ret < 0) pr_warning("%s: gpio31-no: %d\n",__func__, ret);
 else pr_warning("%s: gpio31good: %d\n",__func__, ret);     
 gpio_direction_input(31);

// davinci_cfg_reg(DM365_GPIO32_UART422_RXEN);
 ret = gpio_request(32, "GPIO32_UART422_RXEN");
 if (ret < 0) pr_warning("%s:  gpio32 no: %d\n",__func__, ret);
 else pr_warning("%s: gpio32good: %d\n",__func__, ret);
 gpio_direction_output(32,0);

// davinci_cfg_reg(DM365_GPIO33_UART422_RX);
// ret = gpio_request(33, "GPIO33_UART422_RX");  
// if (ret < 0) pr_warning("%s: gpio33-no: %d\n",__func__, ret);
// else pr_warning("%s:  gpio33good: %d\n", __func__, ret);
// gpio_direction_output(33, 0); 
}

static void send_buffer(char *buffer, size_t count )
{
  int i;
  for(i=0; i<count; i++)
  {
    transmit_char(*buffer++);
    mdelay(60);
  }
}

 

static void loop_out(int loop)
{
  int i=0;
  for (i=0;i<loop;i++)
  {
    send_buffer("test",4);
    mdelay(60);
  }
}

static void transmit_char(char data)
{
//  char temp=0;
  char d0,d1,d2,d3,d4,d5,d6,d7;
  d0= ((data) & 0x01) ;
  d1= ((data >> 1) & 0x01);
  d2= ((data >> 2) & 0x01);
  d3= ((data >> 3) & 0x01);
  d4= ((data >> 4) & 0x01);
  d5= ((data >> 5) & 0x01);
  d6= ((data >> 6) & 0x01);
  d7= ((data >> 7) & 0x01);  
 
    gpio_set_value(GPIO32_RXEN,0); //start bit
      udelay(bit_time);   

 //          temp= ((data) & 0x01) ;
    gpio_set_value(GPIO32_RXEN,d0);
      udelay(bit_time); 
     
//        temp= ((data >> 1) & 0x01);
    gpio_set_value(GPIO32_RXEN,d1);
      udelay(bit_time); 
 
//    temp= ((data >> 2) & 0x01);
    gpio_set_value(GPIO32_RXEN,d2);
      udelay(bit_time);

 //           temp= ((data >> 3) & 0x01);
    gpio_set_value(GPIO32_RXEN,d3);
      udelay(bit_time);

 //       temp= ((data >> 4) & 0x01);
    gpio_set_value(GPIO32_RXEN,d4);
      udelay(bit_time);

//      temp= ((temp) & 0x01);
    gpio_set_value(GPIO32_RXEN,d5);
    udelay(bit_time); 

//      temp= ((data >> 6) & 0x01);
    gpio_set_value(GPIO32_RXEN,d6);
    udelay(bit_time);
   
//    temp= ((data >> 7) & 0x01);
    gpio_set_value(GPIO32_RXEN,d7);
    udelay(bit_time);

    gpio_set_value(GPIO32_RXEN,1); // stop bit
    udelay(bit_time);
}

static char receive_func(void)
{
  char result=0, temp=0;
 
//   if (gpio_get_value(GPIO30_TXEN)==0) //start bit
 //  { 
 udelay(bit_time);   
 udelay(bit_time_half);
   
    temp=gpio_get_value(GPIO30_TXEN); //1st bit
    result=0x01&(temp);
    udelay(bit_time);
   
    temp=gpio_get_value(GPIO30_TXEN); //2nd bit
    temp=(0x01&(temp));
    result=result|(temp<<1);
    udelay(bit_time);
   
    temp=gpio_get_value(GPIO30_TXEN); //3rd bit
    temp=(0x01&(temp));
    result=result|(temp<<2);
    udelay(bit_time);
   
    temp=gpio_get_value(GPIO30_TXEN); //4th bit
    temp=(0x01&(temp));
    result=result|(temp<<3);
    udelay(bit_time);
   
    temp=gpio_get_value(GPIO30_TXEN); //5 bit
    temp=(0x01&(temp));
    result=result|(temp<<4);
    udelay(bit_time);
   
    temp=gpio_get_value(GPIO30_TXEN); //6 bit
    temp=(0x01&(temp));
    result=result|(temp<<5);
    udelay(bit_time);
   
    temp=gpio_get_value(GPIO30_TXEN); //7 bit
    temp=(0x01&(temp));
    result=result|(temp<<6);
    udelay(bit_time);

    temp=gpio_get_value(GPIO30_TXEN); //8 bit
    temp=(0x01&(temp));
    result=result|(temp<<7);
 //  }
   return result;
   
}

static int gpio1_init(void)
{
  int result;

  /* Registering device */
  result = register_chrdev(memory_major, "memory", &gpio1_fops);
  if (result < 0) {
    printk(
      "<1>memory: cannot obtain major number %d\n", memory_major);
    return result;
  }

  /* Allocating memory for the buffer */
 memory_buffer = kmalloc(8192, GFP_USER);
 buf_size = 8192;
 if (!memory_buffer) {
    result = -ENOMEM;
    printk("memory alloc fail\n");
    goto fail;
  }
  memset(memory_buffer, 0, 1);

  printk("<1>Inserting memory module\n");
  printk("Hello,this is gpio 1st code\n");
 
 //dm365evm_DCMC_UART422_configure();
 loop_out(10);
    return 0;

  fail:
    gpio1_cleanup();
    return result;
 
 
}


static void gpio1_cleanup(void)
{
    /* Freeing the major number */
  unregister_chrdev(memory_major, "memory");

  /* Freeing buffer memory */
  if (memory_buffer) {
    kfree(memory_buffer);
  }

  printk("<1>Removing memory module\n");

 
 printk("Exit Gpio Module\n");
   gpio_free(30);
   gpio_free(31);
   gpio_free(32);
//   gpio_free(33);

}


module_init(gpio1_init);
module_exit(gpio1_cleanup);