Guest User

hal_imx6_gpio.c

a guest
Mar 17th, 2014
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.00 KB | None | 0 0
  1. /********************************************************************
  2. * Description:  hal_imx6_gpio.c
  3. *               Driver for iMX6 GPIO pins
  4. *
  5. * Author: Paul Setchko <[email protected]>
  6. * License: GPL Version 2
  7. * Copyright (c) 2014.
  8. *
  9. ********************************************************************/
  10.  
  11.  
  12. #include "rtapi.h"     
  13. #include "rtapi_app.h" 
  14.  
  15. #include "hal.h"   
  16.  
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <fcntl.h>
  20. #include <sys/mman.h>
  21. #include <stdlib.h>
  22. #include <unistd.h>
  23. #include <stdint.h>
  24.  
  25. #include "imx6_gpio.h"
  26.  
  27. #if !defined(BUILD_SYS_USER_DSO)
  28. #error "This driver is for usermode threads only"
  29. #endif
  30.  
  31. #define MODNAME "hal_imx6_gpio"
  32.  
  33. MODULE_AUTHOR("Paul Setchko");
  34. MODULE_DESCRIPTION("Driver for iMX6 GPIO pins");
  35. MODULE_LICENSE("GPL");
  36.  
  37. #define PINS 11
  38.  
  39. typedef struct {
  40.     hal_bit_t* input_pins[PINS]; // array of pointers to bits
  41.     hal_bit_t* output_pins[PINS]; // array of pointers to bits
  42. } port_data_t;
  43.  
  44. static port_data_t *port_data;
  45.  
  46. static const char *modname = MODNAME;
  47.  
  48. static void write_port(void *arg, long period);
  49. static void read_port(void *arg, long period);
  50.  
  51. static off_t start_addr_for_port(int port);
  52. static void configure_pin(imx_gpio_pin *pin, char mode);
  53.  
  54. static int comp_id;
  55. static int num_ports;
  56.  
  57. static char *input_pins;
  58. RTAPI_MP_STRING(input_pins, "input pins, comma separated");
  59.  
  60. static char *output_pins;
  61. RTAPI_MP_STRING(output_pins, "output pins, comma separated");
  62.  
  63. int rtapi_app_main(void) {
  64.     char name[HAL_NAME_LEN + 1];
  65.     int n, retval;
  66.     char *data, *token;
  67.  
  68.     num_ports = 1;
  69.     n = 0; // port number... only one for now
  70.  
  71.     // init driver
  72.     comp_id = hal_init(modname);
  73.     if(comp_id < 0) {
  74.         rtapi_print_msg(RTAPI_MSG_ERR, "%s: ERROR: hal_init() failed\n", modname);
  75.         return -1;
  76.     }
  77.  
  78.     // allocate port memory
  79.     port_data = hal_malloc(sizeof(port_data_t));
  80.     if(port_data == 0) {
  81.         rtapi_print_msg(RTAPI_MSG_ERR, "%s: ERROR: hal_malloc() failed\n", modname);
  82.         hal_exit(comp_id);
  83.         return -1;
  84.     }
  85.  
  86.     // configure input pins
  87.     if(input_pins != NULL) {
  88.         data = input_pins;
  89.         while((token = strtok(data, ",")) != NULL) {
  90.             int pin = strtol(token, NULL, 10);
  91.             imx_gpio_pin *imxpin = &x54_pins[pin];
  92.  
  93.             if(imxpin->claimed != 0) {
  94.                 rtapi_print_msg(RTAPI_MSG_ERR, "%s: ERROR: pin %02d is not available as a GPIO.\n", modname, pin);
  95.                 hal_exit(comp_id);
  96.                 return -1;
  97.             }
  98.  
  99.             // map control module memory
  100.             configure_control_module(imxpin);
  101.  
  102.             data = NULL; // after the first call, subsequent calls to strtok need to be on NULL
  103.  
  104.             // Add HAL pin
  105.             retval = hal_pin_bit_newf(HAL_OUT, &(port_data->input_pins[pin]), comp_id, "imx6_gpio.in-%02d", pin);
  106.  
  107.             if(retval < 0) {
  108.                 rtapi_print_msg(RTAPI_MSG_ERR, "%s: ERROR: could not export pin %02d, err: %d\n", modname, pin, retval);
  109.                 hal_exit(comp_id);
  110.                 return -1;
  111.             }
  112.  
  113.             configure_pin(imxpin, 'I');
  114.             rtapi_print("pin %d maps to pin %d, mode %d\n", pin, imxpin->pin_num, imxpin->claimed);
  115.         }
  116.     }
  117.  
  118.     // configure output pins
  119.     if(output_pins != NULL) {
  120.         data = output_pins;
  121.         while((token = strtok(data, ",")) != NULL) {
  122.             int pin = strtol(token, NULL, 10);
  123.             imx_gpio_pin *imxpin = &x54_pins;
  124.            
  125.             // map control module memory
  126.             configure_control_module(imxpin);
  127.  
  128.             if(imxpin->claimed != 0) {
  129.                 rtapi_print_msg(RTAPI_MSG_ERR, "%s: ERROR: pin %02d is not available as a GPIO.\n", modname, pin);
  130.                 hal_exit(comp_id);
  131.                 return -1;
  132.             }
  133.  
  134.             data = NULL; // after the first call, subsequent calls to strtok need to be on NULL
  135.  
  136.             // Add HAL pin
  137.             retval = hal_pin_bit_newf(HAL_IN, &(port_data->output_pins[pin]), comp_id, "imx6_gpio.out-%02d", pin);
  138.  
  139.             if(retval < 0) {
  140.                 rtapi_print_msg(RTAPI_MSG_ERR, "%s: ERROR: could not export pin %02d, err: %d\n", modname, pin, retval);
  141.                 hal_exit(comp_id);
  142.                 return -1;
  143.             }
  144.  
  145.             configure_pin(imxpin, 'O');
  146.             rtapi_print("pin %d maps to pin %d, mode %d\n", pin, imxpin->pin_num, imxpin->claimed);
  147.         }
  148.     }
  149.  
  150.  
  151.     // export functions
  152.     rtapi_snprintf(name, sizeof(name), "imx6_gpio.write");
  153.     retval = hal_export_funct(name, write_port, port_data, 0, 0, comp_id);
  154.     if(retval < 0) {
  155.         rtapi_print_msg(RTAPI_MSG_ERR, "%s: ERROR: port %d write funct export failed\n", modname, n);
  156.         hal_exit(comp_id);
  157.         return -1;
  158.     }
  159.    
  160.     rtapi_snprintf(name, sizeof(name), "imx6_gpio.read");
  161.     retval = hal_export_funct(name, read_port, port_data, 0, 0, comp_id);
  162.     if(retval < 0) {
  163.         rtapi_print_msg(RTAPI_MSG_ERR, "%s: ERROR: port %d read funct export failed\n", modname, n);
  164.         hal_exit(comp_id);
  165.         return -1;
  166.     }
  167.  
  168.     rtapi_print_msg(RTAPI_MSG_INFO, "%s: installed driver\n", modname);
  169.  
  170.     hal_ready(comp_id);
  171.  
  172.     return 0;
  173. }
  174.  
  175. void rtapi_app_exit(void) {
  176.  
  177.     hal_exit(comp_id);
  178. }
  179.  
  180. static void write_port(void *arg, long period) {
  181.     int i;
  182.     port_data_t *port = (port_data_t *)arg;
  183.  
  184.     // set output states
  185.     for(i = 0; i < PINS; i++) {
  186.        
  187.         if(port->output_pins[i] == NULL)
  188.             continue; // short circuit if hal hasn't malloc'd a bit at this location
  189.  
  190.         imx_gpio_pin pin = x54_pins[i];
  191.  
  192.         int fd = open("/dev/mem", O_RDWR);
  193.  
  194.         gpio = (uint32_t *)mmap( 0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, (uint32_t *)(pin.reg_addr) );
  195.  
  196.         if(gpio == MAP_FAILED) {
  197.             rtapi_print_msg(RTAPI_MSG_ERR, "%s: ERROR: Unable to map Control Module: %s", modname, strerror(errno));
  198.             exit(1);
  199.         }
  200.  
  201.         close(fd);
  202.  
  203.         if( pin.claimed != 'O' )
  204.             continue; // if we somehow get here but the pin isn't claimed as output, short circuit
  205.  
  206.         if(*port->output_pins[i] == 0)
  207.             *(gpio) &= ~( 1 << (pin.pin_num) );
  208.         else
  209.             *(gpio) |= ( 1 << (pin.pin_num) );
  210.     }
  211. }
  212.  
  213.  
  214. static void read_port(void *arg, long period) {
  215.     int i;
  216.     port_data_t *port = (port_data_t *)arg;
  217.  
  218.     // read input states
  219.     for( i = 0; i < PINS; i++ ) {
  220.  
  221.         if(port->input_pins[i] == NULL)
  222.             continue; // short circuit if hal hasn't malloc'd a bit at this location
  223.  
  224.         imx_gpio_pin pin = x54_pins[i];
  225.  
  226.         int fd = open("/dev/mem", O_RDWR);
  227.  
  228.         gpio = (uint32_t *)mmap( 0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, (uint32_t *)(pin.reg_addr) );
  229.  
  230.         if(gpio == MAP_FAILED) {
  231.             rtapi_print_msg(RTAPI_MSG_ERR, "%s: ERROR: Unable to map Control Module: %s", modname, strerror(errno));
  232.             exit(1);
  233.         }
  234.  
  235.         close(fd);
  236.  
  237.  
  238.         if( !(pin.claimed == 'I') )
  239.             continue; // if we get here but the pin isn't claimed as input, short circuit
  240.  
  241.         *port->input_pins[i] = ((*(gpio) & (1 << pin.pin_num))  >> pin.pin_num);
  242.     }
  243. }
  244.  
  245. void configure_pin(imx_gpio_pin *pin, char mode) {
  246.     pin->claimed = mode;
  247.    
  248.     int fd = open("/dev/mem", O_RDWR);
  249.  
  250.     gpio = (uint32_t *)mmap( 0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, (uint32_t *)(pin->reg_addr) );
  251.  
  252.     if(gpio == MAP_FAILED) {
  253.         rtapi_print_msg(RTAPI_MSG_ERR, "%s: ERROR: Unable to map Control Module: %s", modname, strerror(errno));
  254.         exit(1);
  255.     }
  256.  
  257.     close(fd);
  258.    
  259.     switch(mode) {
  260.         case 'O':
  261.             *((gpio) + 4) |= (1 << pin->pin_num); // 0 in OE is output enable
  262.             break;
  263.         case 'I':
  264.             *((gpio) + 4) &= ~(1 << pin->pin_num); // 1 in OE is input
  265.             break;
  266.         default:
  267.             break;
  268.     }
  269. }
Advertisement
Add Comment
Please, Sign In to add comment