Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
proview
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Esteban Blanc
proview
Commits
55485da4
Commit
55485da4
authored
Mar 02, 2014
by
claes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
IO support for Gertboard
parent
57d40ffb
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1158 additions
and
3 deletions
+1158
-3
otherio/lib/rt/src/os_linux/rt_io_gb_common.c
otherio/lib/rt/src/os_linux/rt_io_gb_common.c
+323
-0
otherio/lib/rt/src/os_linux/rt_io_gb_common.h
otherio/lib/rt/src/os_linux/rt_io_gb_common.h
+64
-0
otherio/lib/rt/src/os_linux/rt_io_gb_spi.c
otherio/lib/rt/src/os_linux/rt_io_gb_spi.c
+136
-0
otherio/lib/rt/src/os_linux/rt_io_gb_spi.h
otherio/lib/rt/src/os_linux/rt_io_gb_spi.h
+63
-0
otherio/lib/rt/src/os_linux/rt_io_m_gertboard.c
otherio/lib/rt/src/os_linux/rt_io_m_gertboard.c
+300
-0
otherio/lib/rt/src/rt_io_otherio.meth
otherio/lib/rt/src/rt_io_otherio.meth
+1
-0
otherio/wbl/mcomp/src/otherio.wb_load
otherio/wbl/mcomp/src/otherio.wb_load
+271
-3
No files found.
otherio/lib/rt/src/os_linux/rt_io_gb_common.c
0 → 100644
View file @
55485da4
//=============================================================================
//
//
// 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 "rt_io_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'
;
}
otherio/lib/rt/src/os_linux/rt_io_gb_common.h
0 → 100644
View file @
55485da4
//
// 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)
otherio/lib/rt/src/os_linux/rt_io_gb_spi.c
0 → 100644
View file @
55485da4
//
// 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 "rt_io_gb_common.h"
#include "rt_io_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
otherio/lib/rt/src/os_linux/rt_io_gb_spi.h
0 → 100644
View file @
55485da4
//
// 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
);
otherio/lib/rt/src/os_linux/rt_io_m_gertboard.c
0 → 100644
View file @
55485da4
/*
* Proview Open Source Process Control.
* Copyright (C) 2005-2014 SSAB EMEA AB.
*
* This file is part of Proview.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Proview. If not, see <http://www.gnu.org/licenses/>
*
* Linking Proview statically or dynamically with other modules is
* making a combined work based on Proview. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders of
* Proview give you permission to, from the build function in the
* Proview Configurator, combine Proview with modules generated by the
* Proview PLC Editor to a PLC program, regardless of the license
* terms of these modules. You may copy and distribute the resulting
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* the source code of Proview (the version used to produce the
* combined work), being distributed under the terms of the GNU
* General Public License plus this exception.
*/
/* rt_io_m_gertboard.c -- I/O methods for class Gertboard. */
#include "pwr.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_otherioclasses.h"
#include "co_time.h"
#include "rt_io_base.h"
#include "rt_io_card_init.h"
#include "rt_io_card_close.h"
#include "rt_io_card_read.h"
#include "rt_io_card_write.h"
#include "rt_io_msg.h"
#include "rt_io_gb_common.h"
#include "rt_io_gb_spi.h"
#define GPIO_CHANNELS 12
#define AD0_CHANNEL 12
#define AD1_CHANNEL 13
#define DA0_CHANNEL 14
#define DA1_CHANNEL 15
typedef
struct
{
FILE
*
value_fp
[
GPIO_CHANNELS
];
unsigned
int
number
[
GPIO_CHANNELS
];
unsigned
int
mask
[
GPIO_CHANNELS
];
int
type
[
GPIO_CHANNELS
];
unsigned
int
in_mask
;
unsigned
int
out_mask
;
int
interval_cnt
;
int
has_read_method
;
}
io_sLocalGertboard
;
static
pwr_tStatus
IoCardInit
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
,
io_sCard
*
cp
)
{
int
i
;
pwr_sClass_Gertboard
*
op
=
(
pwr_sClass_Gertboard
*
)
cp
->
op
;
io_sLocalGertboard
*
local
;
int
spi_init
=
0
;
local
=
(
io_sLocalGertboard
*
)
calloc
(
1
,
sizeof
(
io_sLocalGertboard
));
cp
->
Local
=
local
;
setup_io
();
if
(
(
cp
->
chanlist
[
AD0_CHANNEL
].
cop
&&
cp
->
chanlist
[
AD0_CHANNEL
].
sop
)
||
(
cp
->
chanlist
[
AD1_CHANNEL
].
cop
&&
cp
->
chanlist
[
AD1_CHANNEL
].
sop
)
||
(
cp
->
chanlist
[
DA0_CHANNEL
].
cop
&&
cp
->
chanlist
[
DA0_CHANNEL
].
sop
)
||
(
cp
->
chanlist
[
DA1_CHANNEL
].
cop
&&
cp
->
chanlist
[
DA1_CHANNEL
].
sop
))
{
// Init SPI
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_spi
();
spi_init
=
1
;
}
for
(
i
=
0
;
i
<
GPIO_CHANNELS
;
i
++
)
{
if
(
cp
->
chanlist
[
i
].
cop
&&
cp
->
chanlist
[
i
].
sop
)
{
switch
(
cp
->
chanlist
[
i
].
ChanClass
)
{
case
pwr_cClass_ChanD
:
if
(
local
->
number
[
i
]
>
32
)
{
errh_Error
(
"Gertboard channel number error, Buf%d"
,
i
+
1
);
op
->
Status
=
IO__INITFAIL
;
return
IO__INITFAIL
;
}
local
->
type
[
i
]
=
((
pwr_sClass_ChanD
*
)
cp
->
chanlist
[
i
].
cop
)
->
Type
;
local
->
number
[
i
]
=
((
pwr_sClass_ChanD
*
)
cp
->
chanlist
[
i
].
cop
)
->
Number
;
if
(
spi_init
&&
(
local
->
number
[
i
]
==
7
||
local
->
number
[
i
]
==
8
||
local
->
number
[
i
]
==
9
||
local
->
number
[
i
]
==
10
||
local
->
number
[
i
]
==
11
))
{
errh_Warning
(
"GPIO Buf and SPI overlap, %d"
,
local
->
number
[
i
]);
break
;
}
local
->
mask
[
i
]
=
1
<<
local
->
number
[
i
];
if
(
local
->
type
[
i
]
==
pwr_eDChanTypeEnum_Di
)
{
local
->
in_mask
|=
local
->
mask
[
i
];
INP_GPIO
(
local
->
number
[
i
]);
}
else
{
local
->
out_mask
|=
local
->
mask
[
i
];
INP_GPIO
(
local
->
number
[
i
]);
OUT_GPIO
(
local
->
number
[
i
]);
}
break
;
default:
;
}
}
}
if
(
local
->
in_mask
)
{
GPIO_PULL
=
2
;
short_wait
();
GPIO_PULLCLK0
=
local
->
in_mask
;
short_wait
();
GPIO_PULL
=
0
;
GPIO_PULLCLK0
=
0
;
}
if
(
cp
->
chanlist
[
DA0_CHANNEL
].
cop
&&
cp
->
chanlist
[
AD0_CHANNEL
].
sop
)
{
io_AiRangeToCoef
(
&
cp
->
chanlist
[
AD0_CHANNEL
]);
}
if
(
cp
->
chanlist
[
DA1_CHANNEL
].
cop
&&
cp
->
chanlist
[
AD1_CHANNEL
].
sop
)
{
io_AiRangeToCoef
(
&
cp
->
chanlist
[
AD1_CHANNEL
]);
}
if
(
cp
->
chanlist
[
DA0_CHANNEL
].
cop
&&
cp
->
chanlist
[
DA0_CHANNEL
].
sop
)
{
io_AoRangeToCoef
(
&
cp
->
chanlist
[
DA0_CHANNEL
]);
}
if
(
cp
->
chanlist
[
DA1_CHANNEL
].
cop
&&
cp
->
chanlist
[
DA1_CHANNEL
].
sop
)
{
io_AoRangeToCoef
(
&
cp
->
chanlist
[
DA1_CHANNEL
]);
}
errh_Info
(
"Init of Gertboard '%s'"
,
cp
->
Name
);
op
->
Status
=
IO__SUCCESS
;
return
IO__SUCCESS
;
}
static
pwr_tStatus
IoCardClose
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
,
io_sCard
*
cp
)
{
io_sLocalGertboard
*
local
=
(
io_sLocalGertboard
*
)
cp
->
Local
;
pwr_sClass_Gertboard
*
op
=
(
pwr_sClass_Gertboard
*
)
cp
->
op
;
if
(
local
->
in_mask
)
{
GPIO_PULL
=
0
;
short_wait
();
GPIO_PULLCLK0
=
local
->
in_mask
;
short_wait
();
GPIO_PULL
=
0
;
GPIO_PULLCLK0
=
0
;
}
free
(
cp
->
Local
);
op
->
Status
=
0
;
return
IO__SUCCESS
;
}
static
pwr_tStatus
IoCardRead
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
,
io_sCard
*
cp
)
{
io_sLocalGertboard
*
local
=
(
io_sLocalGertboard
*
)
cp
->
Local
;
int
i
;
unsigned
int
value_mask
;
int
ivalue
;
value_mask
=
GPIO_IN0
;
for
(
i
=
0
;
i
<
GPIO_CHANNELS
;
i
++
)
{
if
(
local
->
mask
[
i
]
&
local
->
in_mask
&&
cp
->
chanlist
[
i
].
cop
&&
cp
->
chanlist
[
i
].
vbp
)
{
if
(
value_mask
&
local
->
mask
[
i
])
*
(
pwr_tBoolean
*
)
cp
->
chanlist
[
i
].
vbp
=
1
;
else
*
(
pwr_tBoolean
*
)
cp
->
chanlist
[
i
].
vbp
=
0
;
}
}
for
(
i
=
0
;
i
<
2
;
i
++
)
{
if
(
cp
->
chanlist
[
AD0_CHANNEL
+
i
].
cop
&&
cp
->
chanlist
[
AD0_CHANNEL
+
i
].
sop
)
{
io_sChannel
*
chanp
=
&
cp
->
chanlist
[
AD0_CHANNEL
+
i
];
pwr_sClass_ChanAi
*
cop
=
(
pwr_sClass_ChanAi
*
)
chanp
->
cop
;
pwr_sClass_Ai
*
sop
=
(
pwr_sClass_Ai
*
)
chanp
->
sop
;
float
actvalue
;
if
(
cop
->
CalculateNewCoef
)
// Request to calculate new coefficients
io_AiRangeToCoef
(
chanp
);
ivalue
=
read_adc
(
i
);
io_ConvertAi
(
cop
,
ivalue
,
&
actvalue
);
// Filter
if
(
sop
->
FilterType
==
1
&&
sop
->
FilterAttribute
[
0
]
>
0
&&
sop
->
FilterAttribute
[
0
]
>
ctx
->
ScanTime
)
{
actvalue
=
*
(
pwr_tFloat32
*
)
chanp
->
vbp
+
ctx
->
ScanTime
/
sop
->
FilterAttribute
[
0
]
*
(
actvalue
-
*
(
pwr_tFloat32
*
)
chanp
->
vbp
);
}
*
(
pwr_tFloat32
*
)
chanp
->
vbp
=
actvalue
;
sop
->
SigValue
=
cop
->
SigValPolyCoef1
*
ivalue
+
cop
->
SigValPolyCoef0
;
sop
->
RawValue
=
ivalue
;
}
}
return
IO__SUCCESS
;
}
static
pwr_tStatus
IoCardWrite
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
,
io_sCard
*
cp
)
{
io_sLocalGertboard
*
local
=
(
io_sLocalGertboard
*
)
cp
->
Local
;
int
i
;
unsigned
int
clear_mask
=
0
;
unsigned
int
set_mask
=
0
;
int
ivalue
;
for
(
i
=
0
;
i
<
GPIO_CHANNELS
;
i
++
)
{
if
(
local
->
mask
[
i
]
&
local
->
out_mask
&&
cp
->
chanlist
[
i
].
cop
&&
cp
->
chanlist
[
i
].
vbp
)
{
if
(
*
(
pwr_tBoolean
*
)
cp
->
chanlist
[
i
].
vbp
)
set_mask
|=
local
->
mask
[
i
];
else
clear_mask
|=
local
->
mask
[
i
];
}
}
GPIO_CLR0
=
clear_mask
;
GPIO_SET0
=
set_mask
;
for
(
i
=
0
;
i
<
2
;
i
++
)
{
if
(
cp
->
chanlist
[
DA0_CHANNEL
+
i
].
cop
&&
cp
->
chanlist
[
DA0_CHANNEL
+
i
].
sop
)
{
pwr_sClass_ChanAo
*
cop
=
(
pwr_sClass_ChanAo
*
)
cp
->
chanlist
[
DA0_CHANNEL
+
i
].
cop
;
pwr_sClass_Ao
*
sop
=
(
pwr_sClass_Ao
*
)
cp
->
chanlist
[
DA0_CHANNEL
+
i
].
sop
;
if
(
cop
->
CalculateNewCoef
)
// Request to calculate new coefficients
io_AoRangeToCoef
(
&
cp
->
chanlist
[
DA0_CHANNEL
+
i
]);
ivalue
=
(
int
)(
*
(
pwr_tFloat32
*
)
cp
->
chanlist
[
DA0_CHANNEL
+
i
].
vbp
*
cop
->
OutPolyCoef1
+
cop
->
OutPolyCoef0
+
0
.
5
);
if
(
ivalue
<
0
)
ivalue
=
0
;
else
if
(
ivalue
>
4095
)
ivalue
=
4095
;
sop
->
RawValue
=
ivalue
;
sop
->
SigValue
=
*
(
pwr_tFloat32
*
)
cp
->
chanlist
[
DA0_CHANNEL
+
i
].
vbp
*
cop
->
SigValPolyCoef1
+
cop
->
SigValPolyCoef0
;
write_dac
(
i
,
ivalue
);
}
}
return
IO__SUCCESS
;
}
/* Every method should be registred here. */
pwr_dExport
pwr_BindIoMethods
(
Gertboard
)
=
{
pwr_BindIoMethod
(
IoCardInit
),
pwr_BindIoMethod
(
IoCardClose
),
pwr_BindIoMethod
(
IoCardRead
),
pwr_BindIoMethod
(
IoCardWrite
),
pwr_NullMethod
};
otherio/lib/rt/src/rt_io_otherio.meth
View file @
55485da4
...
@@ -33,4 +33,5 @@ Epl_Module
...
@@ -33,4 +33,5 @@ Epl_Module
Epl_CNServer
Epl_CNServer
Epl_CNServerModule
Epl_CNServerModule
PiFace_Digital
PiFace_Digital
Gertboard
#endif
#endif
\ No newline at end of file
otherio/wbl/mcomp/src/otherio.wb_load
View file @
55485da4
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment