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