소스 검색

Merged from git.drogon.net, SPI driver helpers, C++ wrappers, softPwm, piNes, gertboard, SPI

pull/1/head
Gordon Henderson 12 년 전
committed by Philip Howard
부모
커밋
ae40bdaf6a
22개의 변경된 파일1703개의 추가작업 그리고 274개의 파일을 삭제
  1. +21
    -4
      examples/Makefile
  2. +68
    -0
      examples/delayTest.c
  3. +77
    -0
      examples/gertboard.c
  4. BIN
      examples/gertboard.png
  5. +44
    -0
      examples/nes.c
  6. +69
    -0
      examples/softPwm.c
  7. +1
    -1
      gpio/Makefile
  8. +83
    -19
      gpio/gpio.1
  9. +360
    -90
      gpio/gpio.c
  10. +122
    -0
      wiringPi/gertboard.c
  11. +39
    -0
      wiringPi/gertboard.h
  12. +8
    -0
      wiringPi/lcd.h
  13. +113
    -0
      wiringPi/piNes.c
  14. +45
    -0
      wiringPi/piNes.h
  15. +130
    -0
      wiringPi/softPwm.c
  16. +34
    -0
      wiringPi/softPwm.h
  17. +296
    -135
      wiringPi/wiringPi.c
  18. +15
    -6
      wiringPi/wiringPi.h
  19. +117
    -0
      wiringPi/wiringPiSPI.c
  20. +35
    -0
      wiringPi/wiringPiSPI.h
  21. +25
    -19
      wiringPi/wiringSerial.c
  22. +1
    -0
      wiringPi/wiringSerial.h

+ 21
- 4
examples/Makefile 파일 보기

@@ -35,11 +35,11 @@ LIBS = -lwiringPi
# Should not alter anything below this line
###############################################################################

SRC = test1.c test2.c speed.c lcd.c wfi.c piface.c
SRC = test1.c test2.c speed.c lcd.c wfi.c piface.c gertboard.c nes.c delayTest.c softPwm.c

OBJ = test1.o test2.o speed.o lcd.o wfi.o piface.o
OBJ = test1.o test2.o speed.o lcd.o wfi.o piface.o gertboard.o nes.o delayTest.o softPwm.o

all: test1 test2 speed lcd wfi piface
all: test1 test2 speed lcd wfi piface gertboard nes softPwm

test1: test1.o
@echo [link]
@@ -65,13 +65,30 @@ piface: piface.o
@echo [link]
$(CC) -o $@ piface.o $(LDFLAGS) $(LIBS) -lpthread

gertboard: gertboard.o
@echo [link]
$(CC) -o $@ gertboard.o $(LDFLAGS) $(LIBS) -lm

nes: nes.o
@echo [link]
$(CC) -o $@ nes.o $(LDFLAGS) $(LIBS) -lm

softPwm: softPwm.o
@echo [link]
$(CC) -o $@ softPwm.o $(LDFLAGS) $(LIBS) -lm -lpthread


delayTest: delayTest.o
@echo [link]
$(CC) -o $@ delayTest.o $(LDFLAGS) $(LIBS)


.c.o:
@echo [CC] $<
@$(CC) -c $(CFLAGS) $< -o $@

clean:
rm -f $(OBJ) *~ core tags test1 test2 speed lcd wfi piface
rm -f $(OBJ) *~ core tags test1 test2 speed lcd wfi piface gertboard nes delayTest softPwm

tags: $(SRC)
@echo [ctags]


+ 68
- 0
examples/delayTest.c 파일 보기

@@ -0,0 +1,68 @@

#include <stdio.h>
#include <unistd.h>
#include <wiringPi.h>

#include <time.h>
#include <sys/types.h>
#include <sys/time.h>

#define CYCLES 1000
#define DELAY 99

int main()
{
int x ;
struct timeval t1, t2 ;
long long t ;
unsigned int max, min ;

unsigned int values [CYCLES] ;

max = 0 ;
min = 1000000 ;

if (wiringPiSetup () == -1)
return 1 ;

piHiPri (10) ;
sleep (1) ;

// Baseline test

gettimeofday (&t1, NULL) ;
gettimeofday (&t2, NULL) ;

t = t2.tv_usec - t1.tv_usec ;
printf ("Baseline test: %lld\n", t);

for (x = 0 ; x < CYCLES ; ++x)
{
gettimeofday (&t1, NULL) ;
delayMicroseconds (DELAY) ;
gettimeofday (&t2, NULL) ;
t = t2.tv_usec - t1.tv_usec ;
if (t > max) max = t ;
if (t < min) min = t ;
values [x] = t ;
}

printf ("Done: Max: %d, min: %d\n", max, min) ;

for (x = 0 ; x < CYCLES ; ++x)
{
printf ("%4d", values [x]) ;
if (values [x] > DELAY)
printf (".") ;
else if (values [x] < DELAY)
printf ("-") ;
else
printf (" ") ;
if (((x + 1) % 20) == 0)
printf ("\n") ;
}
printf ("\n") ;

return 0 ;
}

+ 77
- 0
examples/gertboard.c 파일 보기

@@ -0,0 +1,77 @@

/*
* gertboard.c:
* Simple test for the SPI bus on the Gertboard
*
* Hardware setup:
* D/A port 0 jumpered to A/D port 0.
*
* We output a sine wave on D/A port 0 and sample A/D port 0. We then
* copy this value to D/A port 1 and use a 'scope on both D/A ports
* to check all's well.
*
*/

#include <stdio.h>
#include <stdint.h>
#include <math.h>

#define B_SIZE 200
#undef DO_TIMING

#include <wiringPi.h>
#include <gertboard.h>

int main (void)
{
double angle ;
int i ;
uint32_t x1 ;
int buffer [B_SIZE] ;

#ifdef DO_TIMING
unsigned int now, then ;
#endif

printf ("Raspberry Pi Gertboard SPI test program\n") ;

if (wiringPiSetupSys () < 0)
return -1 ;

if (gertboardSPISetup () < 0)
return 1 ;

// Generate a Sine Wave

for (i = 0 ; i < B_SIZE ; ++i)
{
angle = ((double)i / (double)B_SIZE) * M_PI * 2.0 ;
buffer [i] = (int)rint ((sin (angle)) * 127.0 + 128.0) ;
}


for (;;)
{
#ifdef DO_TIMING
then = millis () ;
#endif

for (i = 0 ; i < B_SIZE ; ++i)
{
gertboardAnalogWrite (0, buffer [i]) ;

#ifndef DO_TIMING
x1 = gertboardAnalogRead (0) ;
gertboardAnalogWrite (1, x1 >> 2) ; // 10-bit A/D, 8-bit D/A
#endif
}

#ifdef DO_TIMING
now = millis () ;
printf ("%4d mS, %9.7f S/sample", now - then, ((double)(now - then) / 1000.0) / (double)B_SIZE) ;
printf (" -> %9.4f samples/sec \n", 1 / (((double)(now - then) / 1000.0) / (double)B_SIZE)) ;
#endif
}

return 0 ;
}

BIN
examples/gertboard.png 파일 보기

Before After
Width: 400  |  Height: 240  |  Size: 4.7 KiB

+ 44
- 0
examples/nes.c 파일 보기

@@ -0,0 +1,44 @@

#include <stdio.h>
#include <errno.h>
#include <string.h>

#include <wiringPi.h>
#include <piNes.h>

#define BLANK "| "

int main ()
{
int joystick ;
unsigned int buttons ;

if (wiringPiSetup () == -1)
{
fprintf (stdout, "oops: %s\n", strerror (errno)) ;
return 1 ;
}

if ((joystick = setupNesJoystick (2, 1, 0)) == -1)
{
fprintf (stdout, "Unable to setup joystick\n") ;
return 1 ;
}

for (;;)
{
buttons = readNesJoystick (joystick) ;

if ((buttons & NES_UP) != 0) printf ("| UP " ) ; else printf (BLANK) ;
if ((buttons & NES_DOWN) != 0) printf ("| DOWN " ) ; else printf (BLANK) ;
if ((buttons & NES_LEFT) != 0) printf ("| LEFT " ) ; else printf (BLANK) ;
if ((buttons & NES_RIGHT) != 0) printf ("|RIGHT " ) ; else printf (BLANK) ;
if ((buttons & NES_SELECT) != 0) printf ("|SELECT" ) ; else printf (BLANK) ;
if ((buttons & NES_START) != 0) printf ("|START " ) ; else printf (BLANK) ;
if ((buttons & NES_A) != 0) printf ("| A " ) ; else printf (BLANK) ;
if ((buttons & NES_B) != 0) printf ("| B " ) ; else printf (BLANK) ;
printf ("|\n") ;
}

return 0 ;
}

+ 69
- 0
examples/softPwm.c 파일 보기

@@ -0,0 +1,69 @@

#include <stdio.h>
#include <errno.h>
#include <string.h>

#include <wiringPi.h>
#include <softPwm.h>

#define RANGE 100
#define NUM_LEDS 12

int ledMap [NUM_LEDS] = { 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13 } ;

int values [NUM_LEDS] = { 0, 17, 32, 50, 67, 85, 100, 85, 67, 50, 32, 17 } ;

int main ()
{
int i, j ;
char buf [80] ;

if (wiringPiSetup () == -1)
{
fprintf (stdout, "oops: %s\n", strerror (errno)) ;
return 1 ;
}

for (i = 0 ; i < NUM_LEDS ; ++i)
{
softPwmCreate (ledMap [i], 0, RANGE) ;
printf ("%3d, %3d, %3d\n", i, ledMap [i], values [i]) ;
}

fgets (buf, 80, stdin) ;

// Bring all up one by one:

for (i = 0 ; i < NUM_LEDS ; ++i)
for (j = 0 ; j <= 100 ; ++j)
{
softPwmWrite (ledMap [i], j) ;
delay (10) ;
}

fgets (buf, 80, stdin) ;

// Down fast

for (i = 100 ; i > 0 ; --i)
{
for (j = 0 ; j < NUM_LEDS ; ++j)
softPwmWrite (ledMap [j], i) ;
delay (10) ;
}

fgets (buf, 80, stdin) ;

for (;;)
{
for (i = 0 ; i < NUM_LEDS ; ++i)
softPwmWrite (ledMap [i], values [i]) ;

delay (50) ;

i = values [0] ;
for (j = 0 ; j < NUM_LEDS - 1 ; ++j)
values [j] = values [j + 1] ;
values [NUM_LEDS - 1] = i ;
}
}

+ 1
- 1
gpio/Makefile 파일 보기

@@ -41,7 +41,7 @@ OBJ = gpio.o

all: gpio

gpio: gpio.o
gpio: gpio.o /usr/local/lib/libwiringPi.a
@echo [LD]
@$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS)


+ 83
- 19
gpio/gpio.1 파일 보기

@@ -4,28 +4,55 @@
gpio \- Command-line access to Raspberry Pi and PiFace GPIO

.SH SYNOPSIS
.TP
.B gpio
.RB [ \-v ]
.TP
.B \-v
.PP
.B gpio
.RB [ \-g ]
.RB < read/write/pwm/mode ...>
.TP
.B [ \-g ]
.B read/write/pwm/mode ...
.PP
.B gpio
.RB [ \-p ]
.RB < read/write/mode ...>
.TP
.B [ \-p ]
.B read/write/mode
.B ...
.PP
.B gpio
.B unexportall/exports
.PP
.B gpio
.B export/edge/unexport
.B ...
.PP
.B gpio
.RB < export/edge/unexport/unexportall/exports ...>
.B drive
group value
.PP
.B gpio
.B pwm-bal/pwm-ms
.PP
.B gpio
.B pwmr
range
.PP
.B gpio
.B load \ i2c/spi
.PP
.B gpio
.B gbr
channel
.PP
.B gpio
.B gbw
channel value

.SH DESCRIPTION

.B GPIO
is a command line tool to allow the user easy access to the GPIO pins
on the Raspberry Pi. It's designed for simple testing and diagnostic
purposes, but can be used in shell scripts for general if somewhat slow
control of the GPIO pins.
is a swiss army knofe of a command line tool to allow the user easy
access to the GPIO pins on the Raspberry Pi and the SPI A/D and D/A
convertors on the Gertboard. It's designed for simple testing and
diagnostic purposes, but can be used in shell scripts for general if
somewhat slow control of the GPIO pins.

Additionally, it can be used to set the exports in the \fI/sys/class/gpio\fR
system directory to allow subsequent programs to use the \fR/sys/class/gpio\fR
@@ -65,6 +92,14 @@ use the literals \fIup\fR, \fIdown\fR or \fItri\fR to set the internal
pull-up, pull-down or tristate (off) controls.

.TP
.B unexportall
Un-Export all the GPIO pins in the /sys/class/gpio directory.

.TP
.B exports
Print a list (if any) of all the exported GPIO pins and their current values.

.TP
.B export
Export a GPIO pin in the \fI/sys/class/gpio\fR directory. Use like the
mode command above however only \fIin\fR and \fIout\fR are supported at
@@ -96,12 +131,41 @@ requiring root/sudo.
Un-Export a GPIO pin in the /sys/class/gpio directory.

.TP
.B unexportall
Un-Export all the GPIO pins in the /sys/class/gpio directory.
.B drive
group value

Change the pad driver value for the given pad group to the supplied drive
value. Group is 0, 1 or 2 and value is 0-7. Do not use unless you are
absolutely sure you know what you're doing.

.TP
.B exports
Print a list (if any) of all the exported GPIO pins and their current values.
.B pwm-bal/pwm-ms
Change the PWM mode to balanced (the default) or mark:space ratio (traditional)

.TP
.B pwmr
Change the PWM range register. The default is 1024.

.TP
.B load i2c/spi
This loads the i2c or the spi drivers into the system and changes the permissions on
the associated /dev/ entries so that the current user has access to them.

.TP
.B gbr
channel

This reads the analog to digital convertor on the Gertboard on the given
channel. The board jumpers need to be in-place to do this operation.

.TP
.B gbw
channel value

This writes the supplied value to the output channel on the Gertboards
SPI digital to analogue convertor.
The board jumpers need to be in-place to do this operation.


.SH "WiringPi vs. GPIO Pin numbering"

@@ -170,7 +234,7 @@ Gordon Henderson

.SH "REPORTING BUGS"

Report bugs to <gordon@drogon.net>
Report bugs to <projects@drogon.net>

.SH COPYRIGHT



+ 360
- 90
gpio/gpio.c 파일 보기

@@ -1,6 +1,7 @@
/*
* gpio.c:
* Set-UID command-line interface to the Raspberry Pi's GPIO
* Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
* Pi's GPIO.
* Copyright (c) 2012 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
@@ -21,7 +22,6 @@
***********************************************************************
*/

#include <wiringPi.h>

#include <stdio.h>
#include <stdlib.h>
@@ -32,15 +32,144 @@
#include <sys/types.h>
#include <fcntl.h>

#include <wiringPi.h>
#include <gertboard.h>

#ifndef TRUE
# define TRUE (1==1)
# define FALSE (1==2)
#endif

#define VERSION "1.0"
#define VERSION "1.2"

static int wpMode ;

char *usage = "Usage: gpio -v\n"
" gpio -h\n"
" gpio [-g] <read/write/pwm/mode> ...\n"
" gpio [-p] <read/write/mode> ...\n"
" gpio <export/edge/unexport/unexportall/exports> ..." ;
" gpio export/edge/unexport/unexportall/exports ...\n"
" gpio drive <group> <value>\n"
" gpio pwm-bal/pwm-ms \n"
" gpio pwmr <range> \n"
" gpio load spi/i2c\n"
" gpio gbr <channel>\n"
" gpio gbw <channel> <value>\n" ;


