mirror of https://github.com/wb2osz/direwolf.git
				
				
				
			Merge 9b36294efa into b14f1d0ff2
				
					
				
			This commit is contained in:
		
						commit
						751e052674
					
				
							
								
								
									
										6
									
								
								audio.h
								
								
								
								
							
							
						
						
									
										6
									
								
								audio.h
								
								
								
								
							| 
						 | 
					@ -198,6 +198,12 @@ struct audio_s {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    } octrl[NUM_OCTYPES];
 | 
						    } octrl[NUM_OCTYPES];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    struct {
 | 
				
			||||||
 | 
						    	int enabled;
 | 
				
			||||||
 | 
						    	int gpio;
 | 
				
			||||||
 | 
							int invert;
 | 
				
			||||||
 | 
						    } txinh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Transmit timing. */
 | 
						/* Transmit timing. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    int dwait;			/* First wait extra time for receiver squelch. */
 | 
						    int dwait;			/* First wait extra time for receiver squelch. */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										24
									
								
								config.c
								
								
								
								
							
							
						
						
									
										24
									
								
								config.c
								
								
								
								
							| 
						 | 
					@ -1450,6 +1450,30 @@ void config_init (char *fname, struct audio_s *p_audio_config,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  }  /* end of PTT */
 | 
						  }  /* end of PTT */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * TXINH		- Input for TX inhibit signal
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  else if (strcasecmp(t, "TXINH") == 0) {
 | 
				
			||||||
 | 
						    t = strtok (NULL, " ,\t\n\r");
 | 
				
			||||||
 | 
						    if (t == NULL) {
 | 
				
			||||||
 | 
						      text_color_set(DW_COLOR_ERROR);
 | 
				
			||||||
 | 
						      dw_printf ("Config file line %d: Missing GPIO number for TXINH.\n",
 | 
				
			||||||
 | 
							    line);
 | 
				
			||||||
 | 
						      continue;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						    
 | 
				
			||||||
 | 
						    p_audio_config->achan[channel].txinh.enabled = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    if (*t == '-') {
 | 
				
			||||||
 | 
						      p_audio_config->achan[channel].txinh.gpio = atoi(t+1);
 | 
				
			||||||
 | 
						      p_audio_config->achan[channel].txinh.invert = 1;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						    else {
 | 
				
			||||||
 | 
						      p_audio_config->achan[channel].txinh.gpio = atoi(t);
 | 
				
			||||||
 | 
						      p_audio_config->achan[channel].txinh.invert = 0;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						  }  /* end of TXINH */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * DWAIT 		- Extra delay for receiver squelch.
 | 
					 * DWAIT 		- Extra delay for receiver squelch.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										49
									
								
								hdlc_rec.c
								
								
								
								
							
							
						
						
									
										49
									
								
								hdlc_rec.c
								
								
								
								
							| 
						 | 
					@ -42,6 +42,15 @@
 | 
				
			||||||
#include "demod_9600.h"		/* for descramble() */
 | 
					#include "demod_9600.h"		/* for descramble() */
 | 
				
			||||||
#include "ptt.h"
 | 
					#include "ptt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if __WIN32__
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//#define TEST 1				/* Define for unit testing. */
 | 
					//#define TEST 1				/* Define for unit testing. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -125,6 +134,8 @@ static void dcd_change (int chan, int subchan, int state);
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 ***********************************************************************************/
 | 
					 ***********************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct audio_s *save_audio_config_p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int was_init = 0;
 | 
					static int was_init = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hdlc_rec_init (struct audio_s *pa)
 | 
					void hdlc_rec_init (struct audio_s *pa)
 | 
				
			||||||
| 
						 | 
					@ -137,6 +148,8 @@ void hdlc_rec_init (struct audio_s *pa)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert (pa != NULL);
 | 
						assert (pa != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						save_audio_config_p = pa;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	for (j=0; j<MAX_CHANS; j++)
 | 
						for (j=0; j<MAX_CHANS; j++)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	  composite_dcd[j] = 0;
 | 
						  composite_dcd[j] = 0;
 | 
				
			||||||
| 
						 | 
					@ -632,10 +645,44 @@ static void dcd_change (int chan, int subchan, int state)
 | 
				
			||||||
int hdlc_rec_data_detect_any (int chan)
 | 
					int hdlc_rec_data_detect_any (int chan)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int subchan;
 | 
						int subchan;
 | 
				
			||||||
 | 
						int busy = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert (chan >= 0 && chan < MAX_CHANS);
 | 
						assert (chan >= 0 && chan < MAX_CHANS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (composite_dcd[chan] != 0);
 | 
						if (composite_dcd[chan] != 0) busy = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if __WIN32__
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (save_audio_config_p->achan[chan].txinh.enabled) {
 | 
				
			||||||
 | 
						  int fd;
 | 
				
			||||||
 | 
						  char stemp[80];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  sprintf (stemp, "/sys/class/gpio/gpio%d/value", save_audio_config_p->achan[chan].txinh.gpio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  fd = open(stemp, O_RDONLY);
 | 
				
			||||||
 | 
						  if (fd < 0) {
 | 
				
			||||||
 | 
						    int e = errno;
 | 
				
			||||||
 | 
						    text_color_set(DW_COLOR_ERROR);
 | 
				
			||||||
 | 
						    dw_printf ("Error opening %s to check TXINH.\n", stemp);
 | 
				
			||||||
 | 
						    dw_printf ("%s\n", strerror(e));
 | 
				
			||||||
 | 
						    return (busy != 1);
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  char vtemp[2];
 | 
				
			||||||
 | 
						  if (read (fd, vtemp, 1) != 1) {
 | 
				
			||||||
 | 
						    int e = errno;
 | 
				
			||||||
 | 
						    text_color_set(DW_COLOR_ERROR);
 | 
				
			||||||
 | 
						    dw_printf ("Error getting GPIO %d value for TXINH\n", save_audio_config_p->achan[chan].txinh.gpio);
 | 
				
			||||||
 | 
						    dw_printf ("%s\n", strerror(e));
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
						  close (fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  if (atoi(vtemp) != save_audio_config_p->achan[chan].txinh.invert) busy = 1; 
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (busy != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} /* end hdlc_rec_data_detect_any */
 | 
					} /* end hdlc_rec_data_detect_any */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										190
									
								
								ptt.c
								
								
								
								
							
							
						
						
									
										190
									
								
								ptt.c
								
								
								
								
							| 
						 | 
					@ -155,6 +155,102 @@ static HANDLE ptt_fd[MAX_CHANS][NUM_OCTYPES];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char otnames[NUM_OCTYPES][8];
 | 
					static char otnames[NUM_OCTYPES][8];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void export_gpio(int gpio, int invert, int direction)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						HANDLE fd;
 | 
				
			||||||
 | 
						char stemp[80];
 | 
				
			||||||
 | 
						struct stat finfo;
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fd = open("/sys/class/gpio/export", O_WRONLY);
 | 
				
			||||||
 | 
						if (fd < 0) {
 | 
				
			||||||
 | 
						  text_color_set(DW_COLOR_ERROR);
 | 
				
			||||||
 | 
						  dw_printf ("Permissions do not allow ordinary users to access GPIO.\n");
 | 
				
			||||||
 | 
						  dw_printf ("Log in as root and type this command:\n");
 | 
				
			||||||
 | 
						  dw_printf ("    chmod go+w /sys/class/gpio/export /sys/class/gpio/unexport\n");
 | 
				
			||||||
 | 
						  exit (1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sprintf (stemp, "%d", gpio);
 | 
				
			||||||
 | 
						if (write (fd, stemp, strlen(stemp)) != strlen(stemp)) {
 | 
				
			||||||
 | 
						  int e = errno;
 | 
				
			||||||
 | 
						  /* Ignore EBUSY error which seems to mean */
 | 
				
			||||||
 | 
						  /* the device node already exists. */
 | 
				
			||||||
 | 
						  if (e != EBUSY) {
 | 
				
			||||||
 | 
						    text_color_set(DW_COLOR_ERROR);
 | 
				
			||||||
 | 
						    dw_printf ("Error writing \"%s\" to /sys/class/gpio/export, errno=%d\n", stemp, e);
 | 
				
			||||||
 | 
						    dw_printf ("%s\n", strerror(e));
 | 
				
			||||||
 | 
						    exit (1);
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						close (fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * We will have the same permission problem if not root.
 | 
				
			||||||
 | 
					 * We only care about "direction" and "value".
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
						sprintf (stemp, "sudo chmod go+rw /sys/class/gpio/gpio%d/direction", gpio);
 | 
				
			||||||
 | 
						err = system (stemp);
 | 
				
			||||||
 | 
						sprintf (stemp, "sudo chmod go+rw /sys/class/gpio/gpio%d/value", gpio);
 | 
				
			||||||
 | 
						err = system (stemp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sprintf (stemp, "/sys/class/gpio/gpio%d/value", gpio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (stat(stemp, &finfo) < 0) {
 | 
				
			||||||
 | 
						  int e = errno;
 | 
				
			||||||
 | 
						  text_color_set(DW_COLOR_ERROR);
 | 
				
			||||||
 | 
						  dw_printf ("Failed to get status for %s \n", stemp);
 | 
				
			||||||
 | 
						  dw_printf ("%s\n", strerror(e));
 | 
				
			||||||
 | 
						  exit (1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (geteuid() != 0) {
 | 
				
			||||||
 | 
						  if ( ! (finfo.st_mode & S_IWOTH)) {
 | 
				
			||||||
 | 
						    text_color_set(DW_COLOR_ERROR);
 | 
				
			||||||
 | 
						    dw_printf ("Permissions do not allow ordinary users to access GPIO.\n");
 | 
				
			||||||
 | 
						    dw_printf ("Log in as root and type these commands:\n");
 | 
				
			||||||
 | 
						    dw_printf ("    chmod go+rw /sys/class/gpio/gpio%d/direction", gpio);
 | 
				
			||||||
 | 
						    dw_printf ("    chmod go+rw /sys/class/gpio/gpio%d/value", gpio);
 | 
				
			||||||
 | 
						    exit (1);
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Set direction and initial value.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sprintf (stemp, "/sys/class/gpio/gpio%d/direction", gpio);
 | 
				
			||||||
 | 
						fd = open(stemp, O_WRONLY);
 | 
				
			||||||
 | 
						if (fd < 0) {
 | 
				
			||||||
 | 
						  int e = errno;
 | 
				
			||||||
 | 
						  text_color_set(DW_COLOR_ERROR);
 | 
				
			||||||
 | 
						  dw_printf ("Error opening %s\n", stemp);
 | 
				
			||||||
 | 
						  dw_printf ("%s\n", strerror(e));
 | 
				
			||||||
 | 
						  exit (1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char gpio_val[8];
 | 
				
			||||||
 | 
						if (direction) {
 | 
				
			||||||
 | 
						  if (invert) {
 | 
				
			||||||
 | 
						    strcpy (gpio_val, "high");
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
						  else {
 | 
				
			||||||
 | 
						    strcpy (gpio_val, "low");
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
						  strcpy (gpio_val, "in");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (write (fd, gpio_val, strlen(gpio_val)) != strlen(gpio_val)) {
 | 
				
			||||||
 | 
						  int e = errno;
 | 
				
			||||||
 | 
						  text_color_set(DW_COLOR_ERROR);
 | 
				
			||||||
 | 
						  dw_printf ("Error writing direction to %s\n", stemp);
 | 
				
			||||||
 | 
						  dw_printf ("%s\n", strerror(e));
 | 
				
			||||||
 | 
						  exit (1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						close (fd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ptt_init (struct audio_s *audio_config_p)
 | 
					void ptt_init (struct audio_s *audio_config_p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ch;
 | 
						int ch;
 | 
				
			||||||
| 
						 | 
					@ -326,6 +422,7 @@ void ptt_init (struct audio_s *audio_config_p)
 | 
				
			||||||
	        using_gpio = 1;
 | 
						        using_gpio = 1;
 | 
				
			||||||
	      }
 | 
						      }
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
						    if (audio_config_p->achan[ch].txinh.enabled) using_gpio = 1;
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -343,7 +440,7 @@ void ptt_init (struct audio_s *audio_config_p)
 | 
				
			||||||
	  if (stat("/sys/class/gpio/export", &finfo) < 0) {
 | 
						  if (stat("/sys/class/gpio/export", &finfo) < 0) {
 | 
				
			||||||
	    text_color_set(DW_COLOR_ERROR);
 | 
						    text_color_set(DW_COLOR_ERROR);
 | 
				
			||||||
	    dw_printf ("This system is not configured with the GPIO user interface.\n");
 | 
						    dw_printf ("This system is not configured with the GPIO user interface.\n");
 | 
				
			||||||
	    dw_printf ("Use a different method for PTT control.\n");
 | 
						    dw_printf ("Use a different method for PTT, DCD, or TXINH control.\n");
 | 
				
			||||||
	    exit (1);
 | 
						    exit (1);
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -367,7 +464,7 @@ void ptt_init (struct audio_s *audio_config_p)
 | 
				
			||||||
	        /* Unexpected because we could do it before. */
 | 
						        /* Unexpected because we could do it before. */
 | 
				
			||||||
	        text_color_set(DW_COLOR_ERROR);
 | 
						        text_color_set(DW_COLOR_ERROR);
 | 
				
			||||||
	        dw_printf ("This system is not configured with the GPIO user interface.\n");
 | 
						        dw_printf ("This system is not configured with the GPIO user interface.\n");
 | 
				
			||||||
	        dw_printf ("Use a different method for PTT control.\n");
 | 
						        dw_printf ("Use a different method for PTT, DCD, or TXINH control.\n");
 | 
				
			||||||
	        exit (1);
 | 
						        exit (1);
 | 
				
			||||||
	      }
 | 
						      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -392,93 +489,12 @@ void ptt_init (struct audio_s *audio_config_p)
 | 
				
			||||||
	    int ot;
 | 
						    int ot;
 | 
				
			||||||
	    for (ot = 0; ot < NUM_OCTYPES; ot++) {
 | 
						    for (ot = 0; ot < NUM_OCTYPES; ot++) {
 | 
				
			||||||
	      if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_GPIO) {
 | 
						      if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_GPIO) {
 | 
				
			||||||
	        char stemp[80];
 | 
						        export_gpio(audio_config_p->achan[ch].octrl[ot].ptt_gpio, audio_config_p->achan[ch].octrl[ot].ptt_invert, 1);
 | 
				
			||||||
	        struct stat finfo;
 | 
					 | 
				
			||||||
	        int err;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	        fd = open("/sys/class/gpio/export", O_WRONLY);
 | 
					 | 
				
			||||||
	        if (fd < 0) {
 | 
					 | 
				
			||||||
	          text_color_set(DW_COLOR_ERROR);
 | 
					 | 
				
			||||||
	          dw_printf ("Permissions do not allow ordinary users to access GPIO.\n");
 | 
					 | 
				
			||||||
	          dw_printf ("Log in as root and type this command:\n");
 | 
					 | 
				
			||||||
	          dw_printf ("    chmod go+w /sys/class/gpio/export /sys/class/gpio/unexport\n");
 | 
					 | 
				
			||||||
	          exit (1);
 | 
					 | 
				
			||||||
	        }
 | 
					 | 
				
			||||||
	        sprintf (stemp, "%d", audio_config_p->achan[ch].octrl[ot].ptt_gpio);
 | 
					 | 
				
			||||||
	        if (write (fd, stemp, strlen(stemp)) != strlen(stemp)) {
 | 
					 | 
				
			||||||
	          int e = errno;
 | 
					 | 
				
			||||||
	          /* Ignore EBUSY error which seems to mean */
 | 
					 | 
				
			||||||
	          /* the device node already exists. */
 | 
					 | 
				
			||||||
	          if (e != EBUSY) {
 | 
					 | 
				
			||||||
	            text_color_set(DW_COLOR_ERROR);
 | 
					 | 
				
			||||||
	            dw_printf ("Error writing \"%s\" to /sys/class/gpio/export, errno=%d\n", stemp, e);
 | 
					 | 
				
			||||||
	            dw_printf ("%s\n", strerror(e));
 | 
					 | 
				
			||||||
	            exit (1);
 | 
					 | 
				
			||||||
	          }
 | 
					 | 
				
			||||||
	        }
 | 
					 | 
				
			||||||
	        close (fd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * We will have the same permission problem if not root.
 | 
					 | 
				
			||||||
 * We only care about "direction" and "value".
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
	        sprintf (stemp, "sudo chmod go+rw /sys/class/gpio/gpio%d/direction", audio_config_p->achan[ch].octrl[ot].ptt_gpio);
 | 
					 | 
				
			||||||
	        err = system (stemp);
 | 
					 | 
				
			||||||
	        sprintf (stemp, "sudo chmod go+rw /sys/class/gpio/gpio%d/value", audio_config_p->achan[ch].octrl[ot].ptt_gpio);
 | 
					 | 
				
			||||||
	        err = system (stemp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	        sprintf (stemp, "/sys/class/gpio/gpio%d/value", audio_config_p->achan[ch].octrl[ot].ptt_gpio);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	        if (stat(stemp, &finfo) < 0) {
 | 
					 | 
				
			||||||
	          int e = errno;
 | 
					 | 
				
			||||||
	          text_color_set(DW_COLOR_ERROR);
 | 
					 | 
				
			||||||
	          dw_printf ("Failed to get status for %s \n", stemp);
 | 
					 | 
				
			||||||
	          dw_printf ("%s\n", strerror(e));
 | 
					 | 
				
			||||||
	          exit (1);
 | 
					 | 
				
			||||||
	        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	        if (geteuid() != 0) {
 | 
					 | 
				
			||||||
	          if ( ! (finfo.st_mode & S_IWOTH)) {
 | 
					 | 
				
			||||||
	            text_color_set(DW_COLOR_ERROR);
 | 
					 | 
				
			||||||
	            dw_printf ("Permissions do not allow ordinary users to access GPIO.\n");
 | 
					 | 
				
			||||||
	            dw_printf ("Log in as root and type these commands:\n");
 | 
					 | 
				
			||||||
	            dw_printf ("    chmod go+rw /sys/class/gpio/gpio%d/direction", audio_config_p->achan[ch].octrl[ot].ptt_gpio);
 | 
					 | 
				
			||||||
	            dw_printf ("    chmod go+rw /sys/class/gpio/gpio%d/value", audio_config_p->achan[ch].octrl[ot].ptt_gpio);
 | 
					 | 
				
			||||||
	            exit (1);
 | 
					 | 
				
			||||||
	          }
 | 
					 | 
				
			||||||
	        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Set output direction with initial state off.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	        sprintf (stemp, "/sys/class/gpio/gpio%d/direction", audio_config_p->achan[ch].octrl[ot].ptt_gpio);
 | 
					 | 
				
			||||||
	        fd = open(stemp, O_WRONLY);
 | 
					 | 
				
			||||||
	        if (fd < 0) {
 | 
					 | 
				
			||||||
	          int e = errno;
 | 
					 | 
				
			||||||
	          text_color_set(DW_COLOR_ERROR);
 | 
					 | 
				
			||||||
	          dw_printf ("Error opening %s\n", stemp);
 | 
					 | 
				
			||||||
	          dw_printf ("%s\n", strerror(e));
 | 
					 | 
				
			||||||
	          exit (1);
 | 
					 | 
				
			||||||
	        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	        char hilo[8];
 | 
					 | 
				
			||||||
	        if (audio_config_p->achan[ch].octrl[ot].ptt_invert) {
 | 
					 | 
				
			||||||
	          strcpy (hilo, "high");
 | 
					 | 
				
			||||||
	        }
 | 
					 | 
				
			||||||
	        else {
 | 
					 | 
				
			||||||
	          strcpy (hilo, "low");
 | 
					 | 
				
			||||||
	        }
 | 
					 | 
				
			||||||
	        if (write (fd, hilo, strlen(hilo)) != strlen(hilo)) {
 | 
					 | 
				
			||||||
	          int e = errno;
 | 
					 | 
				
			||||||
	          text_color_set(DW_COLOR_ERROR);
 | 
					 | 
				
			||||||
	          dw_printf ("Error writing initial state to %s\n", stemp);
 | 
					 | 
				
			||||||
	          dw_printf ("%s\n", strerror(e));
 | 
					 | 
				
			||||||
	          exit (1);
 | 
					 | 
				
			||||||
	        }
 | 
					 | 
				
			||||||
	        close (fd);
 | 
					 | 
				
			||||||
	      }
 | 
						      }
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
						    if (audio_config_p->achan[ch].txinh.enabled) {
 | 
				
			||||||
 | 
						      export_gpio(audio_config_p->achan[ch].txinh.gpio, audio_config_p->achan[ch].txinh.invert, 0);
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										18
									
								
								textcolor.c
								
								
								
								
							
							
						
						
									
										18
									
								
								textcolor.c
								
								
								
								
							| 
						 | 
					@ -111,19 +111,19 @@ static const char clear_eos[]	= "\e[0J";
 | 
				
			||||||
/* expected bright/bold (1) to get bright white background. */
 | 
					/* expected bright/bold (1) to get bright white background. */
 | 
				
			||||||
/* Makes no sense but I stumbled across that somewhere. */
 | 
					/* Makes no sense but I stumbled across that somewhere. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char background_white[] = "\e[5;47m";
 | 
					static const char background_white[] = "\e[49m";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Whenever a dark color is used, the */
 | 
					/* Whenever a dark color is used, the */
 | 
				
			||||||
/* background is reset and needs to be set again. */
 | 
					/* background is reset and needs to be set again. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char black[]	= "\e[0;30m" "\e[5;47m";
 | 
					static const char black[]	= "\e[0;39m" "\e[49m";
 | 
				
			||||||
static const char red[] 	= "\e[1;31m" "\e[5;47m";
 | 
					static const char red[] 	= "\e[1;31m" "\e[49m";
 | 
				
			||||||
static const char green[] 	= "\e[1;32m" "\e[5;47m";
 | 
					static const char green[] 	= "\e[1;32m" "\e[49m";
 | 
				
			||||||
static const char yellow[] 	= "\e[1;33m" "\e[5;47m";
 | 
					static const char yellow[] 	= "\e[1;33m" "\e[49m";
 | 
				
			||||||
static const char blue[] 	= "\e[1;34m" "\e[5;47m";
 | 
					static const char blue[] 	= "\e[1;34m" "\e[49m";
 | 
				
			||||||
static const char magenta[] 	= "\e[1;35m" "\e[5;47m";
 | 
					static const char magenta[] 	= "\e[1;35m" "\e[49m";
 | 
				
			||||||
static const char cyan[] 	= "\e[1;36m" "\e[5;47m";
 | 
					static const char cyan[] 	= "\e[1;36m" "\e[49m";
 | 
				
			||||||
static const char dark_green[]	= "\e[0;32m" "\e[5;47m";
 | 
					static const char dark_green[]	= "\e[0;32m" "\e[49m";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Clear from cursor to end of screen. */
 | 
					/* Clear from cursor to end of screen. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue