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
Tammo Jan Dijkema
dt_ctrl
Commits
d51e2d53
Commit
d51e2d53
authored
Nov 09, 2014
by
Jeroen Vreeken
Browse files
Add qed
parent
02339b0e
Changes
5
Hide whitespace changes
Inline
Side-by-side
controller/am335x/am335x.h
View file @
d51e2d53
...
...
@@ -21,6 +21,7 @@
#include <inttypes.h>
#include <unistd.h>
#define AM335X_SYSCLK 100000000
#define AM335X_ADC_BASE 0x44e0d000
#define AM335X_ADC_SIZE 0x00002000
...
...
@@ -33,25 +34,61 @@
#define AM335X_PWMSS_REG_IDVER 0x000
#define AM335X_PWMSS_IDVER_SCHEME_GET(x) (((x) & 0xc0000000) >> 30)
#define AM335X_PWMSS_IDVER_FUNC_GET(x) (((x) & 0x0fff0000) >> 16)
#define AM335X_PWMSS_IDVER_FUNC 0x
00
0
#define AM335X_PWMSS_IDVER_FUNC 0x
74
0
#define AM335X_PWMSS_IDVER_X_MAJOR_GET(x) (((x) & 0x00000700) >> 8)
#define AM335X_PWMSS_IDVER_Y_MINOR_GET(x) (((x) & 0x0000001f) )
#define AM335X_PWMSS_REG_SYSCONFIG 0x004
#define AM335X_PWMSS_REG_CLKCONFIG 0x008
#define AM335X_PWMSS_CLKCONFIG_EPWMCLK_EN 0x00000100
#define AM335X_PWMSS_CLKCONFIG_EPWMCLKSTOP_REQ 0x00000200
#define AM335X_PWMSS_CLKCONFIG_EQEDCLK_EN 0x00000010
#define AM335X_PWMSS_CLKCONFIG_EQEDCLKSTOP_REQ 0x00000020
#define AM335X_PWMSS_REG_CLKSTATUS 0x00c
#define AM335X_PWMSS_REG_EPWM_TBCTL 0x200
#define AM335X_PWMSS_EPWM_TBCTL_CLKDIV_SET(x) ((x) << 10)
#define AM335X_PWMSS_EPWM_TBCTL_CLKDIV_MAX 7
#define AM335X_PWMSS_EPWM_TBCTL_SYNC0SEL_DIS 0x00000030
#define AM335X_PWMSS_EPWM_TBCTL_CTRMODE_UP 0x00000000
#define AM335X_PWMSS_EPWM_TBCTL_CTRMODE_DN 0x00000001
#define AM335X_PWMSS_EPWM_TBCTL_CTRMODE_UD 0x00000002
#define AM335X_PWMSS_EPWM_TBCTL_CTRMODE_SF 0x00000003
#define AM335X_PWMSS_REG_EPWM_TBSTS 0x202
#define AM335X_PWMSS_REG_EPWM_TBPHSHR 0x204
#define AM335X_PWMSS_REG_EPWM_TBPHS 0x206
#define AM335X_PWMSS_REG_EPWM_TBCNT 0x208
#define AM335X_PWMSS_REG_EPWM_TBPRD 0x20a
#define AM335X_PWMSS_EPWM_TBPRD_MAX 0xffff
#define AM335X_PWMSS_REG_EPWM_CMPCTL 0x20e
#define AM335X_PWMSS_REG_EPWM_CMPAHR 0x210
#define AM335X_PWMSS_REG_EPWM_CMPA 0x212
#define AM335X_PWMSS_REG_EPWM_CMPB 0x214
#define AM335X_PWMSS_REG_EPWM_AQCTLA 0x216
#define AM335X_PWMSS_REG_EPWM_AQCTLB 0x218
#define AM335X_PWMSS_EPWM_AQCTLA_CBD_NOP 0x0000
#define AM335X_PWMSS_EPWM_AQCTLA_CBD_CLR 0x0400
#define AM335X_PWMSS_EPWM_AQCTLA_CBD_SET 0x0800
#define AM335X_PWMSS_EPWM_AQCTLA_CBD_TGL 0x0c00
#define AM335X_PWMSS_EPWM_AQCTLA_CBU_NOP 0x0000
#define AM335X_PWMSS_EPWM_AQCTLA_CBU_CLR 0x0100
#define AM335X_PWMSS_EPWM_AQCTLA_CBU_SET 0x0200
#define AM335X_PWMSS_EPWM_AQCTLA_CBU_TGL 0x0300
#define AM335X_PWMSS_EPWM_AQCTLA_CAD_NOP 0x0000
#define AM335X_PWMSS_EPWM_AQCTLA_CAD_CLR 0x0040
#define AM335X_PWMSS_EPWM_AQCTLA_CAD_SET 0x0080
#define AM335X_PWMSS_EPWM_AQCTLA_CAD_TGL 0x00c0
#define AM335X_PWMSS_EPWM_AQCTLA_CAU_NOP 0x0000
#define AM335X_PWMSS_EPWM_AQCTLA_CAU_CLR 0x0010
#define AM335X_PWMSS_EPWM_AQCTLA_CAU_SET 0x0020
#define AM335X_PWMSS_EPWM_AQCTLA_CAU_TGL 0x0030
#define AM335X_PWMSS_EPWM_AQCTLA_PRD_NOP 0x0000
#define AM335X_PWMSS_EPWM_AQCTLA_PRD_CLR 0x0004
#define AM335X_PWMSS_EPWM_AQCTLA_PRD_SET 0x0008
#define AM335X_PWMSS_EPWM_AQCTLA_PRD_TGL 0x000c
#define AM335X_PWMSS_EPWM_AQCTLA_ZRO_NOP 0x0000
#define AM335X_PWMSS_EPWM_AQCTLA_ZRO_CLR 0x0001
#define AM335X_PWMSS_EPWM_AQCTLA_ZRO_SET 0x0002
#define AM335X_PWMSS_EPWM_AQCTLA_ZRO_TGL 0x0003
#define AM335X_PWMSS_REG_EPWM_AQSFRC 0x21a
#define AM335X_PWMSS_REG_EPWM_AQCSFRC 0x21c
#define AM335X_PWMSS_REG_EPWM_DBCTL 0x21e
...
...
@@ -59,6 +96,8 @@
#define AM335X_PWMSS_REG_EPWM_DBFED 0x222
#define AM335X_PWMSS_REG_EPWM_TZSEL 0x224
#define AM335X_PWMSS_REG_EPWM_TZCTL 0x228
#define AM335X_PWMSS_EPWM_TZCTL_TZA_NOP 0x00000003
#define AM335X_PWMSS_EPWM_TZCTL_TZB_NOP 0x0000000c
#define AM335X_PWMSS_REG_EPWM_TZEINT 0x22a
#define AM335X_PWMSS_REG_EPWM_TZFLG 0x22c
#define AM335X_PWMSS_REG_EPWM_TZCLR 0x22e
...
...
@@ -71,6 +110,32 @@
#define AM335X_PWMSS_REG_EPWM_PCCTL 0x23c
#define AM335X_PWMSS_REG_EPWM_HRCNFG 0x2c0
#define AM335X_PWMSS_REG_ECEP_QPOSCNT 0x180
#define AM335X_PWMSS_REG_ECEP_QPOSINIT 0x184
#define AM335X_PWMSS_REG_ECEP_QPOSMAX 0x188
#define AM335X_PWMSS_REG_ECEP_QPOSCMP 0x18c
#define AM335X_PWMSS_REG_ECEP_QPOSILAT 0x190
#define AM335X_PWMSS_REG_ECEP_QPOSSLAT 0x194
#define AM335X_PWMSS_REG_ECEP_QPOSLAT 0x198
#define AM335X_PWMSS_REG_ECEP_QUTMR 0x19c
#define AM335X_PWMSS_REG_ECEP_QUPRD 0x1a0
#define AM335X_PWMSS_REG_ECEP_QWDTMR 0x1a4
#define AM335X_PWMSS_REG_ECEP_QWDPRD 0x1a6
#define AM335X_PWMSS_REG_ECEP_QDECCTL 0x1a8
#define AM335X_PWMSS_REG_ECEP_QEPCTL 0x1aa
#define AM335X_PWMSS_REG_ECEP_QCAPCTL 0x1ac
#define AM335X_PWMSS_REG_ECEP_QPOSCTL 0x1ae
#define AM335X_PWMSS_REG_ECEP_QEINT 0x1b0
#define AM335X_PWMSS_REG_ECEP_QFLG 0x1b2
#define AM335X_PWMSS_REG_ECEP_QCLR 0x1b4
#define AM335X_PWMSS_REG_ECEP_QFRC 0x1b6
#define AM335X_PWMSS_REG_ECEP_QEPSTS 0x1b8
#define AM335X_PWMSS_REG_ECEP_QCTMR 0x1ba
#define AM335X_PWMSS_REG_ECEP_QCPRD 0x1bc
#define AM335X_PWMSS_REG_ECEP_QCTMRLAT 0x1be
#define AM335X_PWMSS_REG_ECEP_QCPRDLAT 0x1c0
#define AM335X_PWMSS_REG_ECEP_REVID 0x1dc
#define AM335X_PWMSS_ECEP_REVID 0x44d31103
#define AM335X_ADC_REG_REVISION 0x000
#define AM335X_ADC_REVISION_SCHEME_GET(x) (((x) & 0xc0000000) >> 30)
...
...
controller/am335x/block_am335x_pwm.c
View file @
d51e2d53
...
...
@@ -26,24 +26,119 @@
#include <fcntl.h>
#include <inttypes.h>
#include <unistd.h>
#include <math.h>
struct
controller_block_private
{
float
*
in
;
uint16_t
tbprd
;
// period
double
freq
;
bool
sym
;
void
*
base
;
};
static
void
pwm_calculate
(
struct
controller_block
*
pwm
)
{
struct
controller_block_private
*
priv
=
pwm
->
private
;
float
in
;
uint16_t
cmp
;
uint16_t
tbprd
;
bool
sign
;
void
*
base
=
priv
->
base
;
tbprd
=
priv
->
tbprd
;
in
=
*
priv
->
in
;
sign
=
signbit
(
in
);
cmp
=
fmax
(
fabsf
(
in
*
tbprd
),
tbprd
);
if
(
sign
)
{
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_CMPA
,
0
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_CMPB
,
cmp
);
}
else
{
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_CMPA
,
cmp
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_CMPB
,
0
);
}
}
static
void
set_freq
(
struct
controller_block
*
pwm
)
{
struct
controller_block_private
*
priv
=
pwm
->
private
;
void
*
base
=
priv
->
base
;
int
clkdiv
=
0
;
int
div
=
1
;
double
period
,
freq
;
uint16_t
tbprd
;
/* double divider for symmetric use */
period
=
AM335X_SYSCLK
/
(
priv
->
freq
*
(
priv
->
sym
?
2
.
0
:
1
.
0
));
while
(
period
>
AM335X_PWMSS_EPWM_TBPRD_MAX
)
{
clkdiv
++
;
div
*=
2
;
period
/=
2
.
0
;
if
(
clkdiv
==
AM335X_PWMSS_EPWM_TBCTL_CLKDIV_MAX
)
break
;
}
tbprd
=
period
;
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_TBCTL
,
AM335X_PWMSS_EPWM_TBCTL_CLKDIV_SET
(
clkdiv
)
|
AM335X_PWMSS_EPWM_TBCTL_SYNC0SEL_DIS
|
AM335X_PWMSS_EPWM_TBCTL_CTRMODE_UD
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_CMPCTL
,
0
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_AQCTLA
,
AM335X_PWMSS_EPWM_AQCTLA_CBD_NOP
|
AM335X_PWMSS_EPWM_AQCTLA_CBU_NOP
|
AM335X_PWMSS_EPWM_AQCTLA_CAD_SET
|
AM335X_PWMSS_EPWM_AQCTLA_CAU_CLR
|
AM335X_PWMSS_EPWM_AQCTLA_PRD_NOP
|
AM335X_PWMSS_EPWM_AQCTLA_PRD_NOP
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_AQCTLB
,
AM335X_PWMSS_EPWM_AQCTLA_CAD_NOP
|
AM335X_PWMSS_EPWM_AQCTLA_CAU_NOP
|
AM335X_PWMSS_EPWM_AQCTLA_CBD_SET
|
AM335X_PWMSS_EPWM_AQCTLA_CBU_CLR
|
AM335X_PWMSS_EPWM_AQCTLA_PRD_NOP
|
AM335X_PWMSS_EPWM_AQCTLA_PRD_NOP
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_AQSFRC
,
0
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_TBPRD
,
tbprd
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_CMPA
,
0
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_CMPB
,
0
);
priv
->
tbprd
=
tbprd
;
freq
=
AM335X_SYSCLK
/
(
tbprd
*
div
*
(
priv
->
sym
?
2
.
0
:
1
.
0
));
log_send
(
LOG_T_DEBUG
,
"%s: Frequency: %gHz, period: %d ticks, divider: %d"
,
pwm
->
name
,
freq
,
tbprd
,
div
);
priv
->
freq
=
freq
;
}
static
struct
controller_block_param_list
params
[]
=
{
{
"frequency"
,
false
},
{
"symmetrical"
,
false
},
{
NULL
},
};
static
void
param_set
(
struct
controller_block
*
pwm
,
int
param
,
va_list
val
)
{
switch
(
param
)
{
case
0
:
pwm
->
private
->
freq
=
va_arg
(
val
,
double
);
set_freq
(
pwm
);
break
;
case
1
:
pwm
->
private
->
sym
=
va_arg
(
val
,
int
);
set_freq
(
pwm
);
break
;
}
}
static
struct
controller_block_interm_list
interms
[]
=
{
...
...
@@ -105,6 +200,17 @@ struct controller_block * block_am335x_pwm_create(char *name, va_list ap)
goto
err_rev
;
}
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_PCCTL
,
0
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_DBCTL
,
0
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_TZCTL
,
AM335X_PWMSS_EPWM_TZCTL_TZA_NOP
|
AM335X_PWMSS_EPWM_TZCTL_TZB_NOP
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_TZEINT
,
0
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_ETSEL
,
0
);
am335x_write16
(
base
,
AM335X_PWMSS_REG_EPWM_HRCNFG
,
0
);
if
(
!
(
pwm
=
controller_block_alloc
(
"am355x_pwm"
,
name
,
sizeof
(
struct
controller_block_private
))))
goto
err_alloc
;
...
...
@@ -113,6 +219,15 @@ struct controller_block * block_am335x_pwm_create(char *name, va_list ap)
pwm
->
private
->
base
=
base
;
pwm
->
private
->
sym
=
true
;
pwm
->
private
->
freq
=
10000
;
set_freq
(
pwm
);
am335x_write32
(
base
,
AM335X_PWMSS_REG_CLKCONFIG
,
(
am335x_read32
(
base
,
AM335X_PWMSS_REG_CLKCONFIG
)
&
~
AM335X_PWMSS_CLKCONFIG_EPWMCLKSTOP_REQ
)
|
AM335X_PWMSS_CLKCONFIG_EPWMCLK_EN
);
pwm
->
calculate
=
pwm_calculate
;
if
(
controller_block_param_list_init
(
pwm
,
params
))
...
...
controller/am335x/block_am335x_qed.c
0 → 100644
View file @
d51e2d53
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2014
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 "am335x.h"
#include <controller/controller_block.h>
#include <log/log.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <inttypes.h>
#include <unistd.h>
#include <math.h>
struct
controller_block_private
{
int32_t
cnt
;
void
*
base
;
};
static
void
qed_calculate
(
struct
controller_block
*
qed
)
{
struct
controller_block_private
*
priv
=
qed
->
private
;
void
*
base
=
priv
->
base
;
int32_t
cnt
;
cnt
=
am335x_read32
(
base
,
AM335X_PWMSS_REG_ECEP_QPOSCNT
);
priv
->
cnt
=
cnt
;
}
static
struct
controller_block_param_list
params
[]
=
{
{
NULL
},
};
static
void
param_set
(
struct
controller_block
*
qed
,
int
param
,
va_list
val
)
{
}
static
struct
controller_block_outterm_list
outterms
[]
=
{
{
"count"
,
CONTROLLER_BLOCK_TERM_SINT32
,
offsetof
(
struct
controller_block_private
,
cnt
)
},
{
NULL
},
};
struct
controller_block
*
block_am335x_qed_create
(
char
*
name
,
va_list
ap
)
{
struct
controller_block
*
qed
;
int
fd
;
void
*
base
;
uint32_t
reg
;
int
qed_nr
;
size_t
offset
;
qed_nr
=
va_arg
(
ap
,
int
);
if
(
qed_nr
<
0
||
qed_nr
>
2
)
{
log_send
(
LOG_T_ERROR
,
"%s: qed%d is not valid. (valid: 0-2)"
,
name
,
qed_nr
);
return
NULL
;
}
switch
(
qed_nr
)
{
case
0
:
offset
=
AM335X_PWMSS0_BASE
;
break
;
case
1
:
offset
=
AM335X_PWMSS1_BASE
;
break
;
case
2
:
offset
=
AM335X_PWMSS2_BASE
;
break
;
}
if
((
fd
=
open
(
"/dev/mem"
,
O_RDWR
|
O_SYNC
))
<
0
)
{
log_send
(
LOG_T_ERROR
,
"%s: Error opening /dev/mem"
,
name
);
close
(
fd
);
return
NULL
;
}
base
=
mmap
(
NULL
,
AM335X_PWMSS_SIZE
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
fd
,
offset
);
close
(
fd
);
if
(
!
base
)
{
log_send
(
LOG_T_ERROR
,
"Mapping QED failed"
);
return
NULL
;
}
log_send
(
LOG_T_DEBUG
,
"%s: QED mapped @ %p"
,
name
,
base
);
reg
=
am335x_read32
(
base
,
AM335X_PWMSS_REG_IDVER
);
log_send
(
LOG_T_DEBUG
,
"%s: IDVER: 0x%"
PRIx32
": func: 0x%03x rev: %d.%d"
,
name
,
reg
,
AM335X_PWMSS_IDVER_FUNC_GET
(
reg
),
AM335X_PWMSS_IDVER_X_MAJOR_GET
(
reg
),
AM335X_PWMSS_IDVER_Y_MINOR_GET
(
reg
));
if
(
AM335X_PWMSS_IDVER_FUNC_GET
(
reg
)
!=
AM335X_PWMSS_IDVER_FUNC
)
{
log_send
(
LOG_T_ERROR
,
"Unexpected functional number"
);
goto
err_rev
;
}
reg
=
am335x_read32
(
base
,
AM335X_PWMSS_REG_ECEP_REVID
);
log_send
(
LOG_T_DEBUG
,
"%s: REVID: 0x%"
PRIx32
,
name
,
reg
);
if
(
reg
!=
AM335X_PWMSS_ECEP_REVID
)
{
log_send
(
LOG_T_ERROR
,
"Unexpected REVID"
);
goto
err_rev
;
}
if
(
!
(
qed
=
controller_block_alloc
(
"am355x_qed"
,
name
,
sizeof
(
struct
controller_block_private
))))
goto
err_alloc
;
if
(
controller_block_outterm_list_init
(
qed
,
outterms
))
goto
err_outterm
;
qed
->
private
->
base
=
base
;
am335x_write32
(
base
,
AM335X_PWMSS_REG_ECEP_QPOSCNT
,
0
);
am335x_write32
(
base
,
AM335X_PWMSS_REG_ECEP_QPOSINIT
,
0
);
am335x_write32
(
base
,
AM335X_PWMSS_REG_CLKCONFIG
,
(
am335x_read32
(
base
,
AM335X_PWMSS_REG_CLKCONFIG
)
&
~
AM335X_PWMSS_CLKCONFIG_EQEDCLKSTOP_REQ
)
|
AM335X_PWMSS_CLKCONFIG_EQEDCLK_EN
);
qed
->
calculate
=
qed_calculate
;
if
(
controller_block_param_list_init
(
qed
,
params
))
goto
err_param
;
qed
->
param_set
=
param_set
;
controller_block_add
(
qed
);
return
qed
;
err_param:
err_outterm:
controller_block_free
(
qed
);
err_alloc:
err_rev:
munmap
(
base
,
AM335X_PWMSS_SIZE
);
return
NULL
;
}
controller/am335x/build.mk
View file @
d51e2d53
...
...
@@ -3,7 +3,8 @@ BLOCK_TARGETS := $(LIBDIR)/libam335x.la
BLOCK_SRCS
:=
\
$(DIR)
/block_am335x_adc.c
\
$(DIR)
/block_am335x_pwm.c
$(DIR)
/block_am335x_pwm.c
\
$(DIR)
/block_am335x_qed.c
BLOCK_OBJS
:=
$(BLOCK_SRCS:.c=.lo)
...
...
controller/controller/controller_block.c
View file @
d51e2d53
...
...
@@ -290,6 +290,7 @@ int controller_block_sample_init(void)
}
}
calculates
=
calloc
(
sizeof
(
struct
calculate_func
),
1
);
for
(
i
=
0
;
i
<
nr_blocks
;
i
++
)
{
if
(
blocks
[
i
]
->
calculate
)
{
log_send
(
LOG_T_DEBUG
,
...
...
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