/*
* changeOwner:
* Change the ownership of the file to the real userId of the calling
* program so we can access it.
*********************************************************************************
*/

static void changeOwner (char *cmd, char *file)
{
uid_t uid = getuid () ;
uid_t gid = getgid () ;

if (chown (file, uid, gid) != 0)
{
if (errno == ENOENT) // Warn that it's not there
fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ;
else
{
fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
exit (1) ;
}
}
}


/*
* moduleLoaded:
* Return true/false if the supplied module is loaded
*********************************************************************************
*/

static int moduleLoaded (char *modName)
{
int len = strlen (modName) ;
int found = FALSE ;
FILE *fd = fopen ("/proc/modules", "r") ;
char line [80] ;

if (fd == NULL)
{
fprintf (stderr, "gpio: Unable to check modules: %s\n", strerror (errno)) ;
exit (1) ;
}

while (fgets (line, 80, fd) != NULL)
{
if (strncmp (line, modName, len) != 0)
continue ;

found = TRUE ;
break ;
}

fclose (fd) ;

return found ;
}


/*
* doLoad:
* Load either the spi or i2c modules and change device ownerships, etc.
*********************************************************************************
*/

static void _doLoadUsage (char *argv [])
{
fprintf (stderr, "Usage: %s load <spi/i2c>\n", argv [0]) ;
exit (1) ;
}

static void doLoad (int argc, char *argv [])
{
char *module ;
char cmd [80] ;
char *file1, *file2 ;

if (argc != 3)
_doLoadUsage (argv) ;

/**/ if (strcasecmp (argv [2], "spi") == 0)
{
module = "spi_bcm2708" ;
file1 = "/dev/spidev0.0" ;
file2 = "/dev/spidev0.1" ;
}
else if (strcasecmp (argv [2], "i2c") == 0)
{
module = "i2c_bcm2708" ;
file1 = "/dev/i2c-0" ;
file2 = "/dev/i2c-1" ;
}
else
_doLoadUsage (argv) ;

if (!moduleLoaded (module))
{
sprintf (cmd, "modprobe %s", module) ;
system (cmd) ;
}

if (!moduleLoaded (module))
{
fprintf (stderr, "%s: Unable to load %s\n", argv [0], module) ;
exit (1) ;
}

sleep (1) ; // To let things get settled

changeOwner (argv [0], file1) ;
changeOwner (argv [0], file2) ;
}



/*
@@ -49,7 +178,7 @@ char *usage = "Usage: gpio -v\n"
*********************************************************************************
*/

void doExports (void)
static void doExports (int argc, char *argv [])
{
int fd ;
int i, l, first ;
@@ -140,8 +269,6 @@ void doExport (int argc, char *argv [])
int pin ;
char *mode ;
char fName [128] ;
uid_t uid ;
gid_t gid ;

if (argc != 4)
{
@@ -183,27 +310,11 @@ void doExport (int argc, char *argv [])

// Change ownership so the current user can actually use it!

uid = getuid () ;
gid = getgid () ;

sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
if (chown (fName, uid, gid) != 0)
{
fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ;
exit (1) ;
}

// Also change ownership of the edge file - if it exists
changeOwner (argv [0], fName) ;

sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
if (chown (fName, uid, gid) != 0)
{
if (errno != ENOENT) // Silently ignore File not found - older kernel
{
fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ;
exit (1) ;
}
}
changeOwner (argv [0], fName) ;

}

@@ -222,8 +333,6 @@ void doEdge (int argc, char *argv [])
int pin ;
char *mode ;
char fName [128] ;
uid_t uid ;
gid_t gid ;

if (argc != 4)
{
@@ -231,8 +340,7 @@ void doEdge (int argc, char *argv [])
exit (1) ;
}

pin = atoi (argv [2]) ;

pin = atoi (argv [2]) ;
mode = argv [3] ;

// Export the pin and set direction to input
@@ -263,40 +371,23 @@ void doEdge (int argc, char *argv [])
exit (1) ;
}

/**/ if (strcasecmp (mode, "none") == 0)
fprintf (fd, "none\n") ;
else if (strcasecmp (mode, "rising") == 0)
fprintf (fd, "rising\n") ;
else if (strcasecmp (mode, "falling") == 0)
fprintf (fd, "falling\n") ;
else if (strcasecmp (mode, "both") == 0)
fprintf (fd, "both\n") ;
/**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
else
{
fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
exit (1) ;
}

// Change ownership so the current user can actually use it!

uid = getuid () ;
gid = getgid () ;
// Change ownership of the value and edge files, so the current user can actually use it!

sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
if (chown (fName, uid, gid) != 0)
{
fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ;
exit (1) ;
}

// Also change ownership of the edge file
changeOwner (argv [0], fName) ;

sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
if (chown (fName, uid, gid) != 0)
{
fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ;
exit (1) ;
}
changeOwner (argv [0], fName) ;

fclose (fd) ;
}
@@ -383,18 +474,12 @@ void doMode (int argc, char *argv [])

mode = argv [3] ;

/**/ if (strcasecmp (mode, "in") == 0)
pinMode (pin, INPUT) ;
else if (strcasecmp (mode, "out") == 0)
pinMode (pin, OUTPUT) ;
else if (strcasecmp (mode, "pwm") == 0)
pinMode (pin, PWM_OUTPUT) ;
else if (strcasecmp (mode, "up") == 0)
pullUpDnControl (pin, PUD_UP) ;
else if (strcasecmp (mode, "down") == 0)
pullUpDnControl (pin, PUD_DOWN) ;
else if (strcasecmp (mode, "tri") == 0)
pullUpDnControl (pin, PUD_OFF) ;
/**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
else
{
fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/up/down/tri\n", argv [1], mode) ;
@@ -402,13 +487,125 @@ void doMode (int argc, char *argv [])
}
}


/*
* doPadDrive:
* gpio drive group value
*********************************************************************************
*/

static void doPadDrive (int argc, char *argv [])
{
int group, val ;

if (argc != 4)
{
fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
exit (1) ;
}

group = atoi (argv [2]) ;
val = atoi (argv [3]) ;

if ((group < 0) || (group > 2))
{
fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
exit (1) ;
}

if ((val < 0) || (val > 7))
{
fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
exit (1) ;
}

setPadDrive (group, val) ;
}


/*
* doGbw:
* gpio gbw channel value
*********************************************************************************
*/

static void doGbw (int argc, char *argv [])
{
int channel, value ;

if (argc != 4)
{
fprintf (stderr, "Usage: %s gbr <channel> <value>\n", argv [0]) ;
exit (1) ;
}

channel = atoi (argv [2]) ;
value = atoi (argv [3]) ;

if ((channel < 0) || (channel > 1))
{
fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
exit (1) ;
}

if ((value < 0) || (value > 1023))
{
fprintf (stderr, "%s: value must be from 0 to 255\n", argv [0]) ;
exit (1) ;
}

if (gertboardSPISetup () == -1)
{
fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
exit (1) ;
}

gertboardAnalogWrite (channel, value) ;
}


/*
* doGbr:
* gpio gbr channel
*********************************************************************************
*/

static void doGbr (int argc, char *argv [])
{
int channel ;

if (argc != 3)
{
fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
exit (1) ;
}

channel = atoi (argv [2]) ;

if ((channel < 0) || (channel > 1))
{
fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
exit (1) ;
}

if (gertboardSPISetup () == -1)
{
fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
exit (1) ;
}

printf ("%d\n",gertboardAnalogRead (channel)) ;
}



/*
* doWrite:
* gpio write pin value
*********************************************************************************
*/

void doWrite (int argc, char *argv [])
static void doWrite (int argc, char *argv [])
{
int pin, val ;

@@ -490,6 +687,39 @@ void doPwm (int argc, char *argv [])


/*
* doPwmMode: doPwmRange:
* Change the PWM mode and Range values
*********************************************************************************
*/

static void doPwmMode (int mode)
{
pwmSetMode (mode) ;
}

static void doPwmRange (int argc, char *argv [])
{
unsigned int range ;

if (argc != 3)
{
fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
exit (1) ;
}

range = (unsigned int)strtoul (argv [2], NULL, 10) ;

if (range == 0)
{
fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
exit (1) ;
}

pwmSetRange (range) ;
}


/*
* main:
* Start here
*********************************************************************************
@@ -505,10 +735,10 @@ int main (int argc, char *argv [])
return 1 ;
}

if (geteuid () != 0)
if (strcasecmp (argv [1], "-h") == 0)
{
fprintf (stderr, "%s: Must be root to run\n", argv [0]) ;
return 1 ;
printf ("%s: %s\n", argv [0], usage) ;
return 0 ;
}

if (strcasecmp (argv [1], "-v") == 0)
@@ -516,21 +746,54 @@ int main (int argc, char *argv [])
printf ("gpio version: %s\n", VERSION) ;
printf ("Copyright (c) 2012 Gordon Henderson\n") ;
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
printf ("For details type: %s -warranty\n", argv [0]) ;
return 0 ;
}

if (strcasecmp (argv [1], "-warranty") == 0)
{
printf ("gpio version: %s\n", VERSION) ;
printf ("Copyright (c) 2012 Gordon Henderson\n") ;
printf ("\n") ;
printf (" This program is free software; you can redistribute it and/or modify\n") ;
printf (" it under the terms of the GNU Leser General Public License as published\n") ;
printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
printf (" (at your option) any later version.\n") ;
printf ("\n") ;
printf (" This program is distributed in the hope that it will be useful,\n") ;
printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
printf (" GNU Lesser General Public License for more details.\n") ;
printf ("\n") ;
printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
printf ("\n") ;
return 0 ;
}

if (geteuid () != 0)
{
fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
return 1 ;
}

// Initial test for /sys/class/gpio operations:

/**/ if (strcasecmp (argv [1], "exports" ) == 0)
{ doExports () ; return 0 ; }
else if (strcasecmp (argv [1], "export" ) == 0)
{ doExport (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "edge" ) == 0)
{ doEdge (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "unexportall") == 0)
{ doUnexportall (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "unexport") == 0)
{ doUnexport (argc, argv) ; return 0 ; }
/**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }

// Check for drive or load commands:

if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; }
if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }

// Gertboard commands

if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }

// Check for -g argument

@@ -538,7 +801,7 @@ int main (int argc, char *argv [])
{
if (wiringPiSetupGpio () == -1)
{
fprintf (stderr, "%s: Unable to initialise GPIO in GPIO mode.\n", argv [0]) ;
fprintf (stderr, "%s: Unable to initialise GPIO mode.\n", argv [0]) ;
exit (1) ;
}

@@ -570,23 +833,30 @@ int main (int argc, char *argv [])
{
if (wiringPiSetup () == -1)
{
fprintf (stderr, "%s: Unable to initialise GPIO in wiringPi mode\n", argv [0]) ;
fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ;
exit (1) ;
}
wpMode = WPI_MODE_PINS ;
}

/**/ if (strcasecmp (argv [1], "write" ) == 0)
doWrite (argc, argv) ;
else if (strcasecmp (argv [1], "read" ) == 0)
doRead (argc, argv) ;
else if (strcasecmp (argv [1], "mode" ) == 0)
doMode (argc, argv) ;
else if (strcasecmp (argv [1], "pwm" ) == 0)
doPwm (argc, argv) ;
// Check for PWM operations

if (wpMode != WPI_MODE_PIFACE)
{
if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode (PWM_MODE_BAL) ; return 0 ; }
if (strcasecmp (argv [1], "pwm-ms") == 0) { doPwmMode (PWM_MODE_MS) ; return 0 ; }
if (strcasecmp (argv [1], "pwmr") == 0) { doPwmRange (argc, argv) ; return 0 ; }
}

// Check for wiring commands

/**/ if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ;
else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
else
{
fprintf (stderr, "%s: Unknown command: %s. (read/write/pwm/mode expected)\n", argv [0], argv [1]) ;
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
exit (1) ;
}
return 0 ;


+ 122
- 0
wiringPi/gertboard.c 파일 보기

@@ -0,0 +1,122 @@
/*
* gertboard.c:
* Access routines for the SPI devices on the Gertboard
* Copyright (c) 2012 Gordon Henderson
*
* The Gertboard has:
*
* An MCP3002 dual-channel A to D convertor connected
* to the SPI bus, selected by chip-select A, and:
*
* An MCP4802 dual-channel D to A convertor connected
* to the SPI bus, selected via chip-select B.
*
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/


#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>

#include "wiringPiSPI.h"

#include "gertboard.h"

// The A-D convertor won't run at more than 1MHz @ 3.3v

#define SPI_ADC_SPEED 1000000
#define SPI_DAC_SPEED 1000000
#define SPI_A2D 0
#define SPI_D2A 1


/*
* gertboardAnalogWrite:
* Write an 8-bit data value to the MCP4802 Analog to digital
* convertor on the Gertboard.
*********************************************************************************
*/

void gertboardAnalogWrite (int chan, int value)
{
uint8_t spiData [2] ;
uint8_t chanBits, dataBits ;

if (chan == 0)
chanBits = 0x30 ;
else
chanBits = 0xB0 ;

chanBits |= ((value >> 4) & 0x0F) ;
dataBits = ((value << 4) & 0xF0) ;

spiData [0] = chanBits ;
spiData [1] = dataBits ;

wiringPiSPIDataRW (SPI_D2A, spiData, 2) ;
}


/*
* gertboardAnalogRead:
* Return the analog value of the given channel (0/1).
* The A/D is a 10-bit device
*********************************************************************************
*/

int gertboardAnalogRead (int chan)
{
uint8_t spiData [2] ;

uint8_t chanBits ;

if (chan == 0)
chanBits = 0b11010000 ;
else
chanBits = 0b11110000 ;

spiData [0] = chanBits ;
spiData [1] = 0 ;

wiringPiSPIDataRW (SPI_A2D, spiData, 2) ;

return ((spiData [0] << 7) | (spiData [1] >> 1)) & 0x3FF ;
}


/*
* gertboardSPISetup:
* Initialise the SPI bus, etc.
*********************************************************************************
*/

int gertboardSPISetup (void)
{
if (wiringPiSPISetup (SPI_A2D, SPI_ADC_SPEED) < 0)
return -1 ;

if (wiringPiSPISetup (SPI_D2A, SPI_DAC_SPEED) < 0)
return -1 ;

return 0 ;
}

+ 39
- 0
wiringPi/gertboard.h 파일 보기

