venkat_330

Parallel port access via Kernel Driver

Aug 31st, 2017
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.10 KB | None | 0 0
  1. #include <errno.h>
  2. #include <fcntl.h>
  3. #include <linux/parport.h>
  4. #include <linux/ppdev.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/ioctl.h>
  9. #include <sys/time.h>
  10. #include <time.h>
  11. #include <unistd.h>
  12. #include <stdint.h>
  13.  
  14. #define PARDEV "/dev/parport0"
  15.  
  16. enum {
  17.   PPIDATA,
  18.   PPICTRL,
  19.   PPISTATUS
  20. };
  21.  
  22. enum {
  23.   PPI_READ=0,
  24.   PPI_WRITE,
  25.   PPI_SHADOWREAD
  26. };
  27.  
  28.  
  29. int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action);
  30. int ppi_set(int fd, int reg, int bit);
  31. int ppi_clr(int fd, int reg, int bit);
  32. int ppi_get(int fd, int reg, int bit);
  33. int ppi_toggle(int fd, int reg, int bit);
  34. int ppi_getall(int fd, int reg);
  35. int ppi_setall(int fd, int reg, int val);
  36. int ppi_open(char * port);
  37. void ppi_close(int fd);
  38. int par_pinStatus(int port);
  39. int par_pinWrite(int port, int data);
  40.  
  41. #define DEBUG_LOG 0
  42. #define TRACE_LOG 1
  43.  
  44. void debug_log(char *s, int t)
  45. {
  46.     printf("\n%s",s);
  47. }
  48.  
  49. #define PARALLEL_PORT_ADDR 0x378
  50. #define JP_SENSOR_PORT_ADDR (PARALLEL_PORT_ADDR + 2)
  51. #define JP_LOWPAPER_SENSOR_PORT (PARALLEL_PORT_ADDR + 1)
  52. #define JP_MOTOR_PORT_ADDR (PARALLEL_PORT_ADDR + 2)
  53.  
  54. #define BIT(x) (1 << x)
  55. #define JP_SENSOR_CTRL_BIT BIT(2)
  56. #define JP_SENSOR_VALUE(x) (((x) & JP_SENSOR_CTRL_BIT) >> 2)
  57. #define JP_LOWPAPER_SENSOR_BIT BIT(3)
  58. #define JP_LOWPAPER_SENSOR_VALUE(x) (((x) & JP_LOWPAPER_SENSOR_BIT) >> 3)
  59. #define JP_MOTOR_CTRL_BIT BIT(0)
  60.  
  61. #define JP_SENSOR_CLEAR 1
  62. #define JP_SENSOR_BLOCK 0
  63.  
  64. #define JP_MOTOR_START 1
  65. #define JP_MOTOR_STOP 0
  66.  
  67. #define OBSOLETE__IOW _IOW
  68.  
  69. #define PPISDATA    PPWDATA
  70. #define PPIGDATA    PPRDATA
  71.  
  72. #define PPISCTRL    PPWCONTROL
  73. #define PPIGCTRL    PPRCONTROL
  74.  
  75. #define PPISSTATUS  PPWSTATUS
  76. #define PPIGSTATUS  PPRSTATUS
  77.  
  78. #define PIN_INVERSE 0x80    /* flag for inverted pin in serbb */
  79. #define PIN_MASK    0x7f
  80.  
  81. struct ppipins_t {
  82.   int pin;
  83.   int reg;
  84.   int bit;
  85.   int inverted;
  86. };
  87.  
  88. struct ppipins_t ppipins[] = {
  89.   {  1, PPICTRL,   0x01, 1 },
  90.   {  2, PPIDATA,   0x01, 0 },
  91.   {  3, PPIDATA,   0x02, 0 },
  92.   {  4, PPIDATA,   0x04, 0 },
  93.   {  5, PPIDATA,   0x08, 0 },
  94.   {  6, PPIDATA,   0x10, 0 },
  95.   {  7, PPIDATA,   0x20, 0 },
  96.   {  8, PPIDATA,   0x40, 0 },
  97.   {  9, PPIDATA,   0x80, 0 },
  98.   { 10, PPISTATUS, 0x40, 0 },
  99.   { 11, PPISTATUS, 0x80, 1 },
  100.   { 12, PPISTATUS, 0x20, 0 },
  101.   { 13, PPISTATUS, 0x10, 0 },
  102.   { 14, PPICTRL,   0x02, 1 },
  103.   { 15, PPISTATUS, 0x08, 0 },
  104.   { 16, PPICTRL,   0x04, 0 },
  105.   { 17, PPICTRL,   0x08, 1 }
  106. };
  107.  
  108.  
  109.  
  110. #define ppi_claim(fd)                                       \
  111.   if (ioctl(fd, PPCLAIM) < 0) {                             \
  112.     fprintf(stderr, "SYSTEM: Parallel Port: can't claim device: %s\n\n", \
  113.             strerror(errno));                \
  114.     close(fd);                                          \
  115.     exit(1);                                                 \
  116.   }
  117.  
  118. #define ppi_release(fd)                                     \
  119.   if (ioctl(fd, PPRELEASE) < 0) {                           \
  120.     fprintf(stderr, "SYSTEM: Parallel Port: can't release device: %s\n\n",      \
  121.             strerror(errno));  \
  122.     close(fd);                     \
  123.     exit(1);                                                 \
  124.   }
  125.  
  126.  
  127. int parallelFd = 0;
  128.  
  129. int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
  130. {
  131.   static unsigned char shadow[3];
  132.   int shadow_num;
  133.   int mode;
  134.   unsigned long set, get;
  135.   int rc = 0;
  136.   char debugBuf[256] = { '\0' };
  137.  
  138.   switch (reg)
  139.   {
  140.     case PPIDATA: set = PPISDATA; get = PPIGDATA; shadow_num = 0; break;
  141.     case PPICTRL: set = PPISCTRL; get = PPIGCTRL; shadow_num = 1; break;
  142.     case PPISTATUS: set = PPISSTATUS; get = PPIGSTATUS; shadow_num = 2; break;
  143.     default:
  144.         memset(debugBuf,0,sizeof(debugBuf));
  145.         sprintf(debugBuf, "SYSTEM: Parallel Port: avr_set(): invalid register=%d\n", reg);
  146.         debug_log(debugBuf,DEBUG_LOG);
  147.       return -1;
  148.       break;
  149.   }
  150.   printf("ShadowAccess for : %d -- Action : %d --",reg,action);
  151.   switch (action)
  152.   {
  153.     case PPI_SHADOWREAD:
  154.         *v = shadow[shadow_num];
  155.         break;
  156.     case PPI_READ:
  157.         mode = IEEE1284_MODE_ECP;
  158.         rc = ioctl(fd, PPSETMODE, &mode);
  159.         rc = ioctl(fd, get, v);
  160.         shadow[shadow_num]=*v;
  161.         break;
  162.     case PPI_WRITE:
  163.         printf("ppi_write");
  164.         shadow[shadow_num]=*v;
  165.         rc = ioctl(fd, set, v);
  166.         break;
  167.   }
  168.   printf(" port Val : %02X - IOCTL ret : %d \n",*v,rc);
  169.   return rc;
  170. }
  171.  
  172. /*
  173.  * get all bits of the specified register.
  174.  */
  175. int ppi_getall(int fd, int reg)
  176. {
  177.   unsigned char v;
  178.   int rc;
  179.  
  180.   rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
  181.  
  182.   if (rc)
  183.     return -1;
  184.  
  185.   return v; /* v == bit */
  186. }
  187.  
  188. /*
  189.  * set all bits of the specified register to val.
  190.  */
  191. int ppi_setall(int fd, int reg, int val)
  192. {
  193.   unsigned char v;
  194.   int rc;
  195.  
  196.   v = val;
  197.   rc = ppi_shadow_access(fd, reg, &v, PPI_WRITE);
  198.  
  199.   if (rc)
  200.     return -1;
  201.  
  202.   return 0;
  203. }
  204.  
  205.  
  206. int ppi_open(char * port)
  207. {
  208.   int prallelFd = 0;
  209.   unsigned char v;
  210.   char debugBuf[256] = { '\0' };
  211.  
  212.   if(!prallelFd)
  213.   {
  214.       prallelFd = open(port, O_RDWR);
  215.       if (prallelFd < 0)
  216.       {
  217.         memset(debugBuf,0,sizeof(debugBuf));
  218.         sprintf(debugBuf, "SYSTEM: Parallel Port: can't open device \"%s\": %s", port, strerror(errno));
  219.         debug_log(debugBuf,DEBUG_LOG);
  220.         return prallelFd;
  221.       }
  222.       ppi_claim(prallelFd);
  223.  
  224.       ppi_shadow_access (prallelFd, PPIDATA, &v, PPI_READ);
  225.       ppi_shadow_access (prallelFd, PPICTRL, &v, PPI_READ);
  226.       ppi_shadow_access (prallelFd, PPISTATUS, &v, PPI_READ);
  227.   }
  228.  
  229.   return prallelFd;
  230. }
  231.  
  232.  
  233. void ppi_close(int fd)
  234. {
  235.     ppi_release(fd);
  236.     close(fd);
  237. }
  238.  
  239.  
  240. int par_pinStatus(int port)
  241. {
  242.     int16_t sensorValue=-1;
  243.     char charBuf[128] = {'\0'};
  244.    
  245.     if(!parallelFd)
  246.         return -1;
  247.  
  248.     switch(port)
  249.     {
  250.         case 0x378: //data
  251.             port=PPIDATA;
  252.             printf("\ndata");
  253.             break;
  254.         case 0x379: //status
  255.             port=PPISTATUS;
  256.             printf("\nstatus");
  257.             break;
  258.         case 0x37A: //control
  259.             printf("\ncontrol");
  260.             port=PPICTRL;
  261.             break;
  262.         default:
  263.             port=PPISTATUS;
  264.             break;
  265.     }
  266.  
  267.     sensorValue = ppi_getall(parallelFd,port);
  268.  
  269.     return sensorValue;
  270. }
  271.  
  272. int par_pinWrite( int data,int port)
  273. {
  274.     int sensorValue=-1;
  275.     char charBuf[128] = {'\0'};
  276.  
  277.     //int parallelFd=ppi_open(PARDEV);
  278.     if(!parallelFd)
  279.         return -1;
  280.  
  281.     switch(port)
  282.     {
  283.         case 0x378: //data
  284.             port=PPIDATA;
  285.             break;
  286.         case 0x379: //status
  287.             port=PPISTATUS;
  288.             break;
  289.         case 0x37A: //control
  290.             port=PPICTRL;
  291.             break;
  292.         default:
  293.             port=PPISTATUS;
  294.             break;
  295.     }
  296.     sensorValue = ppi_setall(parallelFd, port,data);
  297.  
  298.     return sensorValue;
  299. }
  300.  
  301. int16_t jp_readSensorVal(void)
  302. {
  303.     static int16_t portValPrev = 0;
  304.     int16_t portVal = 0;
  305.     char charBuf[128] = {'\0'};
  306.  
  307.     par_pinWrite(par_pinStatus(JP_SENSOR_PORT_ADDR) | JP_SENSOR_CTRL_BIT, JP_MOTOR_PORT_ADDR);
  308.     usleep(5000);// Delay to make sure the value is reflected in any up-coming read
  309.     portVal = par_pinStatus(JP_SENSOR_PORT_ADDR);
  310.     if(portVal != portValPrev)
  311.     {
  312.         memset(charBuf, 0, sizeof(charBuf));
  313.         sprintf(charBuf, "PERIPHERAL:JOURNALPRINTER: portVal=%#x, Sensor=%d, Motor=%d\n", portVal, (portVal & 0x04) >> 2, portVal & 0x01);
  314.         debug_log(charBuf, DEBUG_LOG);
  315.         portValPrev = portVal;
  316.     }
  317.     portVal = JP_SENSOR_VALUE(portVal);
  318.  
  319.     return portVal;
  320. }
  321.  
  322. void jp_rewindMotorCtrl(uint8_t option)
  323. {
  324.     uint8_t portVal = 0;
  325.  
  326.     portVal = par_pinStatus(JP_MOTOR_PORT_ADDR);
  327.     if(option == JP_MOTOR_START)
  328.         portVal |= JP_MOTOR_CTRL_BIT;
  329.     else if(option == JP_MOTOR_STOP)
  330.         portVal &= ~JP_MOTOR_CTRL_BIT;
  331.     par_pinWrite(portVal, JP_MOTOR_PORT_ADDR);
  332.  
  333. }
  334.  
  335. int main(int argc,char *argv[])
  336. {
  337.     unsigned int jpSensorValue = 0;
  338.     int type = atoi(argv[1]);
  339.     char debugBuf[1024] = {'\0'};
  340.  
  341.     int parallelFd = ppi_open("/dev/parport0");
  342.  
  343.     printf("Type: %d", type);
  344.  
  345.     jp_rewindMotorCtrl(type);
  346.  
  347.     jpSensorValue = jp_readSensorVal();
  348.     if(jpSensorValue == JP_SENSOR_CLEAR)
  349.     {
  350.         memset(debugBuf,0,sizeof(debugBuf));
  351.         sprintf(debugBuf,"SYSTEM: JP Sensor Clear: %d", jpSensorValue);
  352.         debug_log(debugBuf,TRACE_LOG); 
  353.     }
  354.     else
  355.     {
  356.         memset(debugBuf,0,sizeof(debugBuf));
  357.         sprintf(debugBuf,"SYSTEM: JP Sensor Block: %d", jpSensorValue);
  358.         debug_log(debugBuf,TRACE_LOG); 
  359.     }
  360.  
  361.     printf("\n");
  362.    
  363.     ppi_close(parallelFd);
  364.  
  365.     return 0;
  366. }
Add Comment
Please, Sign In to add comment