@@ -1,7 +0,0 @@ | |||||
WiringPi: An implementation of most of the Arduino Wiring | |||||
functions for the Raspberry Pi | |||||
Full details at: | |||||
https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
@@ -1,94 +0,0 @@ | |||||
/* | |||||
* 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. | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* 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 <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 ; | |||||
} |
@@ -1,71 +0,0 @@ | |||||
/* | |||||
* piFace.c: | |||||
* Simple test for the PiFace interface board. | |||||
* | |||||
* Read the buttons and output the same to the LEDs | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* 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 <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
int outputs [4] = { 0,0,0,0 } ; | |||||
void scanButton (int button) | |||||
{ | |||||
if (digitalRead (button) == LOW) | |||||
{ | |||||
outputs [button] ^= 1 ; | |||||
digitalWrite (button, outputs [button]) ; | |||||
} | |||||
while (digitalRead (button) == LOW) | |||||
delay (1) ; | |||||
} | |||||
int main (void) | |||||
{ | |||||
int pin, button ; | |||||
printf ("Raspberry Pi wiringPiFace test program\n") ; | |||||
if (wiringPiSetupPiFace () == -1) | |||||
exit (1) ; | |||||
// Enable internal pull-ups | |||||
for (pin = 0 ; pin < 8 ; ++pin) | |||||
pullUpDnControl (pin, PUD_UP) ; | |||||
for (;;) | |||||
{ | |||||
for (button = 0 ; button < 4 ; ++button) | |||||
scanButton (button) ; | |||||
delay (1) ; | |||||
} | |||||
return 0 ; | |||||
} |
@@ -1,111 +0,0 @@ | |||||
/* | |||||
* test1.c: | |||||
* Simple test program to test the wiringPi functions | |||||
* This is a sequencer to make a patter appear on 8 LEDs | |||||
* connected to the GPIO pins. | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* 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 <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
// Simple sequencer data | |||||
// Triplets of LED, On/Off and delay | |||||
uint8_t data [] = | |||||
{ | |||||
0, 1, 1, | |||||
1, 1, 1, | |||||
0, 0, 0, 2, 1, 1, | |||||
1, 0, 0, 3, 1, 1, | |||||
2, 0, 0, 4, 1, 1, | |||||
3, 0, 0, 5, 1, 1, | |||||
4, 0, 0, 6, 1, 1, | |||||
5, 0, 0, 7, 1, 1, | |||||
6, 0, 1, | |||||
7, 0, 1, | |||||
0, 0, 1, // Extra delay | |||||
// Back again | |||||
7, 1, 1, | |||||
6, 1, 1, | |||||
7, 0, 0, 5, 1, 1, | |||||
6, 0, 0, 4, 1, 1, | |||||
5, 0, 0, 3, 1, 1, | |||||
4, 0, 0, 2, 1, 1, | |||||
3, 0, 0, 1, 1, 1, | |||||
2, 0, 0, 0, 1, 1, | |||||
1, 0, 1, | |||||
0, 0, 1, | |||||
0, 0, 1, // Extra delay | |||||
9, 9, 9, // End marker | |||||
} ; | |||||
int main (void) | |||||
{ | |||||
int pin ; | |||||
int dataPtr ; | |||||
int l, s, d ; | |||||
printf ("Raspberry Pi wiringPi test program\n") ; | |||||
if (wiringPiSetup () == -1) | |||||
exit (1) ; | |||||
for (pin = 0 ; pin < 8 ; ++pin) | |||||
pinMode (pin, OUTPUT) ; | |||||
pinMode (8, INPUT) ; // Pin 8 SDA0 - Has on-board 2k2 pull-up resistor | |||||
dataPtr = 0 ; | |||||
for (;;) | |||||
{ | |||||
l = data [dataPtr++] ; // LED | |||||
s = data [dataPtr++] ; // State | |||||
d = data [dataPtr++] ; // Duration (10ths) | |||||
if ((l + s + d) == 27) | |||||
{ | |||||
dataPtr = 0 ; | |||||
continue ; | |||||
} | |||||
digitalWrite (l, s) ; | |||||
if (digitalRead (8) == 0) // Pressed as our switch shorts to ground | |||||
delay (d * 10) ; // Faster! | |||||
else | |||||
delay (d * 100) ; | |||||
} | |||||
return 0 ; | |||||
} |
@@ -1,58 +0,0 @@ | |||||
/* | |||||
* test2.c: | |||||
* This tests the hardware PWM channel. | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* 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 <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
int main (void) | |||||
{ | |||||
int bright ; | |||||
printf ("Raspberry Pi wiringPi PWM test program\n") ; | |||||
if (wiringPiSetup () == -1) | |||||
exit (1) ; | |||||
pinMode (1, PWM_OUTPUT) ; | |||||
for (;;) | |||||
{ | |||||
for (bright = 0 ; bright < 1024 ; ++bright) | |||||
{ | |||||
pwmWrite (1, bright) ; | |||||
delay (1) ; | |||||
} | |||||
for (bright = 1023 ; bright >= 0 ; --bright) | |||||
{ | |||||
pwmWrite (1, bright) ; | |||||
delay (1) ; | |||||
} | |||||
} | |||||
return 0 ; | |||||
} |
@@ -1,59 +0,0 @@ | |||||
/* | |||||
* tone.c: | |||||
* Test of the softTone module in wiringPi | |||||
* Plays a scale out on pin 3 - connect pizeo disc to pin 3 & 0v | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* 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 <errno.h> | |||||
#include <string.h> | |||||
#include <wiringPi.h> | |||||
#include <softTone.h> | |||||
#define PIN 3 | |||||
int scale [8] = { 262, 294, 330, 349, 392, 440, 494, 525 } ; | |||||
int main () | |||||
{ | |||||
int i ; | |||||
if (wiringPiSetup () == -1) | |||||
{ | |||||
fprintf (stdout, "oops: %s\n", strerror (errno)) ; | |||||
return 1 ; | |||||
} | |||||
softToneCreate (PIN) ; | |||||
for (;;) | |||||
{ | |||||
for (i = 0 ; i < 8 ; ++i) | |||||
{ | |||||
printf ("%3d\n", i) ; | |||||
softToneWrite (PIN, scale [i]) ; | |||||
delay (500) ; | |||||
} | |||||
} | |||||
} |
@@ -1,9 +0,0 @@ | |||||
WiringPi: An implementation of most of the Arduino Wiring | |||||
functions for the Raspberry Pi, | |||||
along with many more features and libraries to support | |||||
hardware, etc. on the Raspberry Pi | |||||
Full details at: | |||||
https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
@@ -1,122 +0,0 @@ | |||||
/* | |||||
* 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 ; | |||||
} |
@@ -1,39 +0,0 @@ | |||||
/* | |||||
* 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 |
@@ -1,380 +0,0 @@ | |||||
/* | |||||
* lcd.c: | |||||
* Text-based LCD driver. | |||||
* This is designed to drive the parallel interface LCD drivers | |||||
* based in the Hitachi HD44780U controller and compatables. | |||||
* | |||||
* 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 <stdlib.h> | |||||
#include <stdint.h> | |||||
#include <stdarg.h> | |||||
#include "wiringPi.h" | |||||
#include "lcd.h" | |||||
// Commands | |||||
#define LCD_CLEAR 0x01 | |||||
#define LCD_HOME 0x02 | |||||
#define LCD_ENTRY 0x04 | |||||
#define LCD_ON_OFF 0x08 | |||||
#define LCD_CDSHIFT 0x10 | |||||
#define LCD_FUNC 0x20 | |||||
#define LCD_CGRAM 0x40 | |||||
#define LCD_DGRAM 0x80 | |||||
#define LCD_ENTRY_SH 0x01 | |||||
#define LCD_ENTRY_ID 0x02 | |||||
#define LCD_ON_OFF_B 0x01 | |||||
#define LCD_ON_OFF_C 0x02 | |||||
#define LCD_ON_OFF_D 0x04 | |||||
#define LCD_FUNC_F 0x04 | |||||
#define LCD_FUNC_N 0x08 | |||||
#define LCD_FUNC_DL 0x10 | |||||
#define LCD_CDSHIFT_RL 0x04 | |||||
struct lcdDataStruct | |||||
{ | |||||
uint8_t bits, rows, cols ; | |||||
uint8_t rsPin, strbPin ; | |||||
uint8_t dataPins [8] ; | |||||
} ; | |||||
struct lcdDataStruct *lcds [MAX_LCDS] ; | |||||
/* | |||||
* strobe: | |||||
* Toggle the strobe (Really the "E") pin to the device. | |||||
* According to the docs, data is latched on the falling edge. | |||||
********************************************************************************* | |||||
*/ | |||||
static void strobe (struct lcdDataStruct *lcd) | |||||
{ | |||||
// Note timing changes for new version of delayMicroseconds () | |||||
digitalWrite (lcd->strbPin, 1) ; delayMicroseconds (50) ; | |||||
digitalWrite (lcd->strbPin, 0) ; delayMicroseconds (50) ; | |||||
} | |||||
/* | |||||
* sentDataCmd: | |||||
* Send an data or command byte to the display. | |||||
********************************************************************************* | |||||
*/ | |||||
static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data) | |||||
{ | |||||
uint8_t i, d4 ; | |||||
if (lcd->bits == 4) | |||||
{ | |||||
d4 = (data >> 4) & 0x0F; | |||||
for (i = 0 ; i < 4 ; ++i) | |||||
{ | |||||
digitalWrite (lcd->dataPins [i], (d4 & 1)) ; | |||||
d4 >>= 1 ; | |||||
} | |||||
strobe (lcd) ; | |||||
d4 = data & 0x0F ; | |||||
for (i = 0 ; i < 4 ; ++i) | |||||
{ | |||||
digitalWrite (lcd->dataPins [i], (d4 & 1)) ; | |||||
d4 >>= 1 ; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
for (i = 0 ; i < 8 ; ++i) | |||||
{ | |||||
digitalWrite (lcd->dataPins [i], (data & 1)) ; | |||||
data >>= 1 ; | |||||
} | |||||
} | |||||
strobe (lcd) ; | |||||
} | |||||
/* | |||||
* putCommand: | |||||
* Send a command byte to the display | |||||
********************************************************************************* | |||||
*/ | |||||
static void putCommand (struct lcdDataStruct *lcd, uint8_t command) | |||||
{ | |||||
digitalWrite (lcd->rsPin, 0) ; | |||||
sendDataCmd (lcd, command) ; | |||||
} | |||||
static void put4Command (struct lcdDataStruct *lcd, uint8_t command) | |||||
{ | |||||
uint8_t i ; | |||||
digitalWrite (lcd->rsPin, 0) ; | |||||
for (i = 0 ; i < 4 ; ++i) | |||||
{ | |||||
digitalWrite (lcd->dataPins [i], (command & 1)) ; | |||||
command >>= 1 ; | |||||
} | |||||
strobe (lcd) ; | |||||
} | |||||
/* | |||||
********************************************************************************* | |||||
* User Code below here | |||||
********************************************************************************* | |||||
*/ | |||||
/* | |||||
* lcdHome: lcdClear: | |||||
* Home the cursor or clear the screen. | |||||
********************************************************************************* | |||||
*/ | |||||
void lcdHome (int fd) | |||||
{ | |||||
struct lcdDataStruct *lcd = lcds [fd] ; | |||||
putCommand (lcd, LCD_HOME) ; | |||||
} | |||||
void lcdClear (int fd) | |||||
{ | |||||
struct lcdDataStruct *lcd = lcds [fd] ; | |||||
putCommand (lcd, LCD_CLEAR) ; | |||||
} | |||||
/* | |||||
* lcdSendCommand: | |||||
* Send any arbitary command to the display | |||||
********************************************************************************* | |||||
*/ | |||||
void lcdSendCommand (int fd, uint8_t command) | |||||
{ | |||||
struct lcdDataStruct *lcd = lcds [fd] ; | |||||
putCommand (lcd, command) ; | |||||
} | |||||
/* | |||||
* lcdPosition: | |||||
* Update the position of the cursor on the display | |||||
********************************************************************************* | |||||
*/ | |||||
void lcdPosition (int fd, int x, int y) | |||||
{ | |||||
static uint8_t rowOff [4] = { 0x00, 0x40, 0x14, 0x54 } ; | |||||
struct lcdDataStruct *lcd = lcds [fd] ; | |||||
putCommand (lcd, x + (LCD_DGRAM | rowOff [y])) ; | |||||
} | |||||
/* | |||||
* lcdPutchar: | |||||
* Send a data byte to be displayed on the display | |||||
********************************************************************************* | |||||
*/ | |||||
void lcdPutchar (int fd, uint8_t data) | |||||
{ | |||||
struct lcdDataStruct *lcd = lcds [fd] ; | |||||
digitalWrite (lcd->rsPin, 1) ; | |||||
sendDataCmd (lcd, data) ; | |||||
} | |||||
/* | |||||
* lcdPuts: | |||||
* Send a string to be displayed on the display | |||||
********************************************************************************* | |||||
*/ | |||||
void lcdPuts (int fd, char *string) | |||||
{ | |||||
while (*string) | |||||
lcdPutchar (fd, *string++) ; | |||||
} | |||||
/* | |||||
* lcdPrintf: | |||||
* Printf to an LCD display | |||||
********************************************************************************* | |||||
*/ | |||||
void lcdPrintf (int fd, char *message, ...) | |||||
{ | |||||
va_list argp ; | |||||
char buffer [1024] ; | |||||
va_start (argp, message) ; | |||||
vsnprintf (buffer, 1023, message, argp) ; | |||||
va_end (argp) ; | |||||
lcdPuts (fd, buffer) ; | |||||
} | |||||
/* | |||||
* lcdInit: | |||||
* Take a lot of parameters and initialise the LCD, and return a handle to | |||||
* that LCD, or -1 if any error. | |||||
********************************************************************************* | |||||
*/ | |||||
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) | |||||
{ | |||||
static int initialised = 0 ; | |||||
uint8_t func ; | |||||
int i ; | |||||
int lcdFd = -1 ; | |||||
struct lcdDataStruct *lcd ; | |||||
if (initialised == 0) | |||||
{ | |||||
initialised = 1 ; | |||||
for (i = 0 ; i < MAX_LCDS ; ++i) | |||||
lcds [i] = NULL ; | |||||
} | |||||
// Simple sanity checks | |||||
if (! ((bits == 4) || (bits == 8))) | |||||
return -1 ; | |||||
if ((rows < 0) || (rows > 20)) | |||||
return -1 ; | |||||
if ((cols < 0) || (cols > 20)) | |||||
return -1 ; | |||||
// Create a new LCD: | |||||
for (i = 0 ; i < MAX_LCDS ; ++i) | |||||
{ | |||||
if (lcds [i] == NULL) | |||||
{ | |||||
lcdFd = i ; | |||||
break ; | |||||
} | |||||
} | |||||
if (lcdFd == -1) | |||||
return -1 ; | |||||
lcd = malloc (sizeof (struct lcdDataStruct)) ; | |||||
if (lcd == NULL) | |||||
return -1 ; | |||||
lcd->rsPin = rs ; | |||||
lcd->strbPin = strb ; | |||||
lcd->bits = 8 ; // For now - we'll set it properly later. | |||||
lcd->rows = rows ; | |||||
lcd->cols = cols ; | |||||
lcd->dataPins [0] = d0 ; | |||||
lcd->dataPins [1] = d1 ; | |||||
lcd->dataPins [2] = d2 ; | |||||
lcd->dataPins [3] = d3 ; | |||||
lcd->dataPins [4] = d4 ; | |||||
lcd->dataPins [5] = d5 ; | |||||
lcd->dataPins [6] = d6 ; | |||||
lcd->dataPins [7] = d7 ; | |||||
lcds [lcdFd] = lcd ; | |||||
digitalWrite (lcd->rsPin, 0) ; pinMode (lcd->rsPin, OUTPUT) ; | |||||
digitalWrite (lcd->strbPin, 0) ; pinMode (lcd->strbPin, OUTPUT) ; | |||||
for (i = 0 ; i < bits ; ++i) | |||||
{ | |||||
digitalWrite (lcd->dataPins [i], 0) ; | |||||
pinMode (lcd->dataPins [i], OUTPUT) ; | |||||
} | |||||
delay (35) ; // mS | |||||
// 4-bit mode? | |||||
// OK. This is a PIG and it's not at all obvious from the documentation I had, | |||||
// so I guess some others have worked through either with better documentation | |||||
// or more trial and error... Anyway here goes: | |||||
// | |||||
// It seems that the controller needs to see the FUNC command at least 3 times | |||||
// consecutively - in 8-bit mode. If you're only using 8-bit mode, then it appears | |||||
// that you can get away with one func-set, however I'd not rely on it... | |||||
// | |||||
// So to set 4-bit mode, you need to send the commands one nibble at a time, | |||||
// the same three times, but send the command to set it into 8-bit mode those | |||||
// three times, then send a final 4th command to set it into 4-bit mode, and only | |||||
// then can you flip the switch for the rest of the library to work in 4-bit | |||||
// mode which sends the commands as 2 x 4-bit values. | |||||
if (bits == 4) | |||||
{ | |||||
func = LCD_FUNC | LCD_FUNC_DL ; // Set 8-bit mode 3 times | |||||
put4Command (lcd, func >> 4) ; delay (35) ; | |||||
put4Command (lcd, func >> 4) ; delay (35) ; | |||||
put4Command (lcd, func >> 4) ; delay (35) ; | |||||
func = LCD_FUNC ; // 4th set: 4-bit mode | |||||
put4Command (lcd, func >> 4) ; delay (35) ; | |||||
lcd->bits = 4 ; | |||||
} | |||||
else | |||||
{ | |||||
func = LCD_FUNC | LCD_FUNC_DL ; | |||||
putCommand (lcd, func ) ; delay (35) ; | |||||
putCommand (lcd, func ) ; delay (35) ; | |||||
putCommand (lcd, func ) ; delay (35) ; | |||||
} | |||||
if (lcd->rows > 1) | |||||
{ | |||||
func |= LCD_FUNC_N ; | |||||
putCommand (lcd, func) ; delay (35) ; | |||||
} | |||||
// Rest of the initialisation sequence | |||||
putCommand (lcd, LCD_ON_OFF | LCD_ON_OFF_D) ; delay (2) ; | |||||
putCommand (lcd, LCD_ENTRY | LCD_ENTRY_ID) ; delay (2) ; | |||||
putCommand (lcd, LCD_CDSHIFT | LCD_CDSHIFT_RL) ; delay (2) ; | |||||
putCommand (lcd, LCD_CLEAR) ; delay (5) ; | |||||
return lcdFd ; | |||||
} |
@@ -1,46 +0,0 @@ | |||||
/* | |||||
* lcd.h: | |||||
* Text-based LCD driver. | |||||
* This is designed to drive the parallel interface LCD drivers | |||||
* based in the Hitachi HD44780U controller and compatables. | |||||
* | |||||
* 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_LCDS 8 | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
extern void lcdHome (int fd) ; | |||||
extern void lcdClear (int fd) ; | |||||
extern void lcdSendCommand (int fd, uint8_t command) ; | |||||
extern void lcdPosition (int fd, int x, int y) ; | |||||
extern void lcdPutchar (int fd, uint8_t data) ; | |||||
extern void lcdPuts (int fd, char *string) ; | |||||
extern void lcdPrintf (int fd, char *message, ...) ; | |||||
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 |
@@ -1,113 +0,0 @@ | |||||
/* | |||||
* 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 ; | |||||
} |
@@ -1,45 +0,0 @@ | |||||
/* | |||||
* 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 |
@@ -1,89 +0,0 @@ | |||||
/* | |||||
* q2w.c: | |||||
*********************************************************************** | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <string.h> | |||||
#include <errno.h> | |||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
#include <wiringPi.h> | |||||
#include <wiringPiI2C.h> | |||||
// MCP23S17 Registers | |||||
#define IOCON 0x0A | |||||
#define IODIRA 0x00 | |||||
#define IPOLA 0x02 | |||||
#define GPINTENA 0x04 | |||||
#define DEFVALA 0x06 | |||||
#define INTCONA 0x08 | |||||
#define GPPUA 0x0C | |||||
#define INTFA 0x0E | |||||
#define INTCAPA 0x10 | |||||
#define GPIOA 0x12 | |||||
#define OLATA 0x14 | |||||
#define IODIRB 0x01 | |||||
#define IPOLB 0x03 | |||||
#define GPINTENB 0x05 | |||||
#define DEFVALB 0x07 | |||||
#define INTCONB 0x09 | |||||
#define GPPUB 0x0D | |||||
#define INTFB 0x0F | |||||
#define INTCAPB 0x11 | |||||
#define GPIOB 0x13 | |||||
#define OLATB 0x15 | |||||
// Bits in the IOCON register | |||||
#define IOCON_BANK_MODE 0x80 | |||||
#define IOCON_MIRROR 0x40 | |||||
#define IOCON_SEQOP 0x20 | |||||
#define IOCON_DISSLW 0x10 | |||||
#define IOCON_HAEN 0x08 | |||||
#define IOCON_ODR 0x04 | |||||
#define IOCON_INTPOL 0x02 | |||||
#define IOCON_UNUSED 0x01 | |||||
// Default initialisation mode | |||||
#define IOCON_INIT (IOCON_SEQOP) | |||||
/* | |||||
********************************************************************************* | |||||
* The works | |||||
********************************************************************************* | |||||
*/ | |||||
int main (int argc, char *argv []) | |||||
{ | |||||
int q2w ; | |||||
// if (wiringPiSetup () == -1) | |||||
// { fprintf (stderr, "q2w: Unable to initialise wiringPi: %s\n", strerror (errno)) ; return 1 ; } | |||||
if ((q2w = wiringPiI2CSetup (0x20)) == -1) | |||||
{ fprintf (stderr, "q2w: Unable to initialise I2C: %s\n", strerror (errno)) ; return 1 ; } | |||||
// Very simple direct control of the MCP23017: | |||||
wiringPiI2CWriteReg8 (q2w, IOCON, IOCON_INIT) ; | |||||
wiringPiI2CWriteReg8 (q2w, IODIRA, 0x00) ; // Port A -> Outputs | |||||
wiringPiI2CWriteReg8 (q2w, IODIRB, 0x00) ; // Port B -> Outputs | |||||
for (;;) | |||||
{ | |||||
wiringPiI2CWriteReg8 (q2w, GPIOA, 0x00) ; // All Off | |||||
delay (500) ; | |||||
wiringPiI2CWriteReg8 (q2w, GPIOA, 0xFF) ; // All On | |||||
delay (500) ; | |||||
} | |||||
return 0 ; | |||||
} |
@@ -1,362 +0,0 @@ | |||||
/* | |||||
* wiringPiFace: | |||||
* Arduino compatable (ish) Wiring library for the Raspberry Pi | |||||
* Copyright (c) 2012 Gordon Henderson | |||||
* | |||||
* This file to interface with the PiFace peripheral device which | |||||
* has an MCP23S17 GPIO device connected via the SPI bus. | |||||
* | |||||
*********************************************************************** | |||||
* 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 <sys/types.h> | |||||
#include <linux/spi/spidev.h> | |||||
#include "wiringPi.h" | |||||
// The SPI bus parameters | |||||
// Variables as they need to be passed as pointers later on | |||||
static char *spiDevice = "/dev/spidev0.0" ; | |||||
static uint8_t spiMode = 0 ; | |||||
static uint8_t spiBPW = 8 ; | |||||
static uint32_t spiSpeed = 5000000 ; | |||||
static uint16_t spiDelay = 0; | |||||
// Locals here to keep track of everything | |||||
static int spiFd ; | |||||
// The MCP23S17 doesn't have bit-set operations, so it's | |||||
// cheaper to keep a copy here than to read/modify/write it | |||||
uint8_t dataOutRegister = 0 ; | |||||
uint8_t pudRegister = 0 ; | |||||
// MCP23S17 Registers | |||||
#define IOCON 0x0A | |||||
#define IODIRA 0x00 | |||||
#define IPOLA 0x02 | |||||
#define GPINTENA 0x04 | |||||
#define DEFVALA 0x06 | |||||
#define INTCONA 0x08 | |||||
#define GPPUA 0x0C | |||||
#define INTFA 0x0E | |||||
#define INTCAPA 0x10 | |||||
#define GPIOA 0x12 | |||||
#define OLATA 0x14 | |||||
#define IODIRB 0x01 | |||||
#define IPOLB 0x03 | |||||
#define GPINTENB 0x05 | |||||
#define DEFVALB 0x07 | |||||
#define INTCONB 0x09 | |||||
#define GPPUB 0x0D | |||||
#define INTFB 0x0F | |||||
#define INTCAPB 0x11 | |||||
#define GPIOB 0x13 | |||||
#define OLATB 0x15 | |||||
// Bits in the IOCON register | |||||
#define IOCON_BANK_MODE 0x80 | |||||
#define IOCON_MIRROR 0x40 | |||||
#define IOCON_SEQOP 0x20 | |||||
#define IOCON_DISSLW 0x10 | |||||
#define IOCON_HAEN 0x08 | |||||
#define IOCON_ODR 0x04 | |||||
#define IOCON_INTPOL 0x02 | |||||
#define IOCON_UNUSED 0x01 | |||||
// Default initialisation mode | |||||
#define IOCON_INIT (IOCON_SEQOP) | |||||
// Command codes | |||||
#define CMD_WRITE 0x40 | |||||
#define CMD_READ 0x41 | |||||
/* | |||||
* writeByte: | |||||
* Write a byte to a register on the MCP23S17 on the SPI bus. | |||||
* This is using the synchronous access mechanism. | |||||
********************************************************************************* | |||||
*/ | |||||
static void writeByte (uint8_t reg, uint8_t data) | |||||
{ | |||||
uint8_t spiBufTx [3] ; | |||||
uint8_t spiBufRx [3] ; | |||||
struct spi_ioc_transfer spi ; | |||||
spiBufTx [0] = CMD_WRITE ; | |||||
spiBufTx [1] = reg ; | |||||
spiBufTx [2] = data ; | |||||
spi.tx_buf = (unsigned long)spiBufTx ; | |||||
spi.rx_buf = (unsigned long)spiBufRx ; | |||||
spi.len = 3 ; | |||||
spi.delay_usecs = spiDelay ; | |||||
spi.speed_hz = spiSpeed ; | |||||
spi.bits_per_word = spiBPW ; | |||||
ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ; | |||||
} | |||||
/* | |||||
* readByte: | |||||
* Read a byte from a register on the MCP23S17 on the SPI bus. | |||||
* This is the synchronous access mechanism. | |||||
* What appears to happen is that the data returned is at | |||||
* the same offset as the number of bytes written to the device. So if we | |||||
* write 2 bytes (e.g. command then register number), then the data returned | |||||
* will by at the 3rd byte... | |||||
********************************************************************************* | |||||
*/ | |||||
static uint8_t readByte (uint8_t reg) | |||||
{ | |||||
uint8_t tx [4] ; | |||||
uint8_t rx [4] ; | |||||
struct spi_ioc_transfer spi ; | |||||
tx [0] = CMD_READ ; | |||||
tx [1] = reg ; | |||||
tx [2] = 0 ; | |||||
spi.tx_buf = (unsigned long)tx ; | |||||
spi.rx_buf = (unsigned long)rx ; | |||||
spi.len = 3 ; | |||||
spi.delay_usecs = spiDelay ; | |||||
spi.speed_hz = spiSpeed ; | |||||
spi.bits_per_word = spiBPW ; | |||||
ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ; | |||||
return rx [2] ; | |||||
} | |||||
/* | |||||
* digitalWritePiFace: | |||||
* Perform the digitalWrite function on the PiFace board | |||||
********************************************************************************* | |||||
*/ | |||||
void digitalWritePiFace (int pin, int value) | |||||
{ | |||||
uint8_t mask = 1 << pin ; | |||||
if (value == 0) | |||||
dataOutRegister &= (~mask) ; | |||||
else | |||||
dataOutRegister |= mask ; | |||||
writeByte (GPIOA, dataOutRegister) ; | |||||
} | |||||
void digitalWriteBytePiFace (int value) | |||||
{ | |||||
writeByte (GPIOA, value) ; | |||||
} | |||||
void digitalWritePiFaceSpecial (int pin, int value) | |||||
{ | |||||
uint8_t mask = 1 << pin ; | |||||
uint8_t old ; | |||||
old = readByte (GPIOA) ; | |||||
if (value == 0) | |||||
old &= (~mask) ; | |||||
else | |||||
old |= mask ; | |||||
writeByte (GPIOA, old) ; | |||||
} | |||||
/* | |||||
* digitalReadPiFace: | |||||
* Perform the digitalRead function on the PiFace board | |||||
********************************************************************************* | |||||
*/ | |||||
int digitalReadPiFace (int pin) | |||||
{ | |||||
uint8_t mask = 1 << pin ; | |||||
if ((readByte (GPIOB) & mask) != 0) | |||||
return HIGH ; | |||||
else | |||||
return LOW ; | |||||
} | |||||
/* | |||||
* pullUpDnControlPiFace: | |||||
* Perform the pullUpDnControl function on the PiFace board | |||||
********************************************************************************* | |||||
*/ | |||||
void pullUpDnControlPiFace (int pin, int pud) | |||||
{ | |||||
uint8_t mask = 1 << pin ; | |||||
if (pud == PUD_UP) | |||||
pudRegister |= mask ; | |||||
else | |||||
pudRegister &= (~mask) ; | |||||
writeByte (GPPUB, pudRegister) ; | |||||
} | |||||
void pullUpDnControlPiFaceSpecial (int pin, int pud) | |||||
{ | |||||
uint8_t mask = 1 << pin ; | |||||
uint8_t old ; | |||||
old = readByte (GPPUB) ; | |||||
if (pud == PUD_UP) | |||||
old |= mask ; | |||||
else | |||||
old &= (~mask) ; | |||||
writeByte (GPPUB, old) ; | |||||
} | |||||
/* | |||||
* Dummy functions that are not used in this mode | |||||
********************************************************************************* | |||||
*/ | |||||
void pinModePiFace (int pin, int mode) {} | |||||
void pwmWritePiFace (int pin, int value) {} | |||||
int waitForInterruptPiFace (int pin, int mS) { return 0 ; } | |||||
/* | |||||
* wiringPiSetupPiFace | |||||
* Setup the SPI interface and initialise the MCP23S17 chip | |||||
********************************************************************************* | |||||
*/ | |||||
static int _wiringPiSetupPiFace (void) | |||||
{ | |||||
if ((spiFd = open (spiDevice, O_RDWR)) < 0) | |||||
return -1 ; | |||||
// Set SPI parameters | |||||
// Why are we doing a read after write? | |||||
// I don't know - just blindliy copying an example elsewhere... -GH- | |||||
if (ioctl (spiFd, SPI_IOC_WR_MODE, &spiMode) < 0) | |||||
return -1 ; | |||||
if (ioctl (spiFd, SPI_IOC_RD_MODE, &spiMode) < 0) | |||||
return -1 ; | |||||
if (ioctl (spiFd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) | |||||
return -1 ; | |||||
if (ioctl (spiFd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0) | |||||
return -1 ; | |||||
if (ioctl (spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed) < 0) | |||||
return -1 ; | |||||
if (ioctl (spiFd, SPI_IOC_RD_MAX_SPEED_HZ, &spiSpeed) < 0) | |||||
return -1 ; | |||||
// Setup the MCP23S17 | |||||
writeByte (IOCON, IOCON_INIT) ; | |||||
writeByte (IODIRA, 0x00) ; // Port A -> Outputs | |||||
writeByte (IODIRB, 0xFF) ; // Port B -> Inputs | |||||
return 0 ; | |||||
} | |||||
int wiringPiSetupPiFace (void) | |||||
{ | |||||
int x = _wiringPiSetupPiFace () ; | |||||
if (x != 0) | |||||
return x ; | |||||
writeByte (GPIOA, 0x00) ; // Set all outptus off | |||||
writeByte (GPPUB, 0x00) ; // Disable any pull-ups on port B | |||||
pinMode = pinModePiFace ; | |||||
pullUpDnControl = pullUpDnControlPiFace ; | |||||
digitalWrite = digitalWritePiFace ; | |||||
digitalWriteByte = digitalWriteBytePiFace ; | |||||
pwmWrite = pwmWritePiFace ; | |||||
digitalRead = digitalReadPiFace ; | |||||
waitForInterrupt = waitForInterruptPiFace ; | |||||
return 0 ; | |||||
} | |||||
/* | |||||
* wiringPiSetupPiFaceForGpioProg: | |||||
* Setup the SPI interface and initialise the MCP23S17 chip | |||||
* Special version for the gpio program | |||||
********************************************************************************* | |||||
*/ | |||||
int wiringPiSetupPiFaceForGpioProg (void) | |||||
{ | |||||
int x = _wiringPiSetupPiFace () ; | |||||
if (x != 0) | |||||
return x ; | |||||
pinMode = pinModePiFace ; | |||||
pullUpDnControl = pullUpDnControlPiFaceSpecial ; | |||||
digitalWrite = digitalWritePiFaceSpecial ; | |||||
digitalWriteByte = digitalWriteBytePiFace ; | |||||
pwmWrite = pwmWritePiFace ; | |||||
digitalRead = digitalReadPiFace ; | |||||
waitForInterrupt = waitForInterruptPiFace ; | |||||
return 0 ; | |||||
} |