@@ -0,0 +1,39 @@
/*
* gertboard.h:
* Access routines for the SPI devices on the Gertboard
* Copyright (c) 2012 Gordon Henderson
*
* The Gertboard has an MCP4802 dual-channel D to A convertor
* connected to the SPI bus, selected via chip-select B.
*
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#ifdef __cplusplus
extern "C" {
#endif

extern void gertboardAnalogWrite (int chan, int value) ;
extern int gertboardAnalogRead (int chan) ;
extern int gertboardSPISetup (void) ;

#ifdef __cplusplus
}
#endif

+ 8
- 0
wiringPi/lcd.h 파일 보기

@@ -33,5 +33,13 @@ extern void lcdPutchar (int fd, uint8_t data) ;
extern void lcdPuts (int fd, char *string) ;
extern void lcdPrintf (int fd, char *message, ...) ;

#ifdef __cplusplus
extern "C" {
#endif

extern int lcdInit (int rows, int cols, int bits, int rs, int strb,
int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ;

#ifdef __cplusplus
}
#endif

+ 113
- 0
wiringPi/piNes.c 파일 보기

@@ -0,0 +1,113 @@
/*
* piNes.c:
* Driver for the NES Joystick controller on the Raspberry Pi
* Copyright (c) 2012 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <wiringPi.h>

#include "piNes.h"

#define MAX_NES_JOYSTICKS 8

#define NES_RIGHT 0x01
#define NES_LEFT 0x02
#define NES_DOWN 0x04
#define NES_UP 0x08
#define NES_START 0x10
#define NES_SELECT 0x20
#define NES_B 0x40
#define NES_A 0x80


#define PULSE_TIME 25

// Data to store the pins for each controller

struct nesPinsStruct
{
unsigned int cPin, dPin, lPin ;
} ;

static struct nesPinsStruct nesPins [MAX_NES_JOYSTICKS] ;

static int joysticks = 0 ;


/*
* setupNesJoystick:
* Create a new NES joystick interface, program the pins, etc.
*********************************************************************************
*/

int setupNesJoystick (int dPin, int cPin, int lPin)
{
if (joysticks == MAX_NES_JOYSTICKS)
return -1 ;

nesPins [joysticks].dPin = dPin ;
nesPins [joysticks].cPin = cPin ;
nesPins [joysticks].lPin = lPin ;

digitalWrite (lPin, LOW) ;
digitalWrite (cPin, LOW) ;

pinMode (lPin, OUTPUT) ;
pinMode (cPin, OUTPUT) ;
pinMode (dPin, INPUT) ;

return joysticks++ ;
}


/*
* readNesJoystick:
* Do a single scan of the NES Joystick.
*********************************************************************************
*/

unsigned int readNesJoystick (int joystick)
{
unsigned int value = 0 ;
int i ;

struct nesPinsStruct *pins = &nesPins [joystick] ;
// Toggle Latch - which presents the first bit

digitalWrite (pins->lPin, HIGH) ; delayMicroseconds (PULSE_TIME) ;
digitalWrite (pins->lPin, LOW) ; delayMicroseconds (PULSE_TIME) ;

// Read first bit

value = digitalRead (pins->dPin) ;

// Now get the next 7 bits with the clock

for (i = 0 ; i < 7 ; ++i)
{
digitalWrite (pins->cPin, HIGH) ; delayMicroseconds (PULSE_TIME) ;
digitalWrite (pins->cPin, LOW) ; delayMicroseconds (PULSE_TIME) ;
value = (value << 1) | digitalRead (pins->dPin) ;
}

return value ^ 0xFF ;
}

+ 45
- 0
wiringPi/piNes.h 파일 보기

@@ -0,0 +1,45 @@
/*
* piNes.h:
* Driver for the NES Joystick controller on the Raspberry Pi
* Copyright (c) 2012 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#define MAX_NES_JOYSTICKS 8

#define NES_RIGHT 0x01
#define NES_LEFT 0x02
#define NES_DOWN 0x04
#define NES_UP 0x08
#define NES_START 0x10
#define NES_SELECT 0x20
#define NES_B 0x40
#define NES_A 0x80

#ifdef __cplusplus
extern "C" {
#endif

extern int setupNesJoystick (int dPin, int cPin, int lPin) ;
extern unsigned int readNesJoystick (int joystick) ;

#ifdef __cplusplus
}
#endif

+ 130
- 0
wiringPi/softPwm.c 파일 보기

@@ -0,0 +1,130 @@
/*
* softPwm.c:
* Provide 2 channels of software driven PWM.
* Copyright (c) 2012 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <stdio.h>
#include <pthread.h>

#include "wiringPi.h"
#include "softPwm.h"

#define MAX_PINS 64

// The PWM Frequency is derived from the "pulse time" below. Essentially,
// the frequency is a function of the range and this pulse time.
// The total period will be range * pulse time in uS, so a pulse time
// of 100 and a range of 100 gives a period of 100 * 100 = 10,000 uS
// which is a frequency of 100Hz.
//
// It's possible to get a higher frequency by lowering the pulse time,
// however CPU uage will skyrocket as wiringPi uses a hard-loop to time
// periods under 100uS - this is because the Linux timer calls are just
// accurate at all, and have an overhead.
//
// Another way to increase the frequency is to reduce the range - however
// that reduces the overall output accuracy...

#define PULSE_TIME 100

static int marks [MAX_PINS] ;
static int range [MAX_PINS] ;

int newPin = -1 ;


/*
* softPwmThread:
* Thread to do the actual PWM output
*********************************************************************************
*/

static PI_THREAD (softPwmThread)
{
int pin, mark, space ;

pin = newPin ;
newPin = -1 ;

piHiPri (50) ;

for (;;)
{
mark = marks [pin] ;
space = range [pin] - mark ;

if (mark != 0)
digitalWrite (pin, HIGH) ;
delayMicroseconds (mark * 100) ;

if (space != 0)
digitalWrite (pin, LOW) ;
delayMicroseconds (space * 100) ;
}

return NULL ;
}


/*
* softPwmWrite:
* Write a PWM value to the given pin
*********************************************************************************
*/

void softPwmWrite (int pin, int value)
{
pin &= 63 ;

/**/ if (value < 0)
value = 0 ;
else if (value > range [pin])
value = range [pin] ;

marks [pin] = value ;
}


/*
* softPwmCreate:
* Create a new PWM thread.
*********************************************************************************
*/

int softPwmCreate (int pin, int initialValue, int pwmRange)
{
int res ;

pinMode (pin, OUTPUT) ;
digitalWrite (pin, LOW) ;

marks [pin] = initialValue ;
range [pin] = pwmRange ;

newPin = pin ;
res = piThreadCreate (softPwmThread) ;

while (newPin != -1)
delay (1) ;

return res ;
}

+ 34
- 0
wiringPi/softPwm.h 파일 보기

