Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Michel Roelofs
dt_ctrl
Commits
30c6d3bd
Commit
30c6d3bd
authored
Aug 12, 2018
by
Jeroen Vreeken
Browse files
All atsamx70 blocks working.
Systick trigger working. New deadzone block.
parent
e1cc8739
Changes
30
Hide whitespace changes
Inline
Side-by-side
build.mk
View file @
30c6d3bd
...
...
@@ -27,6 +27,8 @@ endif
ifdef
HOSTSYS
CC
=
${HOSTSYS}
-gcc
LD
=
${HOSTSYS}
-ld
OBJCOPY
=
${HOSTSYS}
-objcopy
OBJDUMP
=
${HOSTSYS}
-objdump
LIBTOOL
=
${HOSTSYS}
-libtool
CONF_HOST
=
--host
=
${HOSTSYS}
HW
=
$(HOSTSYS)
...
...
@@ -101,3 +103,10 @@ endef
%.dtbo
:
%.dts
@
echo
" DTCo
$<
"
@
dtc
-I
dts
$<
-O
dtb
-o
$@
%.hex
:
%
$(OBJCOPY)
--strip-debug
--strip-unneeded
$?
-O
ihex
$?
.hex
%.asm
:
%
$(OBJDUMP)
-D
$?
>
$?
.asm
buildflags.mk.in
View file @
30c6d3bd
...
...
@@ -10,6 +10,7 @@ BUILD_CONSOLE_J2000_INDI=@BUILD_CONSOLE_J2000_INDI@
BUILD_ETHERCAT=@BUILD_ETHERCAT@
BUILD_VESP=@BUILD_VESP@
BUILD_AM335X=@BUILD_AM335X@
BUILD_ATSAMX70=@BUILD_ATSAMX70@
BUILD_LINUX_JOYSTICK=@BUILD_LINUX_JOYSTICK@
BUILD_TEST=@BUILD_TEST@
...
...
common/log/log_std.c
View file @
30c6d3bd
...
...
@@ -69,6 +69,8 @@ void log_send(enum log_type type, char *fmt, ...)
va_start
(
ap
,
fmt
);
vprintf
(
fmt
,
ap
);
va_end
(
ap
);
printf
(
"
\n
"
);
}
...
...
configure.ac
View file @
30c6d3bd
...
...
@@ -131,6 +131,7 @@ AC_CHECK_HEADER(semaphore.h,[HAVE_SEMAPHORE=1],[HAVE_SEMAPHORE=0])
AC_CHECK_HEADER(dlfcn.h,[HAVE_DYNAMICLINKING=1],[HAVE_DYNAMICLINKING=0])
AC_CHECK_HEADER(sysclk.h,[HAVE_SYSTICK=1],[HAVE_SYSTICK=0])
AC_CHECK_HEADER(samx70.h,[HAVE_ATSAMX70=1],[HAVE_ATSAMX70=0])
#######################################################################
#
...
...
@@ -227,6 +228,14 @@ AS_IF([test "$HAVE_SYSTICK" = "1"],
[AC_SUBST(CFLAGS_SYSTICK,["-DHAVE_SYSTICK -D_POSIX_TIMERS"])],
[AC_SUBST(CFLAGS_SYSTICK,[""])])
AS_IF([test "$HAVE_ATSAMX70" = "1"],
[AC_SUBST(BUILD_ATSAMX70,["yes"])],
[AC_SUBST(BUILD_ATSAMX70,[""])])
AS_IF([test "$HAVE_ATSAMX70" = "1"],
[AC_SUBST(CFLAGS_ATSAMX70,["-DHAVE_ATSAMX70"])],
[AC_SUBST(CFLAGS_ATSAMX70,[""])])
#######################################################################
#
# Output
...
...
@@ -279,6 +288,18 @@ AS_IF([test "$BUILD_AM335X" != ""],
AC_MSG_NOTICE([ am335x: yes]),
AC_MSG_NOTICE([ am335x: no]))
AS_IF([test "$BUILD_ATSAMX70" != ""],
AC_MSG_NOTICE([ atsamx70: yes]),
AC_MSG_NOTICE([ atsamx70: no]))
AS_IF([test "$BUILD_SYSTICK" != ""],
AC_MSG_NOTICE([ systick: yes]),
AC_MSG_NOTICE([ systick: no]))
AS_IF([test "$BUILD_EMBEDDED" != ""],
AC_MSG_NOTICE([ embedded: yes]),
AC_MSG_NOTICE([ embedded: no]))
AS_IF([test "$BUILD_TEST" != ""],
AC_MSG_NOTICE([ test: yes]),
AC_MSG_NOTICE([ test: no]))
controller/atsamx70/Makefile
0 → 100644
View file @
30c6d3bd
all
:
@
$(MAKE)
--no-print-directory
-C
../.. targets_controller/atsamx70
controller/atsamx70/block_atsamx70_afec.c
0 → 100644
View file @
30c6d3bd
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2018
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 3 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include
<samx70.h>
#include
<afec.h>
#include
<pio/samx70.h>
#include
<ioport.h>
#include
<controller/controller_block.h>
#include
<log/log.h>
struct
controller_block_private
{
float
value
;
uint32_t
afecnr
;
uint32_t
channel
;
float
factor
;
};
static
void
afec_calculate
(
struct
controller_block
*
afec
)
{
struct
controller_block_private
*
priv
=
afec
->
private
;
int16_t
data
=
afec_read_conversion_data
(
priv
->
afecnr
,
priv
->
channel
);
float
value
=
data
*
priv
->
factor
;
priv
->
value
=
value
;
}
static
struct
controller_block_outterm_list
outterms
[]
=
{
{
"value"
,
CONTROLLER_BLOCK_TERM_FLOAT
,
offsetof
(
struct
controller_block_private
,
value
)
},
{
NULL
},
};
static
struct
controller_block
*
block_atsamx70_afec_create
(
char
*
name
,
int
argc
,
va_list
ap
)
{
struct
controller_block
*
afec
;
int
afec_nr
;
afec_nr
=
va_arg
(
ap
,
int
);
if
(
afec_nr
<
0
||
afec_nr
>
1
)
{
log_send
(
LOG_T_ERROR
,
"%s: afec%d is not valid. (valid: 0-1)"
,
name
,
afec_nr
);
return
NULL
;
}
if
(
!
(
afec
=
controller_block_alloc
(
"atsamx70_afec"
,
name
,
sizeof
(
struct
controller_block_private
))))
goto
err_alloc
;
if
(
controller_block_outterm_list_init
(
afec
,
outterms
))
goto
err_outterm
;
afec
->
calculate
=
afec_calculate
;
uint32_t
pin
;
switch
(
afec_nr
)
{
case
0
:
afec
->
private
->
afecnr
=
AFEC0
;
afec
->
private
->
channel
=
0
;
pin
=
PIO_PD30_IDX
;
break
;
case
1
:
afec
->
private
->
afecnr
=
AFEC1
;
afec
->
private
->
channel
=
1
;
pin
=
PIO_PC13_IDX
;
break
;
}
afec
->
private
->
factor
=
1
.
0
/
2048
.
0
;
ioport_init
();
ioport_disable_pin
(
pin
);
afec_init
(
afec
->
private
->
afecnr
,
AFEC_MR_FREERUN
|
AFEC_MR_PRESCAL
((
sysclk_get_peripheral_hz
()
+
AFEC_FMAX
-
1
)
/
AFEC_FMAX
),
AFEC_EMR_RES_16
|
AFEC_EMR_STM_SINGLE
|
AFEC_EMR_SIGNMODE_SIGNED
);
afec_channel_set_offset
(
afec
->
private
->
afecnr
,
0
,
(
AFEC_ACR_AOFF_MAX
+
1
)
/
2
);
afec_channel_set_gain
(
afec
->
private
->
afecnr
,
0
,
0
);
// set gain to 1 (value 0)
afec_channel_enable
(
afec
->
private
->
afecnr
,
afec_nr
);
if
(
controller_block_add
(
afec
))
goto
err_add
;
return
afec
;
err_add:
err_outterm:
controller_block_free
(
afec
);
err_alloc:
return
NULL
;
}
BLOCK_CREATE
(
atsamx70_afec
)
=
{
.
create
=
block_atsamx70_afec_create
,
.
args
=
{
"int"
,
NULL
},
};
controller/atsamx70/block_atsamx70_pio_in.c
0 → 100644
View file @
30c6d3bd
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2018
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 3 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include
<samx70.h>
#include
<pio/samx70.h>
#include
<ioport.h>
#include
<controller/controller_block.h>
#include
<log/log.h>
struct
controller_block_private
{
bool
value
;
ioport_pin_t
pin
;
};
static
void
pio_in_calculate
(
struct
controller_block
*
pio
)
{
struct
controller_block_private
*
priv
=
pio
->
private
;
priv
->
value
=
ioport_get_pin_level
(
priv
->
pin
);
}
static
struct
controller_block_outterm_list
outterms
[]
=
{
{
"value"
,
CONTROLLER_BLOCK_TERM_BOOL
,
offsetof
(
struct
controller_block_private
,
value
)
},
{
NULL
},
};
static
struct
controller_block
*
block_atsamx70_pio_in_create
(
char
*
name
,
int
argc
,
va_list
ap
)
{
struct
controller_block
*
pio
;
int
pio_nr
;
int
pin_nr
;
pio_nr
=
va_arg
(
ap
,
int
);
if
(
pio_nr
<
0
||
pio_nr
>
4
)
{
log_send
(
LOG_T_ERROR
,
"%s: pio%d is not valid. (valid: 0-4)"
,
name
,
pio_nr
);
return
NULL
;
}
pin_nr
=
va_arg
(
ap
,
int
);
if
(
pin_nr
<
0
||
pin_nr
>
31
)
{
log_send
(
LOG_T_ERROR
,
"%s: pin%d is not valid. (valid: 0-31)"
,
name
,
pin_nr
);
}
if
(
!
(
pio
=
controller_block_alloc
(
"atsamx70_pio_in"
,
name
,
sizeof
(
struct
controller_block_private
))))
goto
err_alloc
;
if
(
controller_block_outterm_list_init
(
pio
,
outterms
))
goto
err_outterm
;
pio
->
calculate
=
pio_in_calculate
;
switch
(
pio_nr
)
{
case
0
:
pio
->
private
->
pin
=
PIO_PA_IDX
;
break
;
case
1
:
pio
->
private
->
pin
=
PIO_PB_IDX
;
break
;
case
2
:
pio
->
private
->
pin
=
PIO_PC_IDX
;
break
;
case
3
:
pio
->
private
->
pin
=
PIO_PD_IDX
;
break
;
case
4
:
pio
->
private
->
pin
=
PIO_PE_IDX
;
break
;
}
pio
->
private
->
pin
|=
pin_nr
;
ioport_init
();
ioport_enable_pin
(
pio
->
private
->
pin
);
ioport_set_pin_dir
(
pio
->
private
->
pin
,
IOPORT_DIR_INPUT
);
if
(
controller_block_add
(
pio
))
goto
err_add
;
return
pio
;
err_add:
err_outterm:
controller_block_free
(
pio
);
err_alloc:
return
NULL
;
}
BLOCK_CREATE
(
atsamx70_pio_in
)
=
{
.
create
=
block_atsamx70_pio_in_create
,
.
args
=
{
"int,int"
,
NULL
},
};
controller/atsamx70/block_atsamx70_pio_out.c
0 → 100644
View file @
30c6d3bd
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2018
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 3 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include
<samx70.h>
#include
<pio/samx70.h>
#include
<ioport.h>
#include
<controller/controller_block.h>
#include
<log/log.h>
struct
controller_block_private
{
bool
*
value
;
ioport_pin_t
pin
;
};
static
void
pio_out_calculate
(
struct
controller_block
*
pio
)
{
struct
controller_block_private
*
priv
=
pio
->
private
;
bool
value
=
*
priv
->
value
;
ioport_set_pin_level
(
priv
->
pin
,
value
);
}
static
struct
controller_block_interm_list
interms
[]
=
{
{
"value"
,
CONTROLLER_BLOCK_TERM_BOOL
,
offsetof
(
struct
controller_block_private
,
value
)
},
{
NULL
},
};
static
struct
controller_block
*
block_atsamx70_pio_out_create
(
char
*
name
,
int
argc
,
va_list
ap
)
{
struct
controller_block
*
pio
;
int
pio_nr
;
int
pin_nr
;
pio_nr
=
va_arg
(
ap
,
int
);
if
(
pio_nr
<
0
||
pio_nr
>
4
)
{
log_send
(
LOG_T_ERROR
,
"%s: pio%d is not valid. (valid: 0-4)"
,
name
,
pio_nr
);
return
NULL
;
}
pin_nr
=
va_arg
(
ap
,
int
);
if
(
pin_nr
<
0
||
pin_nr
>
31
)
{
log_send
(
LOG_T_ERROR
,
"%s: pin%d is not valid. (valid: 0-31)"
,
name
,
pin_nr
);
}
if
(
!
(
pio
=
controller_block_alloc
(
"atsamx70_pio_out"
,
name
,
sizeof
(
struct
controller_block_private
))))
goto
err_alloc
;
if
(
controller_block_interm_list_init
(
pio
,
interms
))
goto
err_interm
;
pio
->
calculate
=
pio_out_calculate
;
switch
(
pio_nr
)
{
case
0
:
pio
->
private
->
pin
=
PIO_PA_IDX
;
break
;
case
1
:
pio
->
private
->
pin
=
PIO_PB_IDX
;
break
;
case
2
:
pio
->
private
->
pin
=
PIO_PC_IDX
;
break
;
case
3
:
pio
->
private
->
pin
=
PIO_PD_IDX
;
break
;
case
4
:
pio
->
private
->
pin
=
PIO_PE_IDX
;
break
;
}
pio
->
private
->
pin
|=
pin_nr
;
ioport_init
();
ioport_enable_pin
(
pio
->
private
->
pin
);
ioport_set_pin_dir
(
pio
->
private
->
pin
,
IOPORT_DIR_OUTPUT
);
if
(
controller_block_add
(
pio
))
goto
err_add
;
return
pio
;
err_add:
err_interm:
controller_block_free
(
pio
);
err_alloc:
return
NULL
;
}
BLOCK_CREATE
(
atsamx70_pio_out
)
=
{
.
create
=
block_atsamx70_pio_out_create
,
.
args
=
{
"int,int"
,
NULL
},
};
controller/atsamx70/block_atsamx70_pwm.c
0 → 100644
View file @
30c6d3bd
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2018
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 3 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include
<samx70.h>
#include
<pwm.h>
#include
<pio/samx70.h>
#include
<ioport.h>
#include
<controller/controller_block.h>
#include
<log/log.h>
struct
controller_block_private
{
float
*
in
;
int
period
;
uint32_t
pwm
;
int
ch_nr
;
uint32_t
outputh
;
uint32_t
outputl
;
};
static
void
pwm_calculate
(
struct
controller_block
*
pwm
)
{
struct
controller_block_private
*
priv
=
pwm
->
private
;
uint32_t
pw
=
priv
->
pwm
;
float
in
=
*
priv
->
in
;
int
period
=
priv
->
period
;
uint32_t
outputl
=
priv
->
outputl
;
uint32_t
outputh
=
priv
->
outputh
;
int
ch_nr
=
priv
->
ch_nr
;
int
duty
=
in
*
period
;
uint32_t
dty
=
abs
(
duty
);
/* Make sure we generate negative pulses for capacitor loading */
if
(
dty
>=
period
)
{
dty
--
;
}
if
(
duty
>
0
)
{
pwm_output_selection_set
(
pw
,
outputl
);
pwm_channel_duty_cycle_update_set
(
pw
,
ch_nr
,
dty
);
pwm_output_selection_clear_update
(
pw
,
outputh
);
}
else
if
(
duty
<
0
)
{
pwm_output_selection_set
(
pw
,
outputh
);
pwm_channel_duty_cycle_update_set
(
pw
,
ch_nr
,
dty
);
pwm_output_selection_clear_update
(
pw
,
outputl
);
}
else
{
pwm_output_selection_set
(
pw
,
outputh
|
outputl
);
pwm_channel_duty_cycle_update_set
(
pw
,
ch_nr
,
dty
);
}
pwm_sync_update
(
pw
);
}
static
struct
controller_block_interm_list
interms
[]
=
{
{
"in"
,
CONTROLLER_BLOCK_TERM_FLOAT
,
offsetof
(
struct
controller_block_private
,
in
)
},
{
NULL
},
};
static
struct
controller_block
*
block_atsamx70_pwm_create
(
char
*
name
,
int
argc
,
va_list
ap
)
{
struct
controller_block
*
pwm
;
int
pwm_nr
;
int
ch_nr
;
double
frequency
;
pwm_nr
=
va_arg
(
ap
,
int
);
if
(
pwm_nr
<
0
||
pwm_nr
>
1
)
{
log_send
(
LOG_T_ERROR
,
"%s: pwm%d is not valid. (valid: 0-1)"
,
name
,
pwm_nr
);
return
NULL
;
}
ch_nr
=
va_arg
(
ap
,
int
);
if
(
ch_nr
<
0
||
ch_nr
>
1
)
{
log_send
(
LOG_T_ERROR
,
"%s: channel %d is not valid. (valid: 0-3)"
,
name
,
ch_nr
);
return
NULL
;
}
double
fclock
=
sysclk_get_peripheral_hz
();
frequency
=
va_arg
(
ap
,
double
);
int
period
=
fclock
/
frequency
;
log_send
(
LOG_T_DEBUG
,
"%s: Frequency: %fHz, period: %d (%fHz)"
,
name
,
frequency
,
period
,
fclock
/
period
);
if
(
!
(
pwm
=
controller_block_alloc
(
"atsamx70_pwm"
,
name
,
sizeof
(
struct
controller_block_private
))))
goto
err_alloc
;
if
(
controller_block_interm_list_init
(
pwm
,
interms
))
goto
err_interm
;
pwm
->
calculate
=
pwm_calculate
;
pwm
->
private
->
ch_nr
=
ch_nr
;
pwm
->
private
->
period
=
period
;
switch
(
pwm_nr
)
{
case
0
:
pwm
->
private
->
pwm
=
PWM0
;
break
;
case
1
:
pwm
->
private
->
pwm
=
PWM1
;
break
;
}
pwm_init
(
pwm
->
private
->
pwm
);
pwm_disable
(
pwm
->
private
->
pwm
,
ch_nr
);
uint32_t
oov
=
pwm_output_override_get
(
pwm
->
private
->
pwm
);
switch
(
ch_nr
)
{
case
0
:
oov
&=
~
(
PWM_OOV_OOVL0
|
PWM_OOV_OOVH0
);
pwm
->
private
->
outputh
=
PWM_OS_OSL0
;
pwm
->
private
->
outputl
=
PWM_OS_OSH0
;
ioport_disable_pin
(
PIO_PD20_IDX
);
ioport_set_pin_mode
(
PIO_PD20_IDX
,
IOPORT_MODE_MUX_A
);
ioport_set_pin_dir
(
PIO_PD20_IDX
,
IOPORT_DIR_OUTPUT
);
ioport_disable_pin
(
PIO_PA19_IDX
);
ioport_set_pin_mode
(
PIO_PA19_IDX
,
IOPORT_MODE_MUX_B
);
ioport_set_pin_dir
(
PIO_PA19_IDX
,
IOPORT_DIR_OUTPUT
);
break
;
case
1
:
oov
&=
~
(
PWM_OOV_OOVL1
|
PWM_OOV_OOVH1
);
pwm
->
private
->
outputh
=
PWM_OS_OSL1
;
pwm
->
private
->
outputl
=
PWM_OS_OSH1
;
break
;
case
2
:
oov
&=
~
(
PWM_OOV_OOVL2
|
PWM_OOV_OOVH2
);
pwm
->
private
->
outputh
=
PWM_OS_OSL0
;
pwm
->
private
->
outputl
=
PWM_OS_OSH2
;
break
;
case
3
:
oov
&=
~
(
PWM_OOV_OOVL3
|
PWM_OOV_OOVH3
);
pwm
->
private
->
outputh
=
PWM_OS_OSL3
;
pwm
->
private
->
outputl
=
PWM_OS_OSH3
;
break
;
}
pwm_output_override_set
(
pwm
->
private
->
pwm
,
oov
);
pwm_output_selection_set_update
(
pwm
->
private
->
pwm
,
pwm
->
private
->
outputh
|
pwm
->
private
->
outputl
);
pwm_sync_mode_set
(
pwm
->
private
->
pwm
,
PWM_SCM_SYNC0
|
PWM_SCM_SYNC1
|
PWM_SCM_SYNC2
|
PWM_SCM_SYNC3
);
pwm_channel_mode_set
(
pwm
->
private
->
pwm
,
ch_nr
,
PWM_CMR_CPOL
|
PWM_CMR_DPOLI
|
PWM_CMR_DTLI
);
pwm_channel_period_set
(
pwm
->
private
->
pwm
,
ch_nr
,
period
);
pwm_channel_duty_cycle_update_set
(
pwm
->
private
->
pwm
,
ch_nr
,
0
);
pwm_channel_dead_time_set
(
pwm
->
private
->
pwm
,
ch_nr
,
0
);
pwm_sync_update
(
pwm
->
private
->
pwm
);
pwm_enable
(
pwm
->
private
->
pwm
,
ch_nr
);
if
(
controller_block_add
(
pwm
))
goto
err_add
;
return
pwm
;
err_add:
err_interm:
controller_block_free
(
pwm
);
err_alloc:
return
NULL
;
}
BLOCK_CREATE
(
atsamx70_pwm
)
=
{
.
create
=
block_atsamx70_pwm_create
,