Added gertboard examples. just for reference.

This commit is contained in:
Marcel Otte 2017-09-26 21:46:42 +02:00
commit 34144ee1d4
20 changed files with 2903 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.o

5
gertboard_sw/README Normal file
View File

@ -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.

126
gertboard_sw/atod.c Normal file
View File

@ -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

144
gertboard_sw/butled.c Normal file
View File

@ -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

150
gertboard_sw/buttons.c Normal file
View File

@ -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

137
gertboard_sw/dad.c Normal file
View File

@ -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

181
gertboard_sw/decoder.c Normal file
View File

@ -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

146
gertboard_sw/dtoa.c Normal file
View File

@ -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

323
gertboard_sw/gb_common.c Normal file
View File

@ -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';
}

64
gertboard_sw/gb_common.h Normal file
View File

@ -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)

155
gertboard_sw/gb_pwm.c Normal file
View File

@ -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);
}

64
gertboard_sw/gb_pwm.h Normal file
View File

@ -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();

136
gertboard_sw/gb_spi.c Normal file
View File

@ -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

63
gertboard_sw/gb_spi.h Normal file
View File

@ -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);

View File

@ -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

244
gertboard_sw/leds.c Normal file
View File

@ -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

103
gertboard_sw/makefile Normal file
View File

@ -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

130
gertboard_sw/motor.c Normal file
View File

@ -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();
}

101
gertboard_sw/ocol.c Normal file
View File

@ -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

173
gertboard_sw/potmot.c Normal file
View File

@ -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();
}