@@ -0,0 +1,34 @@
/*
* softPwm.h:
* Provide 2 channels of software driven PWM.
* Copyright (c) 2012 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#ifdef __cplusplus
extern "C" {
#endif

extern int softPwmCreate (int pin, int value, int range) ;
extern void softPwmWrite (int pin, int value) ;

#ifdef __cplusplus
}
#endif

+ 296
- 135
wiringPi/wiringPi.c 파일 보기

@@ -71,12 +71,16 @@

// Function stubs

void (*pinMode) (int pin, int mode) ;
void (*pullUpDnControl) (int pin, int pud) ;
void (*digitalWrite) (int pin, int value) ;
void (*pwmWrite) (int pin, int value) ;
int (*digitalRead) (int pin) ;
int (*waitForInterrupt) (int pin, int mS) ;
void (*pinMode) (int pin, int mode) ;
void (*pullUpDnControl) (int pin, int pud) ;
void (*digitalWrite) (int pin, int value) ;
void (*pwmWrite) (int pin, int value) ;
void (*setPadDrive) (int group, int value) ;
int (*digitalRead) (int pin) ;
int (*waitForInterrupt) (int pin, int mS) ;
void (*delayMicroseconds) (unsigned int howLong) ;
void (*pwmSetMode) (int mode) ;
void (*pwmSetRange) (unsigned int range) ;


#ifndef TRUE
@@ -84,6 +88,11 @@ int (*waitForInterrupt) (int pin, int mS) ;
#define FALSE (1==2)
#endif

// BCM Magic

#define BCM_PASSWORD 0x5A000000


// Port function select bits

#define FSEL_INPT 0b000
@@ -100,10 +109,11 @@ int (*waitForInterrupt) (int pin, int mS) ;
// Take from Gert/Doms code. Some of this is not in the manual
// that I can find )-:

#define BCM2708_PERI_BASE 0x20000000
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_PADS (BCM2708_PERI_BASE + 0x100000)
#define CLOCK_BASE (BCM2708_PERI_BASE + 0x101000)
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000)
#define GPIO_TIMER (BCM2708_PERI_BASE + 0x00B000)
#define GPIO_PWM (BCM2708_PERI_BASE + 0x20C000)

#define PAGE_SIZE (4*1024)
@@ -137,12 +147,27 @@ int (*waitForInterrupt) (int pin, int mS) ;
#define PWM0_SERIAL 0x0002 // Run in serial mode
#define PWM0_ENABLE 0x0001 // Channel Enable

// Timer

#define TIMER_LOAD (0x400 >> 2)
#define TIMER_VALUE (0x404 >> 2)
#define TIMER_CONTROL (0x408 >> 2)
#define TIMER_IRQ_CLR (0x40C >> 2)
#define TIMER_IRQ_RAW (0x410 >> 2)
#define TIMER_IRQ_MASK (0x414 >> 2)
#define TIMER_RELOAD (0x418 >> 2)
#define TIMER_PRE_DIV (0x41C >> 2)
#define TIMER_COUNTER (0x420 >> 2)

// Locals to hold pointers to the hardware

static volatile uint32_t *gpio ;
static volatile uint32_t *pwm ;
static volatile uint32_t *clk ;
static volatile uint32_t *pads ;
static volatile uint32_t *timer ;

static volatile uint32_t *timerIrqRaw ;

// The BCM2835 has 54 GPIO pins.
// BCM2835 data sheet, Page 90 onwards.
@@ -273,6 +298,8 @@ static uint8_t gpioToFEN [] =
// gpioToPUDCLK
// (Word) offset to the Pull Up Down Clock regsiter

#define GPPUD 37

static uint8_t gpioToPUDCLK [] =
{
38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,
@@ -352,30 +379,42 @@ void pinModeGpio (int pin, int mode)
if (!pwmRunning)
{

// Gert/Doms Values
*(clk + PWMCLK_DIV) = 0x5A000000 | (32<<12) ; // set pwm div to 32 (19.2/3 = 600KHz)
*(clk + PWMCLK_CNTL) = 0x5A000011 ; // Source=osc and enable
digitalWrite (pin, LOW) ;
*(pwm + PWM_CONTROL) = 0 ; // Disable PWM
*(pwm + PWM_CONTROL) = 0 ; // Stop PWM
delayMicroseconds (10) ;
*(pwm + PWM0_RANGE) = 0x400 ;
delayMicroseconds (10) ;
*(pwm + PWM1_RANGE) = 0x400 ;
// Gert/Doms Values
*(clk + PWMCLK_DIV) = BCM_PASSWORD | (32<<12) ; // set pwm div to 32 (19.2/32 = 600KHz)
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Source=osc and enable

delayMicroseconds (10) ;

*(pwm + PWM0_RANGE) = 0x400 ; delayMicroseconds (10) ;
*(pwm + PWM1_RANGE) = 0x400 ; delayMicroseconds (10) ;

// Enable PWMs

*(pwm + PWM0_DATA) = 512 ;
*(pwm + PWM1_DATA) = 512 ;

// Balanced mode (default)

*(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;

pwmRunning = TRUE ;
}

}

// When we change mode of any pin, we remove the pull up/downs
// Or we used to... Hm. Commented out now because for some wieird reason,
// it seems to block subsequent attempts to set the pull up/downs and I've
// not quite gotten to the bottom of why this happens
// The down-side is that the pull up/downs are rememberd in the SoC between
// power cycles, so it's going to be a good idea to explicitly set them in
// any new code.
//
// pullUpDnControl (pin, PUD_OFF) ;

pullUpDnControl (pin, PUD_OFF) ;
}

void pinModeWPi (int pin, int mode)
@@ -389,6 +428,38 @@ void pinModeSys (int pin, int mode)
}


/*
* pwmControl:
* Allow the user to control some of the PWM functions
*********************************************************************************
*/

