Added gertboard examples. just for reference.
This commit is contained in:
commit
34144ee1d4
|
@ -0,0 +1 @@
|
||||||
|
*.o
|
|
@ -0,0 +1,5 @@
|
||||||
|
Gertboard test/example software
|
||||||
|
|
||||||
|
Type "make all" to compile all the examples. Each program will print
|
||||||
|
out a description of what connections need to be made on the Gertboard
|
||||||
|
to run them.
|
|
@ -0,0 +1,126 @@
|
||||||
|
//
|
||||||
|
// Gertboard Demo
|
||||||
|
//
|
||||||
|
// SPI (ADC/DAC) control code
|
||||||
|
//
|
||||||
|
// This code is part of the Gertboard test suite
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Try to strike a balance between keep code simple for
|
||||||
|
// novice programmers but still have reasonable quality code
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
#include "gb_spi.h"
|
||||||
|
#include <time.h>
|
||||||
|
// Set GPIO pins to the right mode
|
||||||
|
// DEMO GPIO mapping:
|
||||||
|
// Function Mode
|
||||||
|
// GPIO0= unused
|
||||||
|
// GPIO1= unused
|
||||||
|
// GPIO4= unused
|
||||||
|
// GPIO7= unused
|
||||||
|
// GPIO8= SPI chip select A Alt. 0
|
||||||
|
// GPIO9= SPI MISO Alt. 0
|
||||||
|
// GPIO10= SPI MOSI Alt. 0
|
||||||
|
// GPIO11= SPI CLK Alt. 0
|
||||||
|
// GPIO14= unused
|
||||||
|
// GPIO15= unused
|
||||||
|
// GPIO17= unused
|
||||||
|
// GPIO18= unused
|
||||||
|
// GPIO21= unused
|
||||||
|
// GPIO22= unused
|
||||||
|
// GPIO23= unused
|
||||||
|
// GPIO24= unused
|
||||||
|
// GPIO25= unused
|
||||||
|
//
|
||||||
|
|
||||||
|
// For A to D we only need the SPI bus and SPI chip select A
|
||||||
|
void setup_gpio()
|
||||||
|
{
|
||||||
|
INP_GPIO(8); SET_GPIO_ALT(8,0);
|
||||||
|
INP_GPIO(9); SET_GPIO_ALT(9,0);
|
||||||
|
INP_GPIO(10); SET_GPIO_ALT(10,0);
|
||||||
|
INP_GPIO(11); SET_GPIO_ALT(11,0);
|
||||||
|
} // setup_gpio
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read ADC input 0 and show as horizontal bar
|
||||||
|
//
|
||||||
|
void main(void)
|
||||||
|
{ int r, v, s, i, chan;
|
||||||
|
|
||||||
|
do {
|
||||||
|
printf ("Which channel do you want to test? Type 0 or 1.\n");
|
||||||
|
chan = (int) getchar();
|
||||||
|
(void) getchar(); // eat carriage return
|
||||||
|
} while (chan != '0' && chan != '1');
|
||||||
|
chan = chan - '0';
|
||||||
|
|
||||||
|
printf ("These are the connections for the analogue to digital test:\n");
|
||||||
|
printf ("jumper connecting GP11 to SCLK\n");
|
||||||
|
printf ("jumper connecting GP10 to MOSI\n");
|
||||||
|
printf ("jumper connecting GP9 to MISO\n");
|
||||||
|
printf ("jumper connecting GP8 to CSnA\n");
|
||||||
|
printf ("Potentiometer connections:\n");
|
||||||
|
printf (" (call 1 and 3 the ends of the resistor and 2 the wiper)\n");
|
||||||
|
printf (" connect 3 to 3V3\n");
|
||||||
|
printf (" connect 2 to AD%d\n", chan);
|
||||||
|
printf (" connect 1 to GND\n");
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
// Map the I/O sections
|
||||||
|
setup_io();
|
||||||
|
|
||||||
|
// activate SPI bus pins
|
||||||
|
setup_gpio();
|
||||||
|
|
||||||
|
// Setup SPI bus
|
||||||
|
setup_spi();
|
||||||
|
|
||||||
|
// The value returned by the A to D can jump around quite a bit, so
|
||||||
|
// simply printing out the value isn't very useful. The bar graph
|
||||||
|
// is better because this hides the noise in the signal.
|
||||||
|
|
||||||
|
clock_t t,f;
|
||||||
|
|
||||||
|
// for (r=0; r<100000; r++)
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
v= read_adc(chan);
|
||||||
|
// V should be in range 0-1023
|
||||||
|
// map to 0-63
|
||||||
|
//s = v >> 4;
|
||||||
|
//printf("%04d;%f;%d\n",v,((float)f)/CLOCKS_PER_SEC,f);
|
||||||
|
printf("%d %d %f %f ",v,v/2,(v/2)*2.54,v*(6.45/512));
|
||||||
|
/*/ show horizontal bar
|
||||||
|
for (i = 0; i < s; i++)
|
||||||
|
putchar('#');
|
||||||
|
for (i = 0; i < 64 - s; i++)
|
||||||
|
putchar(' ');*/
|
||||||
|
putchar(0x0D); // go to start of the line*/
|
||||||
|
short_wait();
|
||||||
|
} // repeated read
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
restore_io();
|
||||||
|
} // main
|
|
@ -0,0 +1,144 @@
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Buttons_test
|
||||||
|
//
|
||||||
|
// main file
|
||||||
|
//
|
||||||
|
// This file is part of the gertboard test suite
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set GPIO pins to the right mode
|
||||||
|
// button test GPIO mapping:
|
||||||
|
// Function Mode
|
||||||
|
// GPIO0= unused
|
||||||
|
// GPIO1= unused
|
||||||
|
// GPIO4= unused
|
||||||
|
// GPIO7= unused
|
||||||
|
// GPIO8= unused
|
||||||
|
// GPIO9= unused
|
||||||
|
// GPIO10= unused
|
||||||
|
// GPIO11= unused
|
||||||
|
// GPIO14= unused
|
||||||
|
// GPIO15= unused
|
||||||
|
// GPIO17= unused
|
||||||
|
// GPIO18= unused
|
||||||
|
// GPIO21= unused
|
||||||
|
// GPIO22= LED Input
|
||||||
|
// GPIO23= Pushbutton (B3) Input
|
||||||
|
// GPIO24= unused
|
||||||
|
// GPIO25= unused
|
||||||
|
//
|
||||||
|
// Always call INP_GPIO(x) first
|
||||||
|
// as that is how the macros work
|
||||||
|
void setup_gpio()
|
||||||
|
{
|
||||||
|
// for this test we are only using GP22, & 23
|
||||||
|
INP_GPIO(22);
|
||||||
|
INP_GPIO(23);
|
||||||
|
|
||||||
|
// enable pull-up on GPIO 23 set pull to 2 (code for pull high)
|
||||||
|
GPIO_PULL = 2;
|
||||||
|
short_wait();
|
||||||
|
// setting bit 23 below means that the GPIO_PULL is applied to GPIO 23
|
||||||
|
GPIO_PULLCLK0 = 0x00800000;
|
||||||
|
short_wait();
|
||||||
|
GPIO_PULL = 0;
|
||||||
|
GPIO_PULLCLK0 = 0;
|
||||||
|
} // setup_gpio
|
||||||
|
|
||||||
|
// remove pulling on pins so they can be used for somnething else next time
|
||||||
|
// gertboard is used
|
||||||
|
void unpull_pins()
|
||||||
|
{
|
||||||
|
// to disable pull-up on GPIO 23, set pull to 0 (code for no pull)
|
||||||
|
GPIO_PULL = 0;
|
||||||
|
short_wait();
|
||||||
|
// setting bit 23 below means that the GPIO_PULL is applied to GPIO 23
|
||||||
|
GPIO_PULLCLK0 = 0x00800000;
|
||||||
|
short_wait();
|
||||||
|
GPIO_PULL = 0;
|
||||||
|
GPIO_PULLCLK0 = 0;
|
||||||
|
} // unpull_pins
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{ int r,d;
|
||||||
|
unsigned int b,prev_b;
|
||||||
|
char str [3];
|
||||||
|
|
||||||
|
printf ("These are the connections you must make on the Gertboard for this test:\n");
|
||||||
|
printf ("GP23 in J2 --- B3 in J3\n");
|
||||||
|
printf ("GP22 in J2 --- B6 in J3\n");
|
||||||
|
printf ("U3-out-B3 pin 1 --- BUF6 in top header\n");
|
||||||
|
printf ("jumper on U4-in-B6\n");
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
// Map the I/O sections
|
||||||
|
setup_io();
|
||||||
|
|
||||||
|
// Set GPIO pins 23, 24, and 25 to the required mode
|
||||||
|
setup_gpio();
|
||||||
|
|
||||||
|
// read the switches a number of times and print out the result
|
||||||
|
|
||||||
|
/* below we set prev_b to a number which will definitely be different
|
||||||
|
from what the switches returns, as after shift & mask, b can only
|
||||||
|
be in range 0..7 */
|
||||||
|
prev_b = 8;
|
||||||
|
|
||||||
|
r = 20; // number of repeats
|
||||||
|
|
||||||
|
while (r)
|
||||||
|
{
|
||||||
|
b = GPIO_IN0;
|
||||||
|
b = (b >> 22 ) & 0x03; // keep only bits 22 & 23
|
||||||
|
if (b^prev_b)
|
||||||
|
{ // one or more buttons changed
|
||||||
|
make_binary_string(2, b, str);
|
||||||
|
printf("%s\n", str);
|
||||||
|
prev_b = b;
|
||||||
|
r--;
|
||||||
|
} // change
|
||||||
|
} // while
|
||||||
|
|
||||||
|
// disable pull up on pins & unmap gpio
|
||||||
|
unpull_pins();
|
||||||
|
restore_io();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} // main
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Buttons_test
|
||||||
|
//
|
||||||
|
// main file
|
||||||
|
//
|
||||||
|
// This file is part of the gertboard test suite
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set GPIO pins to the right mode
|
||||||
|
// button test GPIO mapping:
|
||||||
|
// Function Mode
|
||||||
|
// GPIO0= unused
|
||||||
|
// GPIO1= unused
|
||||||
|
// GPIO4= unused
|
||||||
|
// GPIO7= unused
|
||||||
|
// GPIO8= unused
|
||||||
|
// GPIO9= unused
|
||||||
|
// GPIO10= unused
|
||||||
|
// GPIO11= unused
|
||||||
|
// GPIO14= unused
|
||||||
|
// GPIO15= unused
|
||||||
|
// GPIO17= unused
|
||||||
|
// GPIO18= unused
|
||||||
|
// GPIO21= unused
|
||||||
|
// GPIO22= unused
|
||||||
|
// GPIO23= Pushbutton (B3) Input
|
||||||
|
// GPIO24= Pushbutton (B2) Input
|
||||||
|
// GPIO25= Pushbutton (B1) Input
|
||||||
|
//
|
||||||
|
// Always call INP_GPIO(x) first
|
||||||
|
// as that is how the macros work
|
||||||
|
void setup_gpio()
|
||||||
|
{
|
||||||
|
// for this test we are only using GP23, 24, & 25
|
||||||
|
INP_GPIO(23);
|
||||||
|
INP_GPIO(24);
|
||||||
|
INP_GPIO(25);
|
||||||
|
|
||||||
|
// enable pull-up on GPIO 23,24&25, set pull to 2 (code for pull high)
|
||||||
|
GPIO_PULL = 2;
|
||||||
|
short_wait();
|
||||||
|
// setting bits 23, 24 & 25 below means that the GPIO_PULL is applied to
|
||||||
|
// GPIO 23, 24, & 25
|
||||||
|
GPIO_PULLCLK0 = 0x03800000;
|
||||||
|
short_wait();
|
||||||
|
GPIO_PULL = 0;
|
||||||
|
GPIO_PULLCLK0 = 0;
|
||||||
|
} // setup_gpio
|
||||||
|
|
||||||
|
// remove pulling on pins so they can be used for somnething else next time
|
||||||
|
// gertboard is used
|
||||||
|
void unpull_pins()
|
||||||
|
{
|
||||||
|
// disable pull-up on GPIO 23,24&25, set pull to 0 (code for no pull)
|
||||||
|
GPIO_PULL = 0;
|
||||||
|
short_wait();
|
||||||
|
// setting bits 23, 24 & 25 below means that the GPIO_PULL is applied to
|
||||||
|
// GPIO 23, 24, & 25
|
||||||
|
GPIO_PULLCLK0 = 0x03800000;
|
||||||
|
short_wait();
|
||||||
|
GPIO_PULL = 0;
|
||||||
|
GPIO_PULLCLK0 = 0;
|
||||||
|
} // unpull_pins
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{ int r,d;
|
||||||
|
unsigned int b,prev_b;
|
||||||
|
char str [4];
|
||||||
|
|
||||||
|
printf ("These are the connections for the buttons test:\n");
|
||||||
|
printf ("GP25 in J2 --- B1 in J3\n");
|
||||||
|
printf ("GP24 in J2 --- B2 in J3\n");
|
||||||
|
printf ("GP23 in J2 --- B3 in J3\n");
|
||||||
|
printf ("Optionally, if you want the LEDs to reflect button state do the following:\n");
|
||||||
|
printf ("jumper on U3-out-B1\n");
|
||||||
|
printf ("jumper on U3-out-B2\n");
|
||||||
|
printf ("jumper on U3-out-B3\n");
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
// Map the I/O sections
|
||||||
|
setup_io();
|
||||||
|
|
||||||
|
// Set GPIO pins 23, 24, and 25 to the required mode
|
||||||
|
setup_gpio();
|
||||||
|
|
||||||
|
// read the switches a number of times and print out the result
|
||||||
|
|
||||||
|
/* below we set prev_b to a number which will definitely be different
|
||||||
|
from what the switches returns, as after shift & mask, b can only
|
||||||
|
be in range 0..7 */
|
||||||
|
prev_b = 8;
|
||||||
|
|
||||||
|
r = 20; // number of repeats
|
||||||
|
|
||||||
|
while (r)
|
||||||
|
{
|
||||||
|
b = GPIO_IN0;
|
||||||
|
b = (b >> 23 ) & 0x07; // keep only bits 23, 24 & 25
|
||||||
|
if (b^prev_b)
|
||||||
|
{ // one or more buttons changed
|
||||||
|
make_binary_string(3, b, str);
|
||||||
|
printf("%s\n", str);
|
||||||
|
prev_b = b;
|
||||||
|
r--;
|
||||||
|
} // change
|
||||||
|
} // while
|
||||||
|
|
||||||
|
// disable pull up on pins & unmap gpio
|
||||||
|
unpull_pins();
|
||||||
|
restore_io();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} // main
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
//
|
||||||
|
// Gertboard Demo
|
||||||
|
//
|
||||||
|
// SPI (ADC/DAC) control code
|
||||||
|
//
|
||||||
|
// This code is part of the Gertboard test suite
|
||||||
|
// These routines access the AD and DA chips
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Try to strike a balance between keep code simple for
|
||||||
|
// novice programmers but still have reasonable quality code
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
#include "gb_spi.h"
|
||||||
|
|
||||||
|
// Set GPIO pins to the right mode
|
||||||
|
// dad (digital-analogue-digital) GPIO mapping:
|
||||||
|
// Function Mode
|
||||||
|
// GPIO0= unused
|
||||||
|
// GPIO1= unused
|
||||||
|
// GPIO4= unused
|
||||||
|
// GPIO7= SPI chip select B Alt. 0
|
||||||
|
// GPIO8= SPI chip select A Alt. 0
|
||||||
|
// GPIO9= SPI MISO Alt. 0
|
||||||
|
// GPIO10= SPI MOSI Alt. 0
|
||||||
|
// GPIO11= SPI CLK Alt. 0
|
||||||
|
// GPIO14= unused
|
||||||
|
// GPIO15= unused
|
||||||
|
// GPIO17= unused
|
||||||
|
// GPIO18= unused
|
||||||
|
// GPIO21= unused
|
||||||
|
// GPIO22= unused
|
||||||
|
// GPIO23= unused
|
||||||
|
// GPIO24= unused
|
||||||
|
// GPIO25= unused
|
||||||
|
//
|
||||||
|
|
||||||
|
// For A to D and D to A we need the SPI bus and SPI chip selects A & B
|
||||||
|
void setup_gpio()
|
||||||
|
{
|
||||||
|
INP_GPIO(7); SET_GPIO_ALT(7,0);
|
||||||
|
INP_GPIO(8); SET_GPIO_ALT(8,0);
|
||||||
|
INP_GPIO(9); SET_GPIO_ALT(9,0);
|
||||||
|
INP_GPIO(10); SET_GPIO_ALT(10,0);
|
||||||
|
INP_GPIO(11); SET_GPIO_ALT(11,0);
|
||||||
|
} // setup_gpio
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Do digital to analogue to digital conversion
|
||||||
|
//
|
||||||
|
void main(void)
|
||||||
|
{ int d, dac_val, v, s, i;
|
||||||
|
|
||||||
|
printf ("These are the connections for the digital to analogue to digital test:\n");
|
||||||
|
printf ("jumper connecting GP11 to SCLK\n");
|
||||||
|
printf ("jumper connecting GP10 to MOSI\n");
|
||||||
|
printf ("jumper connecting GP9 to MISO\n");
|
||||||
|
printf ("jumper connecting GP8 to CSnA\n");
|
||||||
|
printf ("jumper connecting GP7 to CSnB\n");
|
||||||
|
printf ("jumper connecting DA1 on J29 to AD0 on J28\n");
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
// Map the I/O sections
|
||||||
|
setup_io();
|
||||||
|
|
||||||
|
// activate SPI bus pins
|
||||||
|
setup_gpio();
|
||||||
|
|
||||||
|
// Setup SPI bus
|
||||||
|
setup_spi();
|
||||||
|
|
||||||
|
// The value returned by the A to D can jump around quite a bit, so
|
||||||
|
// simply printing out the value isn't very useful. The bar graph
|
||||||
|
// is better because this hides the noise in the signal.
|
||||||
|
|
||||||
|
printf ("dig ana\n");
|
||||||
|
for (d=0; d <= 256; d+= 32)
|
||||||
|
{
|
||||||
|
if (d == 256)
|
||||||
|
dac_val = 255 * 16;
|
||||||
|
else
|
||||||
|
dac_val = d * 16;
|
||||||
|
write_dac(1, dac_val);
|
||||||
|
v= read_adc(0);
|
||||||
|
// v should be in range 0-1023
|
||||||
|
// map to 0-63
|
||||||
|
s = v >> 4;
|
||||||
|
printf("%3x %04d ", dac_val, v);
|
||||||
|
// show horizontal bar
|
||||||
|
for (i = 0; i < s; i++)
|
||||||
|
putchar('#');
|
||||||
|
for (i = 0; i < 64 - s; i++)
|
||||||
|
putchar(' ');
|
||||||
|
putchar('\n');
|
||||||
|
short_wait();
|
||||||
|
} // repeated write/read
|
||||||
|
for (d=224; d >= 0; d-= 32)
|
||||||
|
{
|
||||||
|
dac_val = d * 16;
|
||||||
|
write_dac(1, dac_val);
|
||||||
|
v= read_adc(0);
|
||||||
|
// v should be in range 0-1023
|
||||||
|
// map to 0-63
|
||||||
|
s = v >> 4;
|
||||||
|
printf("%3x %04d ", dac_val, v);
|
||||||
|
// show horizontal bar
|
||||||
|
for (i = 0; i < s; i++)
|
||||||
|
putchar('#');
|
||||||
|
for (i = 0; i < 64 - s; i++)
|
||||||
|
putchar(' ');
|
||||||
|
putchar('\n');
|
||||||
|
short_wait();
|
||||||
|
} // repeated write/read
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
restore_io();
|
||||||
|
} // main
|
|
@ -0,0 +1,181 @@
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Decoder: using the bottons as a binary number and turning on one of 8 LEDs
|
||||||
|
//
|
||||||
|
// main file
|
||||||
|
//
|
||||||
|
// This file is part of the gertboard test suite
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set GPIO pins to the right mode
|
||||||
|
// Decoder GPIO mapping:
|
||||||
|
// Function Mode
|
||||||
|
// GPIO0= LED (D12) Output
|
||||||
|
// GPIO1= LED (D11) Output
|
||||||
|
// GPIO4= LED (D10) Output
|
||||||
|
// GPIO7= LED (D9) Output
|
||||||
|
// GPIO8= LED (D8) Output
|
||||||
|
// GPIO9= LED (D7) Output
|
||||||
|
// GPIO10= LED (D6) Output
|
||||||
|
// GPIO11= LED (D5) Output
|
||||||
|
// GPIO14= unused
|
||||||
|
// GPIO15= unused
|
||||||
|
// GPIO17= unused
|
||||||
|
// GPIO18= unused
|
||||||
|
// GPIO21= unused
|
||||||
|
// GPIO22= unused
|
||||||
|
// GPIO23= Pushbutton (B3) Input
|
||||||
|
// GPIO24= Pushbutton (B2) Input
|
||||||
|
// GPIO25= Pushbutton (B1) Input
|
||||||
|
//
|
||||||
|
// Always call INP_GPIO(x) first
|
||||||
|
// as that is how the macros work
|
||||||
|
void setup_gpio()
|
||||||
|
{
|
||||||
|
// GP23, 24, & 25 are handling the pushbuttons
|
||||||
|
INP_GPIO(23);
|
||||||
|
INP_GPIO(24);
|
||||||
|
INP_GPIO(25);
|
||||||
|
|
||||||
|
// enable pull-up on GPIO 23,24&25, set pull to 2 (code for pull high)
|
||||||
|
GPIO_PULL = 2;
|
||||||
|
short_wait();
|
||||||
|
// setting bits 23, 24 & 25 below means that the GPIO_PULL is applied to
|
||||||
|
// GPIO 23, 24, & 25
|
||||||
|
GPIO_PULLCLK0 = 0x03800000;
|
||||||
|
short_wait();
|
||||||
|
GPIO_PULL = 0;
|
||||||
|
GPIO_PULLCLK0 = 0;
|
||||||
|
|
||||||
|
// enable the 8 GPIO pins we use for driving the LEDs
|
||||||
|
INP_GPIO(0); OUT_GPIO(0);
|
||||||
|
INP_GPIO(1); OUT_GPIO(1);
|
||||||
|
INP_GPIO(4); OUT_GPIO(4);
|
||||||
|
INP_GPIO(7); OUT_GPIO(7);
|
||||||
|
INP_GPIO(8); OUT_GPIO(8);
|
||||||
|
INP_GPIO(9); OUT_GPIO(9);
|
||||||
|
INP_GPIO(10); OUT_GPIO(10);
|
||||||
|
INP_GPIO(11); OUT_GPIO(11);
|
||||||
|
} // setup_gpio
|
||||||
|
|
||||||
|
// the led array allows us to select the LED to turn on; for example led[0] is
|
||||||
|
// the bit pattern we need to turn on D5, the leftmost LED of the ones
|
||||||
|
// we are using (and hence it is the output for 0)
|
||||||
|
static int led[] = {1<<11, 1<<10, 1 <<9, 1<<8, 1<<7, 1<<4, 1<<1, 1};
|
||||||
|
|
||||||
|
// remove pulling on pins so they can be used for somnething else next time
|
||||||
|
// gertboard is used
|
||||||
|
void unpull_pins()
|
||||||
|
{
|
||||||
|
// disable pull-up on GPIO 23,24&25, set pull to 0 (code for no pull)
|
||||||
|
GPIO_PULL = 0;
|
||||||
|
short_wait();
|
||||||
|
// setting bits 23, 24 & 25 below means that the GPIO_PULL is applied to
|
||||||
|
// GPIO 23, 24, & 25
|
||||||
|
GPIO_PULLCLK0 = 0x03800000;
|
||||||
|
short_wait();
|
||||||
|
GPIO_PULL = 0;
|
||||||
|
GPIO_PULLCLK0 = 0;
|
||||||
|
} // unpull_pins
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{ int r,d;
|
||||||
|
unsigned int b,prev_b;
|
||||||
|
char str [4];
|
||||||
|
|
||||||
|
printf ("These are the connections for the buttons test:\n");
|
||||||
|
printf ("GP25 in J2 --- B1 in J3\n");
|
||||||
|
printf ("GP24 in J2 --- B2 in J3\n");
|
||||||
|
printf ("GP23 in J2 --- B3 in J3\n");
|
||||||
|
printf ("GP11 in J2 --- B5 in J3\n");
|
||||||
|
printf ("GP10 in J2 --- B6 in J3\n");
|
||||||
|
printf ("GP9 in J2 --- B7 in J3\n");
|
||||||
|
printf ("GP8 in J2 --- B8 in J3\n");
|
||||||
|
printf ("GP7 in J2 --- B9 in J3\n");
|
||||||
|
printf ("GP4 in J2 --- B10 in J3\n");
|
||||||
|
printf ("GP1 in J2 --- B11 in J3\n");
|
||||||
|
printf ("GP0 in J2 --- B12 in J3\n");
|
||||||
|
printf ("jumper on U4-out-B5\n");
|
||||||
|
printf ("jumper on U4-out-B6\n");
|
||||||
|
printf ("jumper on U4-out-B7\n");
|
||||||
|
printf ("jumper on U4-out-B8\n");
|
||||||
|
printf ("jumper on U5-out-B9\n");
|
||||||
|
printf ("jumper on U5-out-B10\n");
|
||||||
|
printf ("jumper on U5-out-B11\n");
|
||||||
|
printf ("jumper on U5-out-B12\n");
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
// Map the I/O sections
|
||||||
|
setup_io();
|
||||||
|
|
||||||
|
// Set GPIO pins 23, 24, and 25 to the required mode
|
||||||
|
setup_gpio();
|
||||||
|
|
||||||
|
// read the switches a number of times and light up a different LED
|
||||||
|
// to show the result
|
||||||
|
|
||||||
|
/* below we set prev_b to a 0 as it will most likely be different from
|
||||||
|
the first number we read from the buttons (user would have to have
|
||||||
|
all buttons pressed to get this value) */
|
||||||
|
prev_b = 0;
|
||||||
|
|
||||||
|
r = 40; // number of repeats
|
||||||
|
|
||||||
|
while (r)
|
||||||
|
{
|
||||||
|
b = GPIO_IN0;
|
||||||
|
b = (b >> 23 ) & 0x07; // keep only bits 23, 24 & 25
|
||||||
|
if (b^prev_b)
|
||||||
|
{ // one or more buttons changed
|
||||||
|
GPIO_CLR0 = led[prev_b]; // turn off LED for prev button setup
|
||||||
|
GPIO_SET0 = led[b]; // turn on LED for this setup
|
||||||
|
prev_b = b;
|
||||||
|
r--;
|
||||||
|
} // change
|
||||||
|
} // while
|
||||||
|
|
||||||
|
// turn off all LEDs
|
||||||
|
for (b = 0; b < 8; b++)
|
||||||
|
GPIO_CLR0 = led[b];
|
||||||
|
// disable pull up on pins & unmap gpio
|
||||||
|
unpull_pins();
|
||||||
|
restore_io();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} // main
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
//
|
||||||
|
// Gertboard Demo
|
||||||
|
//
|
||||||
|
// SPI control code
|
||||||
|
//
|
||||||
|
// This code is part of the Gertboard test suite
|
||||||
|
// These routines access the DA chip
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Try to strike a balance between keep code simple for
|
||||||
|
// novice programmers but still have reasonable quality code
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
#include "gb_spi.h"
|
||||||
|
|
||||||
|
// Set GPIO pins to the right mode
|
||||||
|
// DEMO GPIO mapping:
|
||||||
|
// Function Mode
|
||||||
|
// GPIO0= unused
|
||||||
|
// GPIO1= unused
|
||||||
|
// GPIO4= unused
|
||||||
|
// GPIO7= SPI chip select B Alt. 0
|
||||||
|
// GPIO8= unused
|
||||||
|
// GPIO9= SPI MISO Alt. 0
|
||||||
|
// GPIO10= SPI MOSI Alt. 0
|
||||||
|
// GPIO11= SPI CLK Alt. 0
|
||||||
|
// GPIO14= unused
|
||||||
|
// GPIO15= unused
|
||||||
|
// GPIO17= unused
|
||||||
|
// GPIO18= unused
|
||||||
|
// GPIO21= unused
|
||||||
|
// GPIO22= unused
|
||||||
|
// GPIO23= unused
|
||||||
|
// GPIO24= unused
|
||||||
|
// GPIO25= unused
|
||||||
|
//
|
||||||
|
|
||||||
|
// For D to A we only need the SPI bus and SPI chip select B
|
||||||
|
void setup_gpio()
|
||||||
|
{
|
||||||
|
INP_GPIO(7); SET_GPIO_ALT(7,0);
|
||||||
|
INP_GPIO(9); SET_GPIO_ALT(9,0);
|
||||||
|
INP_GPIO(10); SET_GPIO_ALT(10,0);
|
||||||
|
INP_GPIO(11); SET_GPIO_ALT(11,0);
|
||||||
|
} // setup_gpio
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read ADC input 0 and show as horizontal bar
|
||||||
|
//
|
||||||
|
void main(void)
|
||||||
|
{ int d, chan, dummy;
|
||||||
|
|
||||||
|
do {
|
||||||
|
printf ("Which channel do you want to test? Type 0 or 1.\n");
|
||||||
|
chan = (int) getchar();
|
||||||
|
(void) getchar(); // eat carriage return
|
||||||
|
} while (chan != '0' && chan != '1');
|
||||||
|
chan = chan - '0';
|
||||||
|
|
||||||
|
printf ("These are the connections for the digital to analogue test:\n");
|
||||||
|
printf ("jumper connecting GP11 to SCLK\n");
|
||||||
|
printf ("jumper connecting GP10 to MOSI\n");
|
||||||
|
printf ("jumper connecting GP9 to MISO\n");
|
||||||
|
printf ("jumper connecting GP7 to CSnB\n");
|
||||||
|
printf ("Multimeter connections (set your meter to read V DC):\n");
|
||||||
|
printf (" connect black probe to GND\n");
|
||||||
|
printf (" connect red probe to DA%d on J29\n", chan);
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
// Map the I/O sections
|
||||||
|
setup_io();
|
||||||
|
|
||||||
|
// activate SPI bus pins
|
||||||
|
setup_gpio();
|
||||||
|
|
||||||
|
// Setup SPI bus
|
||||||
|
setup_spi();
|
||||||
|
|
||||||
|
// Most likely, the DAC you have installed is an 8 bit one, not 12 bit so
|
||||||
|
// it will ignore that last nibble (4 bits) we send down the SPI interface.
|
||||||
|
// So the number that we pass to write_dac will need to be the number
|
||||||
|
// want to set (between 0 and 255) multiplied by 16. In hexidecimal,
|
||||||
|
// we just put an extra 0 after the number we want to set.
|
||||||
|
// So if we want to set the DAC to 64, this is 0x40, so we send 0x400
|
||||||
|
// to write_dac.
|
||||||
|
|
||||||
|
// To calculate the voltage we get out, we use this formula from the
|
||||||
|
// datasheet: V_out = (d / 256) * 2.048
|
||||||
|
|
||||||
|
d = 0x000;
|
||||||
|
write_dac(chan, d);
|
||||||
|
// V_out = 0 / 256 * 2.048 (gives 0)
|
||||||
|
printf ("Your meter should read about 0V\n");
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
d = 0x400;
|
||||||
|
write_dac(chan, d);
|
||||||
|
// V_out = 64 / 256 * 2.048 (gives 0.512)
|
||||||
|
printf ("Your meter should read about 0.5V\n");
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
d = 0x7F0;
|
||||||
|
write_dac(chan, d);
|
||||||
|
// V_out = 127 / 256 * 2.048 (gives 1.016)
|
||||||
|
printf ("Your meter should read about 1.02V\n");
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
d = 0xAA0;
|
||||||
|
write_dac(chan, d);
|
||||||
|
// V_out = 170 / 256 * 2.048 (gives 1.36)
|
||||||
|
printf ("Your meter should read about 1.36V\n");
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
d = 0xFF0;
|
||||||
|
write_dac(chan, d);
|
||||||
|
// V_out = 255 / 256 * 2.048 (gives 2.04)
|
||||||
|
printf ("Your meter should read about 2.04V\n");
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
restore_io();
|
||||||
|
} // main
|
|
@ -0,0 +1,323 @@
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Gertboard Common code
|
||||||
|
//
|
||||||
|
// This file is part of the gertboard test suite
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Notes:
|
||||||
|
// 1/ In some Linux systems (e.g. Debian) the UART is used by Linux.
|
||||||
|
// So for now do not demo the UART.
|
||||||
|
// 2/ At the moment (16-March-2012) there is no Linux driver for
|
||||||
|
// the audio yet so the PWM is free.
|
||||||
|
// This is likely to change and in that case the Linux
|
||||||
|
// audio/PWM driver must be disabled.
|
||||||
|
//
|
||||||
|
// This file contains code use by all the test programs for individual
|
||||||
|
// capabilities.
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
|
||||||
|
#define BCM2708_PERI_BASE 0x20000000
|
||||||
|
#define CLOCK_BASE (BCM2708_PERI_BASE + 0x101000) /* Clocks */
|
||||||
|
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO */
|
||||||
|
#define PWM_BASE (BCM2708_PERI_BASE + 0x20C000) /* PWM */
|
||||||
|
#define SPI0_BASE (BCM2708_PERI_BASE + 0x204000) /* SPI0 controller */
|
||||||
|
#define UART0_BASE (BCM2708_PERI_BASE + 0x201000) /* Uart 0 */
|
||||||
|
#define UART1_BASE (BCM2708_PERI_BASE + 0x215000) /* Uart 1 (not used) */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define PAGE_SIZE (4*1024)
|
||||||
|
#define BLOCK_SIZE (4*1024)
|
||||||
|
|
||||||
|
int mem_fd;
|
||||||
|
char *clk_mem_orig, *clk_mem, *clk_map;
|
||||||
|
char *gpio_mem_orig, *gpio_mem, *gpio_map;
|
||||||
|
char *pwm_mem_orig, *pwm_mem, *pwm_map;
|
||||||
|
char *spi0_mem_orig, *spi0_mem, *spi0_map;
|
||||||
|
char *uart_mem_orig, *uart_mem, *uart_map;
|
||||||
|
|
||||||
|
// I/O access
|
||||||
|
volatile unsigned *gpio;
|
||||||
|
volatile unsigned *pwm;
|
||||||
|
volatile unsigned *clk;
|
||||||
|
volatile unsigned *spi0;
|
||||||
|
volatile unsigned *uart;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// GPIO
|
||||||
|
//
|
||||||
|
|
||||||
|
// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
|
||||||
|
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
|
||||||
|
#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
|
||||||
|
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
|
||||||
|
|
||||||
|
#define GPIO_SET0 *(gpio+7) // Set GPIO high bits 0-31
|
||||||
|
#define GPIO_SET1 *(gpio+8) // Set GPIO high bits 32-53
|
||||||
|
|
||||||
|
#define GPIO_CLR0 *(gpio+10) // Set GPIO low bits 0-31
|
||||||
|
#define GPIO_CLR1 *(gpio+11) // Set GPIO low bits 32-53
|
||||||
|
#define GPIO_PULL *(gpio+37) // Pull up/pull down
|
||||||
|
#define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// UART 0
|
||||||
|
//
|
||||||
|
|
||||||
|
#define UART0_BAUD_HI *(uart+9)
|
||||||
|
#define UART0_BAUD_LO *(uart+10)
|
||||||
|
|
||||||
|
|
||||||
|
void setup_io();
|
||||||
|
void restore_io();
|
||||||
|
|
||||||
|
//
|
||||||
|
// This is a software loop to wait
|
||||||
|
// a short while.
|
||||||
|
//
|
||||||
|
void short_wait()
|
||||||
|
{ int w;
|
||||||
|
for (w=0; w<100; w++)
|
||||||
|
{ w++;
|
||||||
|
w--;
|
||||||
|
}
|
||||||
|
} // short_wait
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Simple SW wait loop
|
||||||
|
//
|
||||||
|
void long_wait(int v)
|
||||||
|
{ int w;
|
||||||
|
while (v--)
|
||||||
|
for (w=-800000; w<800000; w++)
|
||||||
|
{ w++;
|
||||||
|
w--;
|
||||||
|
}
|
||||||
|
} // long_wait
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set up memory regions to access the peripherals.
|
||||||
|
// This is a bit of 'magic' which you should not touch.
|
||||||
|
// It it also the part of the code which makes that
|
||||||
|
// you have to use 'sudo' to run this program.
|
||||||
|
//
|
||||||
|
void setup_io()
|
||||||
|
{ unsigned long extra;
|
||||||
|
|
||||||
|
/* open /dev/mem */
|
||||||
|
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
|
||||||
|
printf("Can't open /dev/mem\n");
|
||||||
|
printf("Did you forgot to use 'sudo .. ?'\n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mmap clock
|
||||||
|
*/
|
||||||
|
if ((clk_mem_orig = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
|
||||||
|
printf("allocation error \n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
extra = (unsigned long)clk_mem_orig % PAGE_SIZE;
|
||||||
|
if (extra)
|
||||||
|
clk_mem = clk_mem_orig + PAGE_SIZE - extra;
|
||||||
|
else
|
||||||
|
clk_mem = clk_mem_orig;
|
||||||
|
|
||||||
|
clk_map = (unsigned char *)mmap(
|
||||||
|
(caddr_t)clk_mem,
|
||||||
|
BLOCK_SIZE,
|
||||||
|
PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED|MAP_FIXED,
|
||||||
|
mem_fd,
|
||||||
|
CLOCK_BASE
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((long)clk_map < 0) {
|
||||||
|
printf("clk mmap error %d\n", (int)clk_map);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
clk = (volatile unsigned *)clk_map;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mmap GPIO
|
||||||
|
*/
|
||||||
|
if ((gpio_mem_orig = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
|
||||||
|
printf("allocation error \n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
extra = (unsigned long)gpio_mem_orig % PAGE_SIZE;
|
||||||
|
if (extra)
|
||||||
|
gpio_mem = gpio_mem_orig + PAGE_SIZE - extra;
|
||||||
|
else
|
||||||
|
gpio_mem = gpio_mem_orig;
|
||||||
|
|
||||||
|
gpio_map = (unsigned char *)mmap(
|
||||||
|
(caddr_t)gpio_mem,
|
||||||
|
BLOCK_SIZE,
|
||||||
|
PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED|MAP_FIXED,
|
||||||
|
mem_fd,
|
||||||
|
GPIO_BASE
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((long)gpio_map < 0) {
|
||||||
|
printf("gpio mmap error %d\n", (int)gpio_map);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
gpio = (volatile unsigned *)gpio_map;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mmap PWM
|
||||||
|
*/
|
||||||
|
if ((pwm_mem_orig = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
|
||||||
|
printf("allocation error \n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
extra = (unsigned long)pwm_mem_orig % PAGE_SIZE;
|
||||||
|
if (extra)
|
||||||
|
pwm_mem = pwm_mem_orig + PAGE_SIZE - extra;
|
||||||
|
else
|
||||||
|
pwm_mem = pwm_mem_orig;
|
||||||
|
|
||||||
|
pwm_map = (unsigned char *)mmap(
|
||||||
|
(caddr_t)pwm_mem,
|
||||||
|
BLOCK_SIZE,
|
||||||
|
PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED|MAP_FIXED,
|
||||||
|
mem_fd,
|
||||||
|
PWM_BASE
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((long)pwm_map < 0) {
|
||||||
|
printf("pwm mmap error %d\n", (int)pwm_map);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
pwm = (volatile unsigned *)pwm_map;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mmap SPI0
|
||||||
|
*/
|
||||||
|
if ((spi0_mem_orig = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
|
||||||
|
printf("allocation error \n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
extra = (unsigned long)spi0_mem_orig % PAGE_SIZE;
|
||||||
|
if (extra)
|
||||||
|
spi0_mem = spi0_mem_orig + PAGE_SIZE - extra;
|
||||||
|
else
|
||||||
|
spi0_mem = spi0_mem_orig;
|
||||||
|
|
||||||
|
spi0_map = (unsigned char *)mmap(
|
||||||
|
(caddr_t)spi0_mem,
|
||||||
|
BLOCK_SIZE,
|
||||||
|
PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED|MAP_FIXED,
|
||||||
|
mem_fd,
|
||||||
|
SPI0_BASE
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((long)spi0_map < 0) {
|
||||||
|
printf("spi0 mmap error %d\n", (int)spi0_map);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
spi0 = (volatile unsigned *)spi0_map;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mmap UART
|
||||||
|
*/
|
||||||
|
if ((uart_mem_orig = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
|
||||||
|
printf("allocation error \n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
extra = (unsigned long)uart_mem_orig % PAGE_SIZE;
|
||||||
|
if (extra)
|
||||||
|
uart_mem = uart_mem_orig + PAGE_SIZE - extra;
|
||||||
|
else
|
||||||
|
uart_mem = uart_mem_orig;
|
||||||
|
|
||||||
|
uart_map = (unsigned char *)mmap(
|
||||||
|
(caddr_t)uart_mem,
|
||||||
|
BLOCK_SIZE,
|
||||||
|
PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED|MAP_FIXED,
|
||||||
|
mem_fd,
|
||||||
|
UART0_BASE
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((long)uart_map < 0) {
|
||||||
|
printf("uart mmap error %d\n", (int)uart_map);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
uart = (volatile unsigned *)uart_map;
|
||||||
|
|
||||||
|
} // setup_io
|
||||||
|
|
||||||
|
//
|
||||||
|
// Undo what we did above
|
||||||
|
//
|
||||||
|
void restore_io()
|
||||||
|
{
|
||||||
|
munmap(uart_map,BLOCK_SIZE);
|
||||||
|
munmap(spi0_map,BLOCK_SIZE);
|
||||||
|
munmap(pwm_map,BLOCK_SIZE);
|
||||||
|
munmap(gpio_map,BLOCK_SIZE);
|
||||||
|
munmap(clk_map,BLOCK_SIZE);
|
||||||
|
// free memory
|
||||||
|
free(uart_mem_orig);
|
||||||
|
free(spi0_mem_orig);
|
||||||
|
free(pwm_mem_orig);
|
||||||
|
free(gpio_mem_orig);
|
||||||
|
free(clk_mem_orig);
|
||||||
|
} // restore_io
|
||||||
|
|
||||||
|
// simple routine to convert the last several bits of an integer to a string
|
||||||
|
// showing its binary value
|
||||||
|
// nbits is the number of bits in i to look at
|
||||||
|
// i is integer we want to show as a binary number
|
||||||
|
// we only look at the nbits least significant bits of i and we assume that
|
||||||
|
// s is at least nbits+1 characters long
|
||||||
|
void make_binary_string(int nbits, int i, char *s)
|
||||||
|
{ char *p;
|
||||||
|
int bit;
|
||||||
|
|
||||||
|
p = s;
|
||||||
|
for (bit = 1 << (nbits-1); bit > 0; bit = bit >> 1, p++)
|
||||||
|
*p = (i & bit) ? '1' : '0';
|
||||||
|
*p = '\0';
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
//
|
||||||
|
// Gertboard test suite
|
||||||
|
//
|
||||||
|
// main header file
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Try to strike a balance between keep code simple for
|
||||||
|
// novice programmers but still have reasonable quality code
|
||||||
|
// (e.g. do not use #ifndef big_demo_h....)
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// I/O access
|
||||||
|
extern volatile unsigned *gpio;
|
||||||
|
extern volatile unsigned *pwm;
|
||||||
|
extern volatile unsigned *clk;
|
||||||
|
extern volatile unsigned *spi0;
|
||||||
|
extern volatile unsigned *uart;
|
||||||
|
|
||||||
|
void short_wait();
|
||||||
|
void long_wait(int v);
|
||||||
|
|
||||||
|
void setup_io();
|
||||||
|
void restore_io();
|
||||||
|
void make_binary_string(int, int, char *);
|
||||||
|
|
||||||
|
// GPIO setup macros.
|
||||||
|
// Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
|
||||||
|
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
|
||||||
|
#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
|
||||||
|
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
|
||||||
|
|
||||||
|
#define GPIO_SET0 *(gpio+7) // Set GPIO high bits 0-31
|
||||||
|
#define GPIO_CLR0 *(gpio+10) // Set GPIO low bits 0-31
|
||||||
|
|
||||||
|
#define GPIO_IN0 *(gpio+13) // Reads GPIO input bits 0-31
|
||||||
|
|
||||||
|
#define GPIO_PULL *(gpio+37) // Pull up/pull down
|
||||||
|
#define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// UART 0
|
||||||
|
//
|
||||||
|
|
||||||
|
#define UART0_BAUD_HI *(uart+9)
|
||||||
|
#define UART0_BAUD_LO *(uart+10)
|
|
@ -0,0 +1,155 @@
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Gertboard Demo
|
||||||
|
//
|
||||||
|
// This code is part of the Gertboard test suite
|
||||||
|
// Pulse-Width-Modulation part
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanIwengen2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Try to strike a balance between keep code simple for
|
||||||
|
// novice programmers but still have reasonable quality code
|
||||||
|
//
|
||||||
|
// ______ ____ __
|
||||||
|
// | _ \ \ / / \/ |
|
||||||
|
// | |_) \ \ /\ / /| |\/| |
|
||||||
|
// | __/ \ V V / | | | |
|
||||||
|
// |_| \_/\_/ |_| |_|
|
||||||
|
//
|
||||||
|
|
||||||
|
// Beware of the following:
|
||||||
|
// 1/ Every write to a PWM register needs to be passed to the PWM clock
|
||||||
|
// This may take a while and takes longer if the PWM clock is slow.
|
||||||
|
// 2/ On top of that the PWM does NOT pick up any new values unless the counter
|
||||||
|
// reaches its end. So to quickly pick up a new value you have to disable it
|
||||||
|
// and then enable it again.
|
||||||
|
// 3/ The output polarity and reverse polarity bits are effective also if
|
||||||
|
// the PWM is disabled but not of there is no clock
|
||||||
|
|
||||||
|
// This is how we control a motor with a single PWM channel:
|
||||||
|
//
|
||||||
|
// |\ /|
|
||||||
|
// | \ / |
|
||||||
|
// | \ / |
|
||||||
|
// | >--A-(Motor)-B--< |
|
||||||
|
// | / \ |
|
||||||
|
// | / \ |
|
||||||
|
// |/ \|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// One direction:
|
||||||
|
// +---+ +---+ +---+ +---+
|
||||||
|
// A | | | | | | | |
|
||||||
|
// ==+ +======+ +======+ +======+ +=======
|
||||||
|
//
|
||||||
|
// B
|
||||||
|
// =============================================== (B is always low)
|
||||||
|
// The motor is driven (gets power) when A is high, so a PWM signal with
|
||||||
|
// A high for most of the time will make the motor go fast, and a PWM
|
||||||
|
// signal with A low for most for the time will make the mnotor turn
|
||||||
|
// slowly.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Other direction:
|
||||||
|
// --+ +------+ +------+ +------+ +------
|
||||||
|
// A | | | | | | | |
|
||||||
|
// +===+ +===+ +===+ +===+
|
||||||
|
//
|
||||||
|
// ---------------------------------------------- (B is always high)
|
||||||
|
// B
|
||||||
|
//
|
||||||
|
// Here the situation is reversed: the motor is driven (but in the
|
||||||
|
// opposite direction) when A is low. So a PWM signal with
|
||||||
|
// A low for most of the time will make the motor go fast, and a PWM
|
||||||
|
// signal with A high for most for the time will make the mnotor turn
|
||||||
|
// slowly.
|
||||||
|
//
|
||||||
|
// Off is both A and B low (or high, but I use low)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
#include "gb_pwm.h"
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setup the Pulse Width Modulator
|
||||||
|
// It needs a clock and needs to be off
|
||||||
|
//
|
||||||
|
void setup_pwm()
|
||||||
|
{
|
||||||
|
// Derive PWM clock direct from X-tal
|
||||||
|
// thus any system auto-slow-down-clock-to-save-power does not effect it
|
||||||
|
// The values below depends on the X-tal frequency!
|
||||||
|
PWMCLK_DIV = 0x5A000000 | (1920<<12); // set pwm div to 32 (19.2/3 = 600KHz)
|
||||||
|
PWMCLK_CNTL = 0x5A000011; // Source=osc and enable
|
||||||
|
|
||||||
|
// Make sure PWM is off
|
||||||
|
PWM_CONTROL = 0; short_wait();
|
||||||
|
|
||||||
|
// I use 1024 steps for the PWM
|
||||||
|
// (Just a nice value which I happen to like)
|
||||||
|
PWM0_RANGE = 400; //0x400;
|
||||||
|
short_wait();
|
||||||
|
|
||||||
|
} // setup_pwm
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set PWM value
|
||||||
|
// This routine does not wait for the value to arrive
|
||||||
|
// If a new value comes in before it is picked up by the chip
|
||||||
|
// it will definitely be too fast for the motor to respond to it
|
||||||
|
//
|
||||||
|
void set_pwm0(int v)
|
||||||
|
{ // make sure value is in safe range
|
||||||
|
if (v<0) v=0;
|
||||||
|
if (v>0x400) v=0x400;
|
||||||
|
PWM0_DATA = v;
|
||||||
|
} // set_pwm0
|
||||||
|
|
||||||
|
//
|
||||||
|
// Force PWM value update
|
||||||
|
// This routine makes sure the new value goes in.
|
||||||
|
// This is done by dis-abling the PWM, write the value
|
||||||
|
// and enable it again. This routine is weak as it
|
||||||
|
// uses a delay which is tested (but not guaranteed)
|
||||||
|
// Controls channel 0 only.
|
||||||
|
//
|
||||||
|
void force_pwm0(int v,int mode)
|
||||||
|
{ int w;
|
||||||
|
// disable
|
||||||
|
PWM_CONTROL = 0;
|
||||||
|
// wait for this command to get to the PWM clock domain
|
||||||
|
// that depends on PWN clock speed
|
||||||
|
// unfortunately there is no way to know when this has happened :-(
|
||||||
|
short_wait();
|
||||||
|
// make sure value is in safe range
|
||||||
|
if (v<0) v=0;
|
||||||
|
if (v>0x400) v=0x400;
|
||||||
|
PWM0_DATA = v;
|
||||||
|
short_wait();
|
||||||
|
|
||||||
|
PWM_CONTROL = mode;
|
||||||
|
short_wait();
|
||||||
|
} // force_pwm0
|
||||||
|
|
||||||
|
void pwm_off()
|
||||||
|
{
|
||||||
|
force_pwm0(0,0);
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
//
|
||||||
|
// Gertboard test suite
|
||||||
|
//
|
||||||
|
// pwm header file
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Try to strike a balance between keep code simple for
|
||||||
|
// novice programmers but still have reasonable quality code
|
||||||
|
// (e.g. do not use #ifndef big_demo_h....)
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#define PWMCLK_CNTL *(clk+40)
|
||||||
|
#define PWMCLK_DIV *(clk+41)
|
||||||
|
|
||||||
|
#define PWM_CONTROL *pwm
|
||||||
|
#define PWM_STATUS *(pwm+1)
|
||||||
|
#define PWM0_RANGE *(pwm+4)
|
||||||
|
#define PWM1_RANGE *(pwm+8)
|
||||||
|
#define PWM0_DATA *(pwm+5)
|
||||||
|
#define PWM1_DATA *(pwm+9)
|
||||||
|
|
||||||
|
// PWM Control register bits
|
||||||
|
#define PWM1_MS_MODE 0x8000 // Run in MS mode
|
||||||
|
#define PWM1_USEFIFO 0x2000 // Data from FIFO
|
||||||
|
#define PWM1_REVPOLAR 0x1000 // Reverse polarity
|
||||||
|
#define PWM1_OFFSTATE 0x0800 // Ouput Off state
|
||||||
|
#define PWM1_REPEATFF 0x0400 // Repeat last value if FIFO empty
|
||||||
|
#define PWM1_SERIAL 0x0200 // Run in serial mode
|
||||||
|
#define PWM1_ENABLE 0x0100 // Channel Enable
|
||||||
|
|
||||||
|
#define PWM0_MS_MODE 0x0080 // Run in MS mode
|
||||||
|
#define PWM0_USEFIFO 0x0020 // Data from FIFO
|
||||||
|
#define PWM0_REVPOLAR 0x0010 // Reverse polarity
|
||||||
|
#define PWM0_OFFSTATE 0x0008 // Ouput Off state
|
||||||
|
#define PWM0_REPEATFF 0x0004 // Repeat last value if FIFO empty
|
||||||
|
#define PWM0_SERIAL 0x0002 // Run in serial mode
|
||||||
|
#define PWM0_ENABLE 0x0001 // Channel Enable
|
||||||
|
|
||||||
|
#define PWM_CLRFIFO 0x0040 // Clear FIFO (Self clearing bit)
|
||||||
|
|
||||||
|
// PWM status bits I need
|
||||||
|
#define PWMS_BUSERR 0x0100 // Register access was too fast
|
||||||
|
// (Write to clear it)
|
||||||
|
|
||||||
|
// declarations for routines
|
||||||
|
void setup_pwm();
|
||||||
|
void force_pwm0(int, int);
|
||||||
|
void pwm_off();
|
|
@ -0,0 +1,136 @@
|
||||||
|
//
|
||||||
|
// Gertboard test
|
||||||
|
//
|
||||||
|
// SPI (ADC/DAC) control code
|
||||||
|
//
|
||||||
|
// This code is part of the Gertboard test suite
|
||||||
|
// These routines access the AD and DA chips
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Try to strike a balance between keep code simple for
|
||||||
|
// novice programmers but still have reasonable quality code
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
#include "gb_spi.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set-up the SPI interface
|
||||||
|
//
|
||||||
|
// Speed depends on what you talk to
|
||||||
|
// In this case use 1MHz
|
||||||
|
//
|
||||||
|
void setup_spi()
|
||||||
|
{
|
||||||
|
// Want to have 1 MHz SPI clock.
|
||||||
|
// Assume 250 Mhz system clock
|
||||||
|
// So divide 250MHz system clock by 250 to get 1MHz45
|
||||||
|
SPI0_CLKSPEED = 250;
|
||||||
|
|
||||||
|
// clear FIFOs and all status bits
|
||||||
|
SPI0_CNTLSTAT = SPI0_CS_CLRALL;
|
||||||
|
SPI0_CNTLSTAT = SPI0_CS_DONE; // make sure done bit is cleared
|
||||||
|
} // setup_spi()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read a value from one of the two ADC channels
|
||||||
|
//
|
||||||
|
// To understand this code you had better read the
|
||||||
|
// datasheet of the AD chip (MCP3002)
|
||||||
|
//
|
||||||
|
int read_adc(int chan) // 'chan' must be 0 or 1. This is not checked!
|
||||||
|
{ unsigned char v1,v2,rec_c;
|
||||||
|
int status,w;
|
||||||
|
// Set up for single ended, MS comes out first
|
||||||
|
v1 = 0xD0 | (chan<<5);
|
||||||
|
// Delay to make sure chip select is high for a short while
|
||||||
|
short_wait();
|
||||||
|
|
||||||
|
// Enable SPI interface: Use CS 0 and set activate bit
|
||||||
|
SPI0_CNTLSTAT = SPI0_CS_CHIPSEL0|SPI0_CS_ACTIVATE;
|
||||||
|
|
||||||
|
// Write the command into the FIFO so it will
|
||||||
|
// be transmitted out of the SPI interface to the ADC
|
||||||
|
// We need a 16-bit transfer so we send a command byte
|
||||||
|
// folowed by a dummy byte
|
||||||
|
SPI0_FIFO = v1;
|
||||||
|
SPI0_FIFO = 0; // dummy
|
||||||
|
|
||||||
|
// wait for SPI to be ready
|
||||||
|
// This will take about 16 micro seconds
|
||||||
|
do {
|
||||||
|
status = SPI0_CNTLSTAT;
|
||||||
|
} while ((status & SPI0_CS_DONE)==0);
|
||||||
|
SPI0_CNTLSTAT = SPI0_CS_DONE; // clear the done bit
|
||||||
|
|
||||||
|
// Data from the ADC chip should now be in the receiver
|
||||||
|
// read the received data
|
||||||
|
v1 = SPI0_FIFO;
|
||||||
|
v2 = SPI0_FIFO;
|
||||||
|
// Combine the 8-bit and 2 bit values into an 10-bit integer
|
||||||
|
// NOT!!! return ((v1<<8)|v2)&0x3FF;
|
||||||
|
// I have checked the result and it returns 3 bits in the MS byte not 2!!
|
||||||
|
// So I might have my SPI clock/data pahse wrong.
|
||||||
|
// For now its easier to dadpt the results (running out of time)
|
||||||
|
return ( (v1<<7) | (v2>>1) ) & 0x3FF;
|
||||||
|
} // read_adc
|
||||||
|
|
||||||
|
//
|
||||||
|
// Write 12 bit value to DAC channel 0 or 1
|
||||||
|
//
|
||||||
|
// To understand this code you had better read the
|
||||||
|
// datasheet of the AD chip (MCP4802/MCP4812/MCP4822)
|
||||||
|
//
|
||||||
|
void write_dac(int chan, // chan must be 0 or 1, this is not checked
|
||||||
|
int val) // chan must be max 12 bit
|
||||||
|
{ char v1,v2,dummy;
|
||||||
|
int status;
|
||||||
|
val &= 0xFFF; // force value in 12 bits
|
||||||
|
|
||||||
|
// Build the first byte: write, channel 0 or 1 bit
|
||||||
|
// and the 4 most significant data bits
|
||||||
|
v1 = 0x30 | (chan<<7) | (val>>8);
|
||||||
|
// Remain the Least Significant 8 data bits
|
||||||
|
v2 = val & 0xFF;
|
||||||
|
|
||||||
|
// Delay to have CS high for a short while
|
||||||
|
short_wait();
|
||||||
|
|
||||||
|
// Enable SPI: Use CS 1 and set activate bit
|
||||||
|
SPI0_CNTLSTAT = SPI0_CS_CHIPSEL1|SPI0_CS_ACTIVATE;
|
||||||
|
|
||||||
|
// send the values
|
||||||
|
SPI0_FIFO = v1;
|
||||||
|
SPI0_FIFO = v2;
|
||||||
|
|
||||||
|
// wait for SPI to be ready
|
||||||
|
// This will take about 16 micro seconds
|
||||||
|
do {
|
||||||
|
status = SPI0_CNTLSTAT;
|
||||||
|
} while ((status & SPI0_CS_DONE)==0);
|
||||||
|
SPI0_CNTLSTAT = SPI0_CS_DONE; // clear the done bit
|
||||||
|
|
||||||
|
// For every transmit there is also data coming back
|
||||||
|
// We MUST read that received data from the FIFO
|
||||||
|
// even if we do not use it!
|
||||||
|
dummy = SPI0_FIFO;
|
||||||
|
dummy = SPI0_FIFO;
|
||||||
|
} // write_dac
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
//
|
||||||
|
// Gertboard test suite
|
||||||
|
//
|
||||||
|
// spi header file
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// SPI macros and constants. There are lots!
|
||||||
|
//
|
||||||
|
#define SPI0_CNTLSTAT *(spi0 + 0)
|
||||||
|
#define SPI0_FIFO *(spi0 + 1)
|
||||||
|
#define SPI0_CLKSPEED *(spi0 + 2)
|
||||||
|
|
||||||
|
// SPI0_CNTLSTAT register bits
|
||||||
|
|
||||||
|
#define SPI0_CS_CS2ACTHIGH 0x00800000 // CS2 active high
|
||||||
|
#define SPI0_CS_CS1ACTHIGH 0x00400000 // CS1 active high
|
||||||
|
#define SPI0_CS_CS0ACTHIGH 0x00200000 // CS0 active high
|
||||||
|
#define SPI0_CS_RXFIFOFULL 0x00100000 // Receive FIFO full
|
||||||
|
#define SPI0_CS_RXFIFO3_4 0x00080000 // Receive FIFO 3/4 full
|
||||||
|
#define SPI0_CS_TXFIFOSPCE 0x00040000 // Transmit FIFO has space
|
||||||
|
#define SPI0_CS_RXFIFODATA 0x00020000 // Receive FIFO has data
|
||||||
|
#define SPI0_CS_DONE 0x00010000 // SPI transfer done. WRT to CLR!
|
||||||
|
#define SPI0_CS_MOSI_INPUT 0x00001000 // MOSI is input, read from MOSI (BI-dir mode)
|
||||||
|
#define SPI0_CS_DEASRT_CS 0x00000800 // De-assert CS at end
|
||||||
|
#define SPI0_CS_RX_IRQ 0x00000400 // Receive irq enable
|
||||||
|
#define SPI0_CS_DONE_IRQ 0x00000200 // irq when done
|
||||||
|
#define SPI0_CS_DMA_ENABLE 0x00000100 // Run in DMA mode
|
||||||
|
#define SPI0_CS_ACTIVATE 0x00000080 // Activate: be high before starting
|
||||||
|
#define SPI0_CS_CS_POLARIT 0x00000040 // Chip selects active high
|
||||||
|
#define SPI0_CS_CLRTXFIFO 0x00000020 // Clear TX FIFO (auto clear bit)
|
||||||
|
#define SPI0_CS_CLRRXFIFO 0x00000010 // Clear RX FIFO (auto clear bit)
|
||||||
|
#define SPI0_CS_CLRFIFOS 0x00000030 // Clear BOTH FIFOs (auto clear bit)
|
||||||
|
#define SPI0_CS_CLK_IDLHI 0x00000008 // Clock pin is high when idle
|
||||||
|
#define SPI0_CS_CLKTRANS 0x00000004 // 0=first clock in middle of data bit
|
||||||
|
// 1=first clock at begin of data bit
|
||||||
|
#define SPI0_CS_CHIPSEL0 0x00000000 // Use chip select 0
|
||||||
|
#define SPI0_CS_CHIPSEL1 0x00000001 // Use chip select 1
|
||||||
|
#define SPI0_CS_CHIPSEL2 0x00000002 // No chip select (e.g. use GPIO pin)
|
||||||
|
#define SPI0_CS_CHIPSELN 0x00000003 // No chip select (e.g. use GPIO pin)
|
||||||
|
|
||||||
|
#define SPI0_CS_CLRALL (SPI0_CS_CLRFIFOS|SPI0_CS_DONE)
|
||||||
|
|
||||||
|
// SPI functions
|
||||||
|
|
||||||
|
void setup_spi(void);
|
||||||
|
int read_adc(int);
|
||||||
|
void write_dac(int, int);
|
|
@ -0,0 +1,457 @@
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Gertboard Demo
|
||||||
|
//
|
||||||
|
// main file
|
||||||
|
//
|
||||||
|
// This file is part of gertboard_demo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Try to strike a balance between keep code simple for
|
||||||
|
// novice programmers but still have reasonable quality code
|
||||||
|
//
|
||||||
|
// DEMO GPIO mapping:
|
||||||
|
// Function Mode
|
||||||
|
// GPIO0= LED Output
|
||||||
|
// GPIO1= LED Output
|
||||||
|
// GPIO4= PWM channel-B Output
|
||||||
|
// GPIO7= SPI chip select B Funct. 0
|
||||||
|
// GPIO8= SPI chip select A Funct. 0
|
||||||
|
// GPIO9= SPI MISO Funct. 0
|
||||||
|
// GPIO10= SPI MOSI Funct. 0
|
||||||
|
// GPIO11= SPI CLK Funct. 0
|
||||||
|
// GPIO14= UART TXD (Funct. 0)
|
||||||
|
// GPIO15= UART RXD (Funct. 0)
|
||||||
|
// GPIO17= LED Output
|
||||||
|
// GPIO18= PWM channel-A Funct. 5
|
||||||
|
// GPIO21= LED Output
|
||||||
|
// GPIO22= LED Output
|
||||||
|
// GPIO23= LED Output
|
||||||
|
// GPIO24= Pushbutton Input
|
||||||
|
// GPIO25= Pushbutton Input
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Notes:
|
||||||
|
// 1/ In some Linux systems (e.g. Debian) the UART is used by Linux.
|
||||||
|
// So for now do not demo the UART.
|
||||||
|
// 2/ At the moment (16-March-2012) there is no Linux driver for
|
||||||
|
// the audio yet so the PWM is free.
|
||||||
|
// This is likely to change and in that case the Linux
|
||||||
|
// audio/PWM driver must be disabled.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "gertboard_demo.h"
|
||||||
|
|
||||||
|
#define BCM2708_PERI_BASE 0x20000000
|
||||||
|
#define CLOCK_BASE (BCM2708_PERI_BASE + 0x101000) /* Clocks */
|
||||||
|
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO */
|
||||||
|
#define PWM_BASE (BCM2708_PERI_BASE + 0x20C000) /* PWM */
|
||||||
|
#define SPI0_BASE (BCM2708_PERI_BASE + 0x204000) /* SPI0 controller */
|
||||||
|
#define UART0_BASE (BCM2708_PERI_BASE + 0x201000) /* Uart 0 */
|
||||||
|
#define UART1_BASE (BCM2708_PERI_BASE + 0x215000) /* Uart 1 (not used) */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define PAGE_SIZE (4*1024)
|
||||||
|
#define BLOCK_SIZE (4*1024)
|
||||||
|
|
||||||
|
int mem_fd;
|
||||||
|
char *clk_mem, *clk_map;
|
||||||
|
char *gpio_mem, *gpio_map;
|
||||||
|
char *pwm_mem, *pwm_map;
|
||||||
|
char *spi0_mem, *spi0_map;
|
||||||
|
char *uart_mem, *uart_map;
|
||||||
|
|
||||||
|
// I/O access
|
||||||
|
volatile unsigned *gpio;
|
||||||
|
volatile unsigned *pwm;
|
||||||
|
volatile unsigned *clk;
|
||||||
|
volatile unsigned *spi0;
|
||||||
|
volatile unsigned *uart;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// GPIO
|
||||||
|
//
|
||||||
|
|
||||||
|
// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
|
||||||
|
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
|
||||||
|
#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
|
||||||
|
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
|
||||||
|
|
||||||
|
#define GPIO_SET0 *(gpio+7) // Set GPIO high bits 0-31
|
||||||
|
#define GPIO_SET1 *(gpio+8) // Set GPIO high bits 32-53
|
||||||
|
|
||||||
|
#define GPIO_CLR0 *(gpio+10) // Set GPIO low bits 0-31
|
||||||
|
#define GPIO_CLR1 *(gpio+11) // Set GPIO low bits 32-53
|
||||||
|
#define GPIO_PULL *(gpio+37) // Pull up/pull down
|
||||||
|
#define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// UART 0
|
||||||
|
//
|
||||||
|
|
||||||
|
#define UART0_BAUD_HI *(uart+9)
|
||||||
|
#define UART0_BAUD_LO *(uart+10)
|
||||||
|
|
||||||
|
|
||||||
|
void setup_io();
|
||||||
|
void restore_io();
|
||||||
|
|
||||||
|
//
|
||||||
|
// This is a software loop to wait
|
||||||
|
// a short while.
|
||||||
|
//
|
||||||
|
void short_wait()
|
||||||
|
{ int w;
|
||||||
|
for (w=0; w<100; w++)
|
||||||
|
{ w++;
|
||||||
|
w--;
|
||||||
|
}
|
||||||
|
} // short_wait
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Simple SW wait loop
|
||||||
|
//
|
||||||
|
void long_wait(int v)
|
||||||
|
{ int w;
|
||||||
|
while (v--)
|
||||||
|
for (w=-800000; w<800000; w++)
|
||||||
|
{ w++;
|
||||||
|
w--;
|
||||||
|
}
|
||||||
|
} // long_wait
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set GPIO pins to the right mode
|
||||||
|
// DEMO GPIO mapping:
|
||||||
|
// Function Mode
|
||||||
|
// GPIO0= LED Output
|
||||||
|
// GPIO1= LED Output
|
||||||
|
// GPIO4= PWM channel-B Output
|
||||||
|
// GPIO7= SPI chip select B Funct. 0
|
||||||
|
// GPIO8= SPI chip select A Funct. 0
|
||||||
|
// GPIO9= SPI MISO Funct. 0
|
||||||
|
// GPIO10= SPI MOSI Funct. 0
|
||||||
|
// GPIO11= SPI CLK Funct. 0
|
||||||
|
// GPIO14= UART TXD (Funct. 0)
|
||||||
|
// GPIO15= UART RXD (Funct. 0)
|
||||||
|
// GPIO17= LED Output
|
||||||
|
// GPIO18= PWM channel-A Funct. 5
|
||||||
|
// GPIO21= LED Output
|
||||||
|
// GPIO22= LED Output
|
||||||
|
// GPIO23= LED Output
|
||||||
|
// GPIO24= Pushbutton Input
|
||||||
|
// GPIO25= Pushbutton Input
|
||||||
|
//
|
||||||
|
// Always call INP_GPIO(x) first
|
||||||
|
// as that is how the macros work
|
||||||
|
void setup_gpio()
|
||||||
|
{
|
||||||
|
INP_GPIO(0); OUT_GPIO(0);
|
||||||
|
INP_GPIO(1); OUT_GPIO(1);
|
||||||
|
INP_GPIO(4); OUT_GPIO(4);
|
||||||
|
INP_GPIO(7); SET_GPIO_ALT(7,0);
|
||||||
|
INP_GPIO(8); SET_GPIO_ALT(8,0);
|
||||||
|
INP_GPIO(9); SET_GPIO_ALT(9,0);
|
||||||
|
INP_GPIO(10); SET_GPIO_ALT(10,0);
|
||||||
|
INP_GPIO(11); SET_GPIO_ALT(11,0);
|
||||||
|
// 14 and 15 are already set to UART mode
|
||||||
|
// by Linux. Best if we don't touch them
|
||||||
|
// INP_GPIO(14); SET_GPIO_ALT(14,0);
|
||||||
|
// INP_GPIO(54); SET_GPIO_ALT(15,0);
|
||||||
|
INP_GPIO(17); OUT_GPIO(17);
|
||||||
|
INP_GPIO(18); SET_GPIO_ALT(18,5);
|
||||||
|
INP_GPIO(21); OUT_GPIO(21);
|
||||||
|
INP_GPIO(22); OUT_GPIO(22);
|
||||||
|
INP_GPIO(23); OUT_GPIO(23);
|
||||||
|
INP_GPIO(24);
|
||||||
|
INP_GPIO(25);
|
||||||
|
|
||||||
|
// enable pull-up on GPIO24&25
|
||||||
|
GPIO_PULL = 2;
|
||||||
|
short_wait();
|
||||||
|
// clock on GPIO 24 & 25 (bit 24 & 25 set)
|
||||||
|
GPIO_PULLCLK0 = 0x03000000;
|
||||||
|
short_wait();
|
||||||
|
GPIO_PULL = 0;
|
||||||
|
GPIO_PULLCLK0 = 0;
|
||||||
|
} // setup_gpio
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{ char key;
|
||||||
|
|
||||||
|
// Map the I/O sections
|
||||||
|
setup_io();
|
||||||
|
|
||||||
|
// Set ALL GPIO pins to the required mode
|
||||||
|
setup_gpio();
|
||||||
|
|
||||||
|
// Set up PWM module
|
||||||
|
setup_pwm();
|
||||||
|
|
||||||
|
// Setup the SPI
|
||||||
|
setup_spi();
|
||||||
|
|
||||||
|
// We don't touch the UART for now
|
||||||
|
|
||||||
|
//
|
||||||
|
// Here your main program can start
|
||||||
|
//
|
||||||
|
do {
|
||||||
|
printf(" l/L : Walk the LEDS\n");
|
||||||
|
printf(" b/B : Show buttons\n");
|
||||||
|
printf(" m/M : Control the motor\n");
|
||||||
|
printf(" a/A : Read the ADC values\n");
|
||||||
|
printf(" c/C : ADC => Motor\n");
|
||||||
|
printf("( D : Set the DAC values\n");
|
||||||
|
printf(" q/Q : Quit program\n");
|
||||||
|
key = getchar();
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case 'l':
|
||||||
|
case 'L':
|
||||||
|
quick_led_demo();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
quick_buttons_demo();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
case 'M':
|
||||||
|
quick_pwm_demo();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'a':
|
||||||
|
case 'A':
|
||||||
|
quick_adc_demo();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
case 'C':
|
||||||
|
adc_pwm_demo();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0A:
|
||||||
|
case 0x0D:
|
||||||
|
// ignore CR/LF
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("???\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (key!='q' && key!='Q');
|
||||||
|
|
||||||
|
// make sure everything is off!
|
||||||
|
leds_off();
|
||||||
|
pwm_off();
|
||||||
|
|
||||||
|
restore_io();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} // main
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set up memory regions to access the peripherals.
|
||||||
|
// This is a bit of 'magic' which you should not touch.
|
||||||
|
// It it also the part of the code which makes that
|
||||||
|
// you have to use 'sudo' to run this program.
|
||||||
|
//
|
||||||
|
void setup_io()
|
||||||
|
{
|
||||||
|
|
||||||
|
/* open /dev/mem */
|
||||||
|
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
|
||||||
|
printf("Can't open /dev/mem\n");
|
||||||
|
printf("Did you forgot to use 'sudo .. ?'\n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mmap clock
|
||||||
|
*/
|
||||||
|
if ((clk_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
|
||||||
|
printf("allocation error \n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
if ((unsigned long)clk_mem % PAGE_SIZE)
|
||||||
|
clk_mem += PAGE_SIZE - ((unsigned long)clk_mem % PAGE_SIZE);
|
||||||
|
|
||||||
|
clk_map = (unsigned char *)mmap(
|
||||||
|
(caddr_t)clk_mem,
|
||||||
|
BLOCK_SIZE,
|
||||||
|
PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED|MAP_FIXED,
|
||||||
|
mem_fd,
|
||||||
|
CLOCK_BASE
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((long)clk_map < 0) {
|
||||||
|
printf("clk mmap error %d\n", (int)clk_map);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
clk = (volatile unsigned *)clk_map;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mmap GPIO
|
||||||
|
*/
|
||||||
|
if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
|
||||||
|
printf("allocation error \n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
if ((unsigned long)gpio_mem % PAGE_SIZE)
|
||||||
|
gpio_mem += PAGE_SIZE - ((unsigned long)gpio_mem % PAGE_SIZE);
|
||||||
|
|
||||||
|
gpio_map = (unsigned char *)mmap(
|
||||||
|
(caddr_t)gpio_mem,
|
||||||
|
BLOCK_SIZE,
|
||||||
|
PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED|MAP_FIXED,
|
||||||
|
mem_fd,
|
||||||
|
GPIO_BASE
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((long)gpio_map < 0) {
|
||||||
|
printf("gpio mmap error %d\n", (int)gpio_map);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
gpio = (volatile unsigned *)gpio_map;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mmap PWM
|
||||||
|
*/
|
||||||
|
if ((pwm_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
|
||||||
|
printf("allocation error \n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
if ((unsigned long)pwm_mem % PAGE_SIZE)
|
||||||
|
pwm_mem += PAGE_SIZE - ((unsigned long)pwm_mem % PAGE_SIZE);
|
||||||
|
|
||||||
|
pwm_map = (unsigned char *)mmap(
|
||||||
|
(caddr_t)pwm_mem,
|
||||||
|
BLOCK_SIZE,
|
||||||
|
PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED|MAP_FIXED,
|
||||||
|
mem_fd,
|
||||||
|
PWM_BASE
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((long)pwm_map < 0) {
|
||||||
|
printf("pwm mmap error %d\n", (int)pwm_map);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
pwm = (volatile unsigned *)pwm_map;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mmap SPI0
|
||||||
|
*/
|
||||||
|
if ((spi0_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
|
||||||
|
printf("allocation error \n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
if ((unsigned long)spi0_mem % PAGE_SIZE)
|
||||||
|
spi0_mem += PAGE_SIZE - ((unsigned long)spi0_mem % PAGE_SIZE);
|
||||||
|
|
||||||
|
spi0_map = (unsigned char *)mmap(
|
||||||
|
(caddr_t)spi0_mem,
|
||||||
|
BLOCK_SIZE,
|
||||||
|
PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED|MAP_FIXED,
|
||||||
|
mem_fd,
|
||||||
|
SPI0_BASE
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((long)spi0_map < 0) {
|
||||||
|
printf("spi0 mmap error %d\n", (int)spi0_map);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
spi0 = (volatile unsigned *)spi0_map;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mmap UART
|
||||||
|
*/
|
||||||
|
if ((uart_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
|
||||||
|
printf("allocation error \n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
if ((unsigned long)uart_mem % PAGE_SIZE)
|
||||||
|
uart_mem += PAGE_SIZE - ((unsigned long)uart_mem % PAGE_SIZE);
|
||||||
|
|
||||||
|
uart_map = (unsigned char *)mmap(
|
||||||
|
(caddr_t)uart_mem,
|
||||||
|
BLOCK_SIZE,
|
||||||
|
PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED|MAP_FIXED,
|
||||||
|
mem_fd,
|
||||||
|
UART0_BASE
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((long)uart_map < 0) {
|
||||||
|
printf("uart mmap error %d\n", (int)uart_map);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
uart = (volatile unsigned *)uart_map;
|
||||||
|
|
||||||
|
} // setup_io
|
||||||
|
|
||||||
|
//
|
||||||
|
// Undo what we did above
|
||||||
|
//
|
||||||
|
void restore_io()
|
||||||
|
{
|
||||||
|
munmap(uart_map,BLOCK_SIZE);
|
||||||
|
munmap(spi0_map,BLOCK_SIZE);
|
||||||
|
munmap(pwm_map,BLOCK_SIZE);
|
||||||
|
munmap(gpio_map,BLOCK_SIZE);
|
||||||
|
munmap(clk_map,BLOCK_SIZE);
|
||||||
|
// can't reliable return data
|
||||||
|
// as the pntr may have been moved to 4K boundary
|
||||||
|
// so leave it to OS to return the memory
|
||||||
|
// free(uart_mem);
|
||||||
|
// free(spi0_mem);
|
||||||
|
// free(pwm_mem);
|
||||||
|
// free(gpio_mem);
|
||||||
|
// free(clk_mem );
|
||||||
|
} // restore_io
|
||||||
|
|
|
@ -0,0 +1,244 @@
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Gertboard test suite
|
||||||
|
//
|
||||||
|
// These program walks the LEDs
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// This file is part of gertboard test suite.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Try to strike a balance between keep code simple for
|
||||||
|
// novice programmers but still have reasonable quality code
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
|
||||||
|
// Use defines for the LEDS. In the GPIO code, GPIO pins n is controlled
|
||||||
|
// by bit n. The idea is here is that for example L1 will refer
|
||||||
|
// to the first LED, which is controlled by GPIO25 (because we will
|
||||||
|
// put a strap between GP25 anb B1). This gives a more intuitive
|
||||||
|
// name to use for the LEDs in the patterns.
|
||||||
|
//
|
||||||
|
// For novice users: don't worry about the complexity
|
||||||
|
// The compiler will optimise out all constant expressions and you
|
||||||
|
// will end up with a single constant value in your table.
|
||||||
|
#define L1 (1<<25)
|
||||||
|
#define L2 (1<<24)
|
||||||
|
#define L3 (1<<23)
|
||||||
|
#define L4 (1<<22)
|
||||||
|
#define L5 (1<<21)
|
||||||
|
#define L6 (1<<18)
|
||||||
|
#define L7 (1<<17)
|
||||||
|
#define L8 (1<<11)
|
||||||
|
#define L9 (1<<10)
|
||||||
|
#define L10 (1<<9)
|
||||||
|
#define L11 (1<<8)
|
||||||
|
#define L12 (1<<7)
|
||||||
|
|
||||||
|
#define ALL_LEDS (L1|L2|L3|L4|L5|L6|L7|L8|L9|L10|L11|L12)
|
||||||
|
|
||||||
|
// LEDs test GPIO mapping:
|
||||||
|
// Function Mode
|
||||||
|
// GPIO0= unused
|
||||||
|
// GPIO1= unused
|
||||||
|
// GPIO4= unused
|
||||||
|
// GPIO7= LED Output
|
||||||
|
// GPIO8= LED Output
|
||||||
|
// GPIO9= LED Output
|
||||||
|
// GPIO10= LED Output
|
||||||
|
// GPIO11= LED Output
|
||||||
|
// GPIO14= unused (preset to be UART)
|
||||||
|
// GPIO15= unused (preset to be UART)
|
||||||
|
// GPIO17= LED Output
|
||||||
|
// GPIO18= LED Output
|
||||||
|
// GPIO21= LED Output
|
||||||
|
// GPIO22= LED Output
|
||||||
|
// GPIO23= LED Output
|
||||||
|
// GPIO24= LED Output
|
||||||
|
// GPIO25= LED Output
|
||||||
|
|
||||||
|
void setup_gpio(void)
|
||||||
|
{
|
||||||
|
INP_GPIO(7); OUT_GPIO(7);
|
||||||
|
INP_GPIO(8); OUT_GPIO(8);
|
||||||
|
INP_GPIO(9); OUT_GPIO(9);
|
||||||
|
INP_GPIO(10); OUT_GPIO(10);
|
||||||
|
INP_GPIO(11); OUT_GPIO(11);
|
||||||
|
// 14 and 15 are already set to UART mode
|
||||||
|
// by Linux. Best if we don't touch them
|
||||||
|
INP_GPIO(17); OUT_GPIO(17);
|
||||||
|
INP_GPIO(18); OUT_GPIO(18);
|
||||||
|
INP_GPIO(21); OUT_GPIO(21);
|
||||||
|
INP_GPIO(22); OUT_GPIO(22);
|
||||||
|
INP_GPIO(23); OUT_GPIO(23);
|
||||||
|
INP_GPIO(24); OUT_GPIO(24);
|
||||||
|
INP_GPIO(25); OUT_GPIO(25);
|
||||||
|
} // setup_gpio
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the various patterns.
|
||||||
|
// The idea here is that each number in the arrays below specifies
|
||||||
|
// a collection of LEDs to turn on. The last element in each array is
|
||||||
|
// -1 so we can run through the patter with a a loop and detect when
|
||||||
|
// we are at the last item in the pattern. pattern0 and pattern1
|
||||||
|
// have only one LED on at a time. pattern2 starts with one on
|
||||||
|
// then turns on 2 of themm then 3, etc. Since each LED is controlled by
|
||||||
|
// a bit, we | (or) them together to turn on more than one LED as a time.
|
||||||
|
//
|
||||||
|
|
||||||
|
static int pattern0[] =
|
||||||
|
{L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, -1 };
|
||||||
|
static int pattern1[] =
|
||||||
|
{L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12,
|
||||||
|
L12, L11, L10, L9, L8, L7, L6, L5, L4, L3, L2, L1, -1 };
|
||||||
|
static int pattern2[] =
|
||||||
|
{0x0,
|
||||||
|
L1,
|
||||||
|
L1|L2,
|
||||||
|
L1|L2|L3,
|
||||||
|
L1|L2|L3|L4,
|
||||||
|
L1|L2|L3|L4|L5,
|
||||||
|
L1|L2|L3|L4|L5|L6,
|
||||||
|
L1|L2|L3|L4|L5|L6|L7,
|
||||||
|
L1|L2|L3|L4|L5|L6|L7|L8,
|
||||||
|
L1|L2|L3|L4|L5|L6|L7|L8|L9,
|
||||||
|
L1|L2|L3|L4|L5|L6|L7|L8|L9|L10,
|
||||||
|
L1|L2|L3|L4|L5|L6|L7|L8|L9|L10|L11,
|
||||||
|
L1|L2|L3|L4|L5|L6|L7|L8|L9|L10|L11|L12,
|
||||||
|
L2|L3|L4|L5|L6|L7|L8|L9|L10|L11|L12,
|
||||||
|
L3|L4|L5|L6|L7|L8|L9|L10|L11|L12,
|
||||||
|
L4|L5|L6|L7|L8|L9|L10|L11|L12,
|
||||||
|
L5|L6|L7|L8|L9|L10|L11|L12,
|
||||||
|
L6|L7|L8|L9|L10|L11|L12,
|
||||||
|
L7|L8|L9|L10|L11|L12,
|
||||||
|
L8|L9|L10|L11|L12,
|
||||||
|
L9|L10|L11|L12,
|
||||||
|
L10|L11|L12,
|
||||||
|
L11|L12,
|
||||||
|
L12,
|
||||||
|
-1};
|
||||||
|
|
||||||
|
// Local (to this file) variables
|
||||||
|
static int *pattern = pattern0; // current pattern
|
||||||
|
static int step = 0; // which pattern element we are showing
|
||||||
|
|
||||||
|
void show_LEDs(int value)
|
||||||
|
{
|
||||||
|
// first turn off all LEDs - GPIO_CLR0 selects which output pins
|
||||||
|
// will be set up 0
|
||||||
|
GPIO_CLR0 = ALL_LEDS;
|
||||||
|
// now light up the ones for this value - GPIO_SET0 selects which
|
||||||
|
// output pins will be set up 1
|
||||||
|
GPIO_SET0 = value;
|
||||||
|
} // set_pattern
|
||||||
|
|
||||||
|
void leds_off(void)
|
||||||
|
{
|
||||||
|
GPIO_CLR0 = ALL_LEDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start anew with one of the available patterns
|
||||||
|
//
|
||||||
|
void start_new_pattern(int p)
|
||||||
|
{
|
||||||
|
switch (p)
|
||||||
|
{
|
||||||
|
case 0 : pattern = pattern0; break;
|
||||||
|
case 1 : pattern = pattern1; break;
|
||||||
|
case 2 : pattern = pattern2; break;
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
step = 0;
|
||||||
|
// show the LEDs for the first item in the new pattern
|
||||||
|
show_LEDs(pattern[step]);
|
||||||
|
} // start_new_pattern
|
||||||
|
|
||||||
|
//
|
||||||
|
// Do single pattern step
|
||||||
|
// return 1 on last pattern
|
||||||
|
// return 0 on all others
|
||||||
|
//
|
||||||
|
int led_step()
|
||||||
|
{
|
||||||
|
step++;
|
||||||
|
if (pattern[step]==-1) // we're at end of this pattern, start over
|
||||||
|
step=0;
|
||||||
|
show_LEDs(pattern[step]);
|
||||||
|
return pattern[step+1]== -1 ? 1 : 0; // are we at last value?
|
||||||
|
} // led_step
|
||||||
|
|
||||||
|
//
|
||||||
|
// Quick play all patterns
|
||||||
|
//
|
||||||
|
int main(void)
|
||||||
|
{ int p,r,last;
|
||||||
|
|
||||||
|
printf ("These are the connections for the LEDs test:\n");
|
||||||
|
printf ("jumpers in every out location (U3-out-B1, U3-out-B2, etc)\n");
|
||||||
|
printf ("GP25 in J2 --- B1 in J3\n");
|
||||||
|
printf ("GP24 in J2 --- B2 in J3\n");
|
||||||
|
printf ("GP23 in J2 --- B3 in J3\n");
|
||||||
|
printf ("GP22 in J2 --- B4 in J3\n");
|
||||||
|
printf ("GP21 in J2 --- B5 in J3\n");
|
||||||
|
printf ("GP18 in J2 --- B6 in J3\n");
|
||||||
|
printf ("GP17 in J2 --- B7 in J3\n");
|
||||||
|
printf ("GP11 in J2 --- B8 in J3\n");
|
||||||
|
printf ("GP10 in J2 --- B9 in J3\n");
|
||||||
|
printf ("GP9 in J2 --- B10 in J3\n");
|
||||||
|
printf ("GP8 in J2 --- B11 in J3\n");
|
||||||
|
printf ("GP7 in J2 --- B12 in J3\n");
|
||||||
|
printf ("(If you don't have enough straps and jumpers you can install\n");
|
||||||
|
printf ("just a few of them, then run again later with the next batch.)\n");
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
// Map the I/O sections
|
||||||
|
setup_io();
|
||||||
|
|
||||||
|
// Set 12 GPIO pins to output mode
|
||||||
|
setup_gpio();
|
||||||
|
|
||||||
|
/* for testing purposes...
|
||||||
|
GPIO_SET0 = 0x180;
|
||||||
|
(void) getchar();
|
||||||
|
GPIO_CLR0 = 0x100;
|
||||||
|
(void) getchar();
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (p=0; p<3; p++)
|
||||||
|
{
|
||||||
|
// run pattern several times
|
||||||
|
start_new_pattern(p);
|
||||||
|
for (r=0; r<2; r++)
|
||||||
|
{ do {
|
||||||
|
last = led_step();
|
||||||
|
long_wait(3);
|
||||||
|
} while (!last);
|
||||||
|
} // run the pattern 2 times
|
||||||
|
} // loop over patterns
|
||||||
|
|
||||||
|
leds_off();
|
||||||
|
restore_io();
|
||||||
|
} // main
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
#
|
||||||
|
# Makefile for gertboard test programs
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
# No rights reserved
|
||||||
|
# You may treat this program as if it was in the public domain
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
# Keep things simple for novice users
|
||||||
|
# so do not use any implicit rules!
|
||||||
|
#
|
||||||
|
|
||||||
|
all : buttons butled leds ocol atod dtoa dad motor potmot decoder
|
||||||
|
|
||||||
|
clean :
|
||||||
|
rm *.o buttons butled leds ocol atod dtoa dad motor potmot decoder
|
||||||
|
|
||||||
|
buttons : gb_common.o buttons.o
|
||||||
|
gcc -o buttons gb_common.o buttons.o
|
||||||
|
|
||||||
|
butled : gb_common.o butled.o
|
||||||
|
gcc -o butled gb_common.o butled.o
|
||||||
|
|
||||||
|
leds : gb_common.o leds.o
|
||||||
|
gcc -o leds gb_common.o leds.o
|
||||||
|
|
||||||
|
ocol : gb_common.o ocol.o
|
||||||
|
gcc -o ocol gb_common.o ocol.o
|
||||||
|
|
||||||
|
atod : gb_common.o gb_spi.o atod.o
|
||||||
|
gcc -o atod gb_common.o gb_spi.o atod.o
|
||||||
|
|
||||||
|
dtoa : gb_common.o gb_spi.o dtoa.o
|
||||||
|
gcc -o dtoa gb_common.o gb_spi.o dtoa.o
|
||||||
|
|
||||||
|
dad : gb_common.o gb_spi.o dad.o
|
||||||
|
gcc -o dad gb_common.o gb_spi.o dad.o
|
||||||
|
|
||||||
|
motor : gb_common.o gb_pwm.o motor.o
|
||||||
|
gcc -o motor gb_common.o gb_pwm.o motor.o
|
||||||
|
|
||||||
|
potmot : gb_common.o gb_pwm.o gb_spi.o potmot.o
|
||||||
|
gcc -o potmot gb_common.o gb_pwm.o gb_spi.o potmot.o
|
||||||
|
|
||||||
|
decoder : gb_common.o decoder.o
|
||||||
|
gcc -o decoder gb_common.o decoder.o
|
||||||
|
|
||||||
|
# The next lines generate the various object files
|
||||||
|
|
||||||
|
gb_common.o : gb_common.c gb_common.h
|
||||||
|
gcc -c gb_common.c
|
||||||
|
|
||||||
|
buttons.o : buttons.c gb_common.h
|
||||||
|
gcc -c buttons.c
|
||||||
|
|
||||||
|
butled.o : butled.c gb_common.h
|
||||||
|
gcc -c butled.c
|
||||||
|
|
||||||
|
leds.o : leds.c gb_common.h
|
||||||
|
gcc -c leds.c
|
||||||
|
|
||||||
|
gb_spi.o : gb_spi.c gb_common.h gb_spi.h
|
||||||
|
gcc -c gb_spi.c
|
||||||
|
|
||||||
|
gb_pwm.o : gb_pwm.c gb_common.h gb_pwm.h
|
||||||
|
gcc -c gb_pwm.c
|
||||||
|
|
||||||
|
atod.o : atod.c gb_common.h gb_spi.h
|
||||||
|
gcc -c atod.c
|
||||||
|
|
||||||
|
atod2.o : atod.c gb_common.h gb_spi.h
|
||||||
|
gcc -c atod2.c
|
||||||
|
|
||||||
|
dtoa.o : dtoa.c gb_common.h gb_spi.h
|
||||||
|
gcc -c dtoa.c
|
||||||
|
|
||||||
|
dad.o : dad.c gb_common.h gb_spi.h
|
||||||
|
gcc -c dad.c
|
||||||
|
|
||||||
|
motor.o : motor.c gb_common.h gb_pwm.h
|
||||||
|
gcc -c motor.c
|
||||||
|
|
||||||
|
potmot.o : potmot.c gb_common.h gb_spi.h gb_pwm.h
|
||||||
|
gcc -c potmot.c
|
||||||
|
|
||||||
|
ocol.o : ocol.c gb_common.h gb_spi.h
|
||||||
|
gcc -c ocol.c
|
||||||
|
|
||||||
|
decoder.o : decoder.c gb_common.h
|
||||||
|
gcc -c decoder.c
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Gertboard tests
|
||||||
|
//
|
||||||
|
// This code is part of the Gertboard test suite
|
||||||
|
// motor control part
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Try to strike a balance between keep code simple for
|
||||||
|
// novice programmers but still have reasonable quality code
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
#include "gb_pwm.h"
|
||||||
|
|
||||||
|
// motor test GPIO mapping:
|
||||||
|
// Function Mode
|
||||||
|
// GPIO0= unused
|
||||||
|
// GPIO1= unused
|
||||||
|
// GPIO4= unused
|
||||||
|
// GPIO7= unused
|
||||||
|
// GPIO8= unused
|
||||||
|
// GPIO9= unused
|
||||||
|
// GPIO10= unused
|
||||||
|
// GPIO11= unused
|
||||||
|
// GPIO14= unused (preset to be UART)
|
||||||
|
// GPIO15= unused (preset to be UART)
|
||||||
|
// GPIO17= motor control B Output
|
||||||
|
// GPIO18= PWM (motor A) alt ftn 5
|
||||||
|
// GPIO21= unused
|
||||||
|
// GPIO22= unused
|
||||||
|
// GPIO23= unused
|
||||||
|
// GPIO24= unused
|
||||||
|
// GPIO25= unused
|
||||||
|
|
||||||
|
void setup_gpio(void)
|
||||||
|
{
|
||||||
|
INP_GPIO(17); OUT_GPIO(17);
|
||||||
|
INP_GPIO(18); SET_GPIO_ALT(18, 5);
|
||||||
|
} // setup_gpio
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{ int r,s;
|
||||||
|
|
||||||
|
printf ("These are the connections for the motor test:\n");
|
||||||
|
printf ("GP17 in J2 --- MOTB (just above GP1)\n");
|
||||||
|
printf ("GP18 in J2 --- MOTA (just above GP4)\n");
|
||||||
|
printf ("+ of external power source --- MOT+ in J19\n");
|
||||||
|
printf ("ground of external power source --- GND (any)\n");
|
||||||
|
printf ("one wire for your motor in MOTA in J19\n");
|
||||||
|
printf ("the other wire for your motor in MOTB in J19\n");
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
// Map the I/O sections
|
||||||
|
setup_io();
|
||||||
|
|
||||||
|
// Set GPIO pin 18 to use PWM and pin 17 to output mode
|
||||||
|
setup_gpio();
|
||||||
|
|
||||||
|
// set pin controlling the non-PWM driver to low and get PWM ready
|
||||||
|
GPIO_CLR0 = 1<<17; // Set GPIO pin LOW
|
||||||
|
setup_pwm(17);
|
||||||
|
|
||||||
|
printf("\n>>> "); fflush(stdout);
|
||||||
|
// motor B input is still low, so motor gets power when pwm input A is high
|
||||||
|
force_pwm0(0,PWM0_ENABLE);
|
||||||
|
// start motor off slow (low most of the time) then ramp up speed
|
||||||
|
// (increasing the high part of the pulses)
|
||||||
|
for (s=0x0; s<=400; s+=10)
|
||||||
|
{ long_wait(6);
|
||||||
|
set_pwm0(s);
|
||||||
|
putchar('+'); fflush(stdout);
|
||||||
|
}
|
||||||
|
long_wait(10);
|
||||||
|
// now slow the motor down by decreasing the time the pwm is high
|
||||||
|
for (s=400; s>=0x00; s-=10)
|
||||||
|
{ long_wait(6);
|
||||||
|
set_pwm0(s);
|
||||||
|
putchar('-'); fflush(stdout);
|
||||||
|
}
|
||||||
|
// make sure motor is stopped
|
||||||
|
pwm_off();
|
||||||
|
// same in reverse direction
|
||||||
|
// set motor B input to high, so motor gets power when pwm input A is low
|
||||||
|
GPIO_SET0 = 1<<17;
|
||||||
|
// when we enable pwm with reverse polarity, a pwm value near 0 means
|
||||||
|
// that the LOW phase is only done for a short period amount of time
|
||||||
|
// and a pwm value near 0x400 (the max we set in setup_pwm) means
|
||||||
|
// that the LOW phase is done for a long period amount of time
|
||||||
|
force_pwm0(0,PWM0_ENABLE|PWM0_REVPOLAR);
|
||||||
|
printf("\n<<< ");
|
||||||
|
// as before we ramp up speed of motor
|
||||||
|
for (s=0; s<=400; s+=10)
|
||||||
|
{ long_wait(6);
|
||||||
|
set_pwm0(s);
|
||||||
|
putchar('+'); fflush(stdout);
|
||||||
|
}
|
||||||
|
long_wait(10);
|
||||||
|
// then slow it down
|
||||||
|
for (s=400; s>=0; s-=10)
|
||||||
|
{ long_wait(6);
|
||||||
|
set_pwm0(s);
|
||||||
|
putchar('-'); fflush(stdout);
|
||||||
|
}
|
||||||
|
GPIO_CLR0 = 1<<17;
|
||||||
|
pwm_off();
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
restore_io();
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Gertboard test suite
|
||||||
|
//
|
||||||
|
// These program works the open collector
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// This file is part of gertboard test suite.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Try to strike a balance between keep code simple for
|
||||||
|
// novice programmers but still have reasonable quality code
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
// open colloector test GPIO mapping:
|
||||||
|
// Function Mode
|
||||||
|
// GPIO0= unused
|
||||||
|
// GPIO1= unused
|
||||||
|
// GPIO4= open collector Output
|
||||||
|
// GPIO7= unused
|
||||||
|
// GPIO8= unused
|
||||||
|
// GPIO9= unused
|
||||||
|
// GPIO10= unused
|
||||||
|
// GPIO11= unused
|
||||||
|
// GPIO14= unused (preset to be UART)
|
||||||
|
// GPIO15= unused (preset to be UART)
|
||||||
|
// GPIO17= unused
|
||||||
|
// GPIO18= unused
|
||||||
|
// GPIO21= unused
|
||||||
|
// GPIO22= unused
|
||||||
|
// GPIO23= unused
|
||||||
|
// GPIO24= unused
|
||||||
|
// GPIO25= unused
|
||||||
|
|
||||||
|
void setup_gpio(void)
|
||||||
|
{
|
||||||
|
INP_GPIO(4); OUT_GPIO(4);
|
||||||
|
} // setup_gpio
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// send on/off signals to GPIO4 - it's the wiring on and off the board
|
||||||
|
// that makes interesting things happen
|
||||||
|
//
|
||||||
|
int main(void)
|
||||||
|
{ int p,r,last, chan;
|
||||||
|
|
||||||
|
do {
|
||||||
|
printf ("Which driver do you want to test?\n");
|
||||||
|
printf ("Type a number between 1 and 6.\n");
|
||||||
|
chan = (int) getchar();
|
||||||
|
(void) getchar(); // eat carriage return
|
||||||
|
} while (chan < '1' | chan > '6');
|
||||||
|
chan = chan - '0';
|
||||||
|
|
||||||
|
printf ("These are the connections for the open collector test:\n");
|
||||||
|
printf ("GP4 in J2 --- RLY%d in J4\n", chan);
|
||||||
|
printf ("+ of external power source --- RPWR in J6\n");
|
||||||
|
printf ("ground of external power source --- GND (any)\n");
|
||||||
|
printf ("ground side of your circuit --- RLY%d in J%d\n", chan, chan + 11);
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
// Map the I/O sections
|
||||||
|
setup_io();
|
||||||
|
|
||||||
|
// Set GPIO4 pin to output mode
|
||||||
|
setup_gpio();
|
||||||
|
|
||||||
|
for (p = 0; p < 10; p++) {
|
||||||
|
GPIO_SET0 = 1 << 4;
|
||||||
|
long_wait(10);
|
||||||
|
GPIO_CLR0 = 1 << 4;
|
||||||
|
long_wait(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_io();
|
||||||
|
} // main
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,173 @@
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Gertboard tests
|
||||||
|
//
|
||||||
|
// This code is part of the Gertboard test suite
|
||||||
|
// motor control part
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
|
||||||
|
// No rights reserved
|
||||||
|
// You may treat this program as if it was in the public domain
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Try to strike a balance between keep code simple for
|
||||||
|
// novice programmers but still have reasonable quality code
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
#include "gb_spi.h"
|
||||||
|
#include "gb_pwm.h"
|
||||||
|
|
||||||
|
// potentiometer - motor test GPIO mapping:
|
||||||
|
// Function Mode
|
||||||
|
// GPIO0= unused
|
||||||
|
// GPIO1= unused
|
||||||
|
// GPIO4= unused
|
||||||
|
// GPIO7= unused
|
||||||
|
// GPIO8= unused
|
||||||
|
// GPIO8= SPI chip select A Alt. 0
|
||||||
|
// GPIO9= SPI MISO Alt. 0
|
||||||
|
// GPIO10= SPI MOSI Alt. 0
|
||||||
|
// GPIO11= SPI CLK Alt. 0
|
||||||
|
// GPIO14= unused (preset to be UART)
|
||||||
|
// GPIO15= unused (preset to be UART)
|
||||||
|
// GPIO17= motor control B Output
|
||||||
|
// GPIO18= PWM (motor A) alt ftn 5
|
||||||
|
// GPIO21= unused
|
||||||
|
// GPIO22= unused
|
||||||
|
// GPIO23= unused
|
||||||
|
// GPIO24= unused
|
||||||
|
// GPIO25= unused
|
||||||
|
|
||||||
|
void setup_gpio(void)
|
||||||
|
{
|
||||||
|
// setup GPIO 8 to 11 for SPI bus use
|
||||||
|
INP_GPIO(8); SET_GPIO_ALT(8,0);
|
||||||
|
INP_GPIO(9); SET_GPIO_ALT(9,0);
|
||||||
|
INP_GPIO(10); SET_GPIO_ALT(10,0);
|
||||||
|
INP_GPIO(11); SET_GPIO_ALT(11,0);
|
||||||
|
// GPIO 17 is used for the MOTB input and is just high or low
|
||||||
|
// (depending on potentiometer input)
|
||||||
|
INP_GPIO(17); OUT_GPIO(17);
|
||||||
|
// GPIO 18 is set up for using the pulse width modulator
|
||||||
|
INP_GPIO(18); SET_GPIO_ALT(18, 5);
|
||||||
|
} // setup_gpio
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{ int r, s, v, fwd;
|
||||||
|
|
||||||
|
printf ("These are the connections for the potentiometer - motor test:\n");
|
||||||
|
printf ("jumper connecting GP11 to SCLK\n");
|
||||||
|
printf ("jumper connecting GP10 to MOSI\n");
|
||||||
|
printf ("jumper connecting GP9 to MISO\n");
|
||||||
|
printf ("jumper connecting GP8 to CSnA\n");
|
||||||
|
printf ("Potentiometer connections:\n");
|
||||||
|
printf (" (call 1 and 3 the ends of the resistor and 2 the wiper)\n");
|
||||||
|
printf (" connect 3 to 3V3\n");
|
||||||
|
printf (" connect 2 to AD0\n");
|
||||||
|
printf (" connect 1 to GND\n");
|
||||||
|
printf ("GP17 in J2 --- MOTB (just above GP1)\n");
|
||||||
|
printf ("GP18 in J2 --- MOTA (just above GP4)\n");
|
||||||
|
printf ("+ of external power source --- MOT+ in J19\n");
|
||||||
|
printf ("ground of external power source --- GND (any)\n");
|
||||||
|
printf ("one wire for your motor in MOTA in J19\n");
|
||||||
|
printf ("the other wire for your motor in MOTB in J19\n");
|
||||||
|
printf ("When ready hit enter.\n");
|
||||||
|
(void) getchar();
|
||||||
|
|
||||||
|
// Map the I/O sections
|
||||||
|
setup_io();
|
||||||
|
|
||||||
|
// Set up GPIO pins for both A/D and motor
|
||||||
|
setup_gpio();
|
||||||
|
|
||||||
|
// Setup SPI bus
|
||||||
|
setup_spi();
|
||||||
|
|
||||||
|
// set pin controlling the non-PWM driver to low and get PWM ready
|
||||||
|
GPIO_CLR0 = 1<<17; // Set GPIO pin LOW
|
||||||
|
setup_pwm(17);
|
||||||
|
|
||||||
|
// motor B input is still low, so motor gets power when pwm input A is high
|
||||||
|
force_pwm0(0,PWM0_ENABLE);
|
||||||
|
// we call "forward" the direction we get when the B input is high
|
||||||
|
// we start out set up for going "backwards"
|
||||||
|
fwd = 0;
|
||||||
|
|
||||||
|
for (r=0; r<1200000; r++)
|
||||||
|
{
|
||||||
|
v= read_adc(0);
|
||||||
|
if (v <= 511)
|
||||||
|
{
|
||||||
|
// map 0 to 511 to going "backwards" -- 0 (one end of your pot) means
|
||||||
|
// go backwards fast (v sent to PWM is near 1023), as we increase
|
||||||
|
// towards 510, motor speed slows, and at 511 (middle) motor is stopped
|
||||||
|
// (v sent to PWM is near 0)
|
||||||
|
v = 1023-(v * 2);
|
||||||
|
// we want v near 0 to mean motor slow/stopped and v near 1023 to
|
||||||
|
// mean motor going "backwards" fast
|
||||||
|
if (fwd)
|
||||||
|
{ // going in the wrong direction
|
||||||
|
// reverse polarity
|
||||||
|
GPIO_SET0 = 1<<17;
|
||||||
|
// We set PWM0_REVPOLAR flag below because normally a high value for
|
||||||
|
// v means high cycle which means signal high most of the time.
|
||||||
|
// But with motor input B high, this would mean that motor is slow,
|
||||||
|
// which is not what we want. Setting PWM0_REVPOLAR flips the
|
||||||
|
// polarity so that a high v means that the signal is low most
|
||||||
|
// of the time, which gives us a high speed.
|
||||||
|
force_pwm0(v,PWM0_ENABLE|PWM0_REVPOLAR);
|
||||||
|
fwd = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
set_pwm0(v);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// map A/D value of 512 to 1023 to going "forwards" -- at 512 (middle)
|
||||||
|
// motor is stopped (v sent to PWM is near 0), as we increase A/D value
|
||||||
|
// motor speed increases (in the "forwards" direction), and when A/D
|
||||||
|
// value is at 1023 (at the "other" end of your pot), we send PWM a
|
||||||
|
// value near 1023 so it goes very fast "forwards".
|
||||||
|
v = (v-512)*2;
|
||||||
|
if (!fwd)
|
||||||
|
{ // going in the wrong direction
|
||||||
|
// reverse polarity
|
||||||
|
GPIO_CLR0 = 1<<17;
|
||||||
|
// Now normal polarity works for us:
|
||||||
|
// With a low v sent to PWM we get a low duty cycle, power
|
||||||
|
// is off most of the time, and since motor b input is low this
|
||||||
|
// means a slow motor; when v goes to near 1023 we get a high duty
|
||||||
|
// cycle which means power on most of the time which results in
|
||||||
|
// motor going quickly
|
||||||
|
force_pwm0(v,PWM0_ENABLE);
|
||||||
|
fwd = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
set_pwm0(v);
|
||||||
|
}
|
||||||
|
short_wait();
|
||||||
|
} // repeated read
|
||||||
|
|
||||||
|
// set motor A and B inputs to 0 so motor stops
|
||||||
|
GPIO_CLR0 = 1<<17;
|
||||||
|
force_pwm0(0,PWM0_ENABLE);
|
||||||
|
|
||||||
|
|
||||||
|
restore_io();
|
||||||
|
}
|
Loading…
Reference in New Issue