void pwmSetModeWPi (int mode)
{
if (mode == PWM_MODE_MS)
*(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ;
else
*(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
}

void pwmSetModeSys (int mode)
{
return ;
}


void pwmSetRangeWPi (unsigned int range)
{
*(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
*(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
}

void pwmSetRangeSys (unsigned int range)
{
return ;
}


#ifdef notYetReady
/*
* pinED01:
@@ -414,12 +485,12 @@ void pinEnableED01Pi (int pin)

void digitalWriteWPi (int pin, int value)
{
int gpioPin = pinToGpio [pin & 63] ;
pin = pinToGpio [pin & 63] ;

if (value == LOW)
*(gpio + gpioToGPCLR [gpioPin]) = 1 << gpioPin ;
*(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
else
*(gpio + gpioToGPSET [gpioPin]) = 1 << gpioPin ;
*(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
}

void digitalWriteGpio (int pin, int value)
@@ -427,9 +498,9 @@ void digitalWriteGpio (int pin, int value)
pin &= 63 ;

if (value == LOW)
*(gpio + gpioToGPCLR [pin]) = 1 << pin ;
*(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
else
*(gpio + gpioToGPSET [pin]) = 1 << pin ;
*(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
}

void digitalWriteSys (int pin, int value)
@@ -452,28 +523,55 @@ void digitalWriteSys (int pin, int value)
*********************************************************************************
*/

void pwmWriteWPi (int pin, int value)
void pwmWriteGpio (int pin, int value)
{
int port, gpioPin ;
int port ;

gpioPin = pinToGpio [pin & 63] ;
port = gpioToPwmPort [gpioPin] ;
pin = pin & 63 ;
port = gpioToPwmPort [pin] ;

*(pwm + port) = value & 0x3FF ;
*(pwm + port) = value ;
}

void pwmWriteGpio (int pin, int value)
void pwmWriteWPi (int pin, int value)
{
pwmWriteGpio (pinToGpio [pin & 63], value) ;
}

void pwmWriteSys (int pin, int value)
{
return ;
}


/*
* setPadDrive:
* Set the PAD driver value
*********************************************************************************
*/

void setPadDriveWPi (int group, int value)
{
int port, gpioPin ;
uint32_t wrVal ;

gpioPin = pin & 63 ;
port = gpioToPwmPort [gpioPin] ;
if ((group < 0) || (group > 2))
return ;

*(pwm + port) = value & 0x3FF ;
wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
*(pads + group + 11) = wrVal ;

#ifdef DEBUG_PADS
printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
printf ("Read : %08X\n", *(pads + group + 11)) ;
#endif
}

void setPadDriveGpio (int group, int value)
{
setPadDriveWPi (group, value) ;
}

void pwmWriteSys (int pin, int value)
void setPadDriveSys (int group, int value)
{
return ;
}
@@ -487,13 +585,9 @@ void pwmWriteSys (int pin, int value)

int digitalReadWPi (int pin)
{
int gpioPin ;

pin &= 63 ;

gpioPin = pinToGpio [pin] ;
pin = pinToGpio [pin & 63] ;

if ((*(gpio + gpioToGPLEV [gpioPin]) & (1 << gpioPin)) != 0)
if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
return HIGH ;
else
return LOW ;
@@ -503,7 +597,7 @@ int digitalReadGpio (int pin)
{
pin &= 63 ;

if ((*(gpio + gpioToGPLEV [pin]) & (1 << pin)) != 0)
if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
return HIGH ;
else
return LOW ;
@@ -533,30 +627,21 @@ int digitalReadSys (int pin)
*********************************************************************************
*/

void pullUpDnControlWPi (int pin, int pud)
void pullUpDnControlGpio (int pin, int pud)
{
pin = pinToGpio [pin & 63] ;
pin &= 63 ;
pud &= 3 ;

*(gpio + 37) = pud ;
delayMicroseconds (10) ;
*(gpio + gpioToPUDCLK [pin]) = 1 << pin ;
delayMicroseconds (10) ;
*(gpio + GPPUD) = pud ; delayMicroseconds (5) ;
*(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ;
*(gpio + 37) = 0 ;
*(gpio + gpioToPUDCLK [pin]) = 0 ;
*(gpio + GPPUD) = 0 ; delayMicroseconds (5) ;
*(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ;
}

void pullUpDnControlGpio (int pin, int pud)
void pullUpDnControlWPi (int pin, int pud)
{
pin &= 63 ;

*(gpio + 37) = pud ;
delayMicroseconds (10) ;
*(gpio + gpioToPUDCLK [pin]) = 1 << pin ;
delayMicroseconds (10) ;
*(gpio + 37) = 0 ;
*(gpio + gpioToPUDCLK [pin]) = 0 ;
pullUpDnControlGpio (pinToGpio [pin & 63], pud) ;
}

void pullUpDnControlSys (int pin, int pud)
@@ -615,6 +700,94 @@ int waitForInterruptGpio (int pin, int mS)




/*
* delay:
* Wait for some number of milli seconds
*********************************************************************************
*/

void delay (unsigned int howLong)
{
struct timespec sleeper, dummy ;

sleeper.tv_sec = (time_t)(howLong / 1000) ;
sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;

nanosleep (&sleeper, &dummy) ;
}


/*
* delayMicroseconds:
* This is somewhat intersting. It seems that on the Pi, a single call
* to nanosleep takes some 80 to 130 microseconds anyway, so while
* obeying the standards (may take longer), it's not always what we
* want!
*
* So what I'll do now is if the delay is less than 100uS we'll do it
* in a hard loop, watching a built-in counter on the ARM chip. This is
* somewhat sub-optimal in that it uses 100% CPU, something not an issue
* in a microcontroller, but under a multi-tasking, multi-user OS, it's
* wastefull, however we've no real choice )-:
*********************************************************************************
*/

void delayMicrosecondsSys (unsigned int howLong)
{
struct timespec sleeper, dummy ;

sleeper.tv_sec = 0 ;
sleeper.tv_nsec = (long)(howLong * 1000) ;

nanosleep (&sleeper, &dummy) ;
}

void delayMicrosecondsHard (unsigned int howLong)
{
*(timer + TIMER_LOAD) = howLong ;
*(timer + TIMER_IRQ_CLR) = 0 ;

while (*timerIrqRaw == 0)
;
}

void delayMicrosecondsWPi (unsigned int howLong)
{
struct timespec sleeper, dummy ;

/**/ if (howLong == 0)
return ;
else if (howLong < 100)
delayMicrosecondsHard (howLong) ;
else
{
sleeper.tv_sec = 0 ;
sleeper.tv_nsec = (long)(howLong * 1000) ;
nanosleep (&sleeper, &dummy) ;
}
}


/*
* millis:
* Return a number of milliseconds as an unsigned int.
*********************************************************************************
*/

unsigned int millis (void)
{
struct timeval tv ;
unsigned long long t1 ;

gettimeofday (&tv, NULL) ;

t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;

return (uint32_t)(t1 - epoch) ;
}


/*
* wiringPiSetup:
* Must be called once at the start of your program execution.
@@ -627,20 +800,19 @@ int waitForInterruptGpio (int pin, int mS)
int wiringPiSetup (void)
{
int fd ;
uint8_t *gpioMem, *pwmMem, *clkMem ;
uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ;
struct timeval tv ;

#ifdef DEBUG_PADS
uint8_t *gpioMem, *padsMem, *pwmMem, *clkMem ;
uint32_t *pads ;
#endif

pinMode = pinModeWPi ;
pullUpDnControl = pullUpDnControlWPi ;
digitalWrite = digitalWriteWPi ;
pwmWrite = pwmWriteWPi ;
digitalRead = digitalReadWPi ;
waitForInterrupt = waitForInterruptWPi ;
pinMode = pinModeWPi ;
pullUpDnControl = pullUpDnControlWPi ;
digitalWrite = digitalWriteWPi ;
pwmWrite = pwmWriteWPi ;
setPadDrive = setPadDriveWPi ;
digitalRead = digitalReadWPi ;
waitForInterrupt = waitForInterruptWPi ;
delayMicroseconds = delayMicrosecondsWPi ;
pwmSetMode = pwmSetModeWPi ;
pwmSetRange = pwmSetRangeWPi ;
// Open the master /dev/memory device

@@ -711,7 +883,8 @@ int wiringPiSetup (void)
return -1 ;
}
#ifdef DEBUG_PADS
// The drive pads

if ((padsMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
{
fprintf (stderr, "wiringPiSetup: padsMem malloc failed: %s\n", strerror (errno)) ;
@@ -728,14 +901,41 @@ int wiringPiSetup (void)
fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ;
return -1 ;
}
printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ;

printf ("%08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
// *(pads + 11) = 0x1F ;
printf ("%08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
#ifdef DEBUG_PADS
printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ;
printf (" -> %08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
#endif

// The system timer

if ((timerMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
{
fprintf (stderr, "wiringPiSetup: timerMem malloc failed: %s\n", strerror (errno)) ;
return -1 ;
}

if (((uint32_t)timerMem % PAGE_SIZE) != 0)
timerMem += PAGE_SIZE - ((uint32_t)timerMem % PAGE_SIZE) ;

timer = (uint32_t *)mmap(timerMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_TIMER) ;

if ((int32_t)timer < 0)
{
fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ;
return -1 ;
}

// Set the timer to free-running, 1MHz.
// 0xF9 is 249, the timer divide is base clock / (divide+1)
// so base clock is 250MHz / 250 = 1MHz.

*(timer + TIMER_CONTROL) = 0x0000280 ;
*(timer + TIMER_PRE_DIV) = 0x00000F9 ;
timerIrqRaw = timer + TIMER_IRQ_RAW ;

// Initialise our epoch for millis()

gettimeofday (&tv, NULL) ;
epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;

@@ -759,12 +959,16 @@ int wiringPiSetupGpio (void)
if (x != 0)
return x ;

pinMode = pinModeGpio ;
pullUpDnControl = pullUpDnControlGpio ;
digitalWrite = digitalWriteGpio ;
pwmWrite = pwmWriteGpio ;
digitalRead = digitalReadGpio ;
waitForInterrupt = waitForInterruptGpio ;
pinMode = pinModeGpio ;
pullUpDnControl = pullUpDnControlGpio ;
digitalWrite = digitalWriteGpio ;
pwmWrite = pwmWriteGpio ;
setPadDrive = setPadDriveGpio ;
digitalRead = digitalReadGpio ;
waitForInterrupt = waitForInterruptGpio ;
delayMicroseconds = delayMicrosecondsWPi ; // Same
pwmSetMode = pwmSetModeWPi ;
pwmSetRange = pwmSetRangeWPi ;

return 0 ;
}
@@ -785,12 +989,17 @@ int wiringPiSetupSys (void)
struct timeval tv ;
char fName [128] ;

pinMode = pinModeSys ;
pullUpDnControl = pullUpDnControlSys ;
digitalWrite = digitalWriteSys ;
pwmWrite = pwmWriteSys ;
digitalRead = digitalReadSys ;
waitForInterrupt = waitForInterruptSys ;
pinMode = pinModeSys ;
pullUpDnControl = pullUpDnControlSys ;
digitalWrite = digitalWriteSys ;
pwmWrite = pwmWriteSys ;
setPadDrive = setPadDriveSys ;
digitalRead = digitalReadSys ;
waitForInterrupt = waitForInterruptSys ;
delayMicroseconds = delayMicrosecondsSys ;
pwmSetMode = pwmSetModeSys ;
pwmSetRange = pwmSetRangeSys ;


// Open and scan the directory, looking for exported GPIOs, and pre-open
// the 'value' interface to speed things up for later
@@ -808,51 +1017,3 @@ int wiringPiSetupSys (void)

return 0 ;
}





/*
* delay: delayMicroseconds
* Wait for some number of milli/micro seconds
*********************************************************************************
*/

void delay (unsigned int howLong)
{
struct timespec sleeper, dummy ;

sleeper.tv_sec = (time_t)(howLong / 1000) ;
sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;

nanosleep (&sleeper, &dummy) ;
}

void delayMicroseconds (unsigned int howLong)
{
struct timespec sleeper, dummy ;

sleeper.tv_sec = 0 ;
sleeper.tv_nsec = (long)(howLong * 1000) ;

nanosleep (&sleeper, &dummy) ;
}

/*
* millis:
* Return a number of milliseconds as an unsigned int.
*********************************************************************************
*/

unsigned int millis (void)
{
struct timeval tv ;
unsigned long long t1 ;

gettimeofday (&tv, NULL) ;

t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;

return (uint32_t)(t1 - epoch) ;
}

+ 15
- 6
wiringPi/wiringPi.h 파일 보기

@@ -41,6 +41,12 @@
#define PUD_DOWN 1
#define PUD_UP 2

// PWM

#define PWM_MODE_MS 0
#define PWM_MODE_BAL 1


// Function prototypes
// c++ wrappers thanks to a commend by Nick Lott
// (and others on the Raspberry Pi forums)
@@ -58,11 +64,15 @@ extern int wiringPiSetupPiFace (void) ;

extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only

extern void (*pinMode) (int pin, int mode) ;
extern void (*pullUpDnControl) (int pin, int pud) ;
extern void (*digitalWrite) (int pin, int value) ;
extern void (*pwmWrite) (int pin, int value) ;
extern int (*digitalRead) (int pin) ;
extern void (*pinMode) (int pin, int mode) ;
extern void (*pullUpDnControl) (int pin, int pud) ;
extern void (*digitalWrite) (int pin, int value) ;
extern void (*pwmWrite) (int pin, int value) ;
extern void (*setPadDrive) (int group, int value) ;
extern int (*digitalRead) (int pin) ;
extern void (*delayMicroseconds) (unsigned int howLong) ;
extern void (*pwmSetMode) (int mode) ;
extern void (*pwmSetRange) (unsigned int range) ;

// Interrupts

@@ -84,7 +94,6 @@ extern int piHiPri (int pri) ;
// Extras from arduino land

extern void delay (unsigned int howLong) ;
extern void delayMicroseconds (unsigned int howLong) ;
extern unsigned int millis (void) ;

#ifdef __cplusplus


+ 117
- 0
wiringPi/wiringPiSPI.c 파일 보기

@@ -0,0 +1,117 @@
/*
* wiringPiSPI.c:
* Simplified SPI access routines
* Copyright (c) 2012 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/


#include <stdint.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>

#include "wiringPiSPI.h"


// The SPI bus parameters
// Variables as they need to be passed as pointers later on

static char *spiDev0 = "/dev/spidev0.0" ;
static char *spiDev1 = "/dev/spidev0.1" ;
static uint8_t spiMode = 0 ;
static uint8_t spiBPW = 8 ;
static uint16_t spiDelay = 0;

static uint32_t spiSpeeds [2] ;
static int spiFds [2] ;


/*
* wiringPiSPIGetFd:
* Return the file-descriptor for the given channel
*********************************************************************************
*/

int wiringPiSPIGetFd (int channel)
{
return spiFds [channel &1] ;
}


/*
* wiringPiSPIDataRW:
* Write and Read a block of data over the SPI bus.
* Note the data ia being read into the transmit buffer, so will
* overwrite it!
* This is also a full-duplex operation.
*********************************************************************************
*/

int wiringPiSPIDataRW (int channel, unsigned char *data, int len)
{
struct spi_ioc_transfer spi ;

channel &= 1 ;

spi.tx_buf = (unsigned long)data ;
spi.rx_buf = (unsigned long)data ;
spi.len = len ;
spi.delay_usecs = spiDelay ;
spi.speed_hz = spiSpeeds [channel] ;
spi.bits_per_word = spiBPW ;

return ioctl (spiFds [channel], SPI_IOC_MESSAGE(1), &spi) ;
}


/*
* wiringPiSPISetup:
* Open the SPI device, and set it up, etc.
*********************************************************************************
*/

int wiringPiSPISetup (int channel, int speed)
{
int fd ;

channel &= 1 ;

if ((fd = open (channel == 0 ? spiDev0 : spiDev1, O_RDWR)) < 0)
return -1 ;

spiSpeeds [channel] = speed ;
spiFds [channel] = fd ;

// Set SPI parameters.
// Why are we reading it afterwriting it? I've no idea, but for now I'm blindly
// copying example code I've seen online...

if (ioctl (fd, SPI_IOC_WR_MODE, &spiMode) < 0) return -1 ;
if (ioctl (fd, SPI_IOC_RD_MODE, &spiMode) < 0) return -1 ;

if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) return -1 ;
if (ioctl (fd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0) return -1 ;

if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) return -1 ;
if (ioctl (fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) return -1 ;

return fd ;
}

+ 35
- 0
wiringPi/wiringPiSPI.h 파일 보기

@@ -0,0 +1,35 @@
/*
* wiringPiSPI.h:
* Simplified SPI access routines
* Copyright (c) 2012 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#ifdef __cplusplus
extern "C" {
#endif

int wiringPiSPIGetFd (int channel) ;
int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ;
int wiringPiSPISetup (int channel, int speed) ;

#ifdef __cplusplus
}
#endif

+ 25
- 19
wiringPi/wiringSerial.c 파일 보기

@@ -20,8 +20,6 @@
***********************************************************************
*/

#undef DEBUG

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -49,10 +47,6 @@ int serialOpen (char *device, int baud)
speed_t myBaud ;
int status, fd ;

#ifdef DEBUG
printf ("openSerialPort: <%s> baud: $d\n", device, baud) ;
#endif

switch (baud)
{
case 50: myBaud = B50 ; break ;
@@ -86,22 +80,22 @@ int serialOpen (char *device, int baud)

tcgetattr (fd, &options) ;

cfmakeraw (&options) ;
cfsetispeed (&options, myBaud) ;
cfsetospeed (&options, myBaud) ;
cfmakeraw (&options) ;
cfsetispeed (&options, myBaud) ;
cfsetospeed (&options, myBaud) ;

options.c_cflag |= (CLOCAL | CREAD) ;
options.c_cflag &= ~PARENB ;
options.c_cflag &= ~CSTOPB ;
options.c_cflag &= ~CSIZE ;
options.c_cflag |= CS8 ;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
options.c_oflag &= ~OPOST ;
options.c_cflag |= (CLOCAL | CREAD) ;
options.c_cflag &= ~PARENB ;
options.c_cflag &= ~CSTOPB ;
options.c_cflag &= ~CSIZE ;
options.c_cflag |= CS8 ;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
options.c_oflag &= ~OPOST ;

options.c_cc [VMIN] = 0 ;
options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)
options.c_cc [VMIN] = 0 ;
options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)

tcsetattr (fd, TCSANOW, &options) ;
tcsetattr (fd, TCSANOW | TCSAFLUSH, &options) ;

ioctl (fd, TIOCMGET, &status);

@@ -117,6 +111,18 @@ int serialOpen (char *device, int baud)


/*
* serialFlush:
* Flush the serial buffers (both tx & rx)
*********************************************************************************
*/

void serialFlush (int fd)
{
tcflush (fd, TCIOFLUSH) ;
}


/*
* serialClose:
* Release the serial port
*********************************************************************************


+ 1
- 0
wiringPi/wiringSerial.h 파일 보기

@@ -26,6 +26,7 @@ extern "C" {

extern int serialOpen (char *device, int baud) ;
extern void serialClose (int fd) ;
extern void serialFlush (int fd) ;
extern void serialPutchar (int fd, unsigned char c) ;
extern void serialPuts (int fd, char *s) ;
extern void serialPrintf (int fd, char *message, ...) ;


불러오는 중...
취소
저장