Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Software for White Rabbit PTP Core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
32
Issues
32
List
Board
Labels
Milestones
Merge Requests
6
Merge Requests
6
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Software for White Rabbit PTP Core
Commits
27afa141
Commit
27afa141
authored
Mar 11, 2020
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dev: driver for AD9910 DDS SPI configuration
parent
846d2be5
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
183 additions
and
0 deletions
+183
-0
ad9910.c
dev/ad9910.c
+132
-0
dev.mk
dev/dev.mk
+1
-0
ad9910.h
include/dev/ad9910.h
+50
-0
No files found.
dev/ad9910.c
0 → 100644
View file @
27afa141
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* 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 <stdint.h>
#include <stdio.h>
#include "dev/gpio.h"
#include "dev/bb_spi.h"
#include "dev/ad9910.h"
#define AD9910_REF_FREQ ( 1000000000ULL ) // 1 GHz
static
struct
ad9910_config_reg
ad9910_default_config
[]
=
{
{
0
,
0x02000002
|
(
1
<<
13
),
32
},
// CFR1, unidir mode for SDIO, autoclear phase accumulator on IOUPDATE
{
1
,
0x00000800
,
32
},
// CFR2, TW - enabled sync pulse timing validation
{
2
,
0x1f3fc000
,
32
},
// CFR3: no PLL
{
3
,
0x00007f64
,
32
},
// Aux DAC control: DAC Full scale current
{
4
,
0xffffffff
,
32
},
// IO update rate
{
7
,
0x00000000
,
32
},
// default FTW
{
8
,
0x0000
,
16
},
// default phase offset
{
9
,
0x00000000
,
32
},
// amplitude scale factors
{
0xa
,
0x00000000
,
32
},
// multichip sync
{
0xe
,
0x08b5000039374bc7ULL
,
64
},
// profile 0: 223.5 MHz, 0 deg phi, ASF 0.13
{
-
1
,
0
,
0
}};
uint64_t
ad9910_read
(
struct
ad9910_device
*
dev
,
uint32_t
reg
,
int
nbits
)
{
uint64_t
rv
;
bb_spi_cs
(
dev
->
bus
,
1
);
bb_spi_write
(
dev
->
bus
,
reg
|
0x80
,
8
);
rv
=
bb_spi_read
(
dev
->
bus
,
nbits
);
bb_spi_cs
(
dev
->
bus
,
0
);
return
rv
;
}
void
ad9910_write
(
struct
ad9910_device
*
dev
,
uint32_t
reg
,
uint64_t
value
,
int
nbits
)
{
bb_spi_cs
(
dev
->
bus
,
1
);
bb_spi_write
(
dev
->
bus
,
reg
,
8
);
bb_spi_write
(
dev
->
bus
,
value
,
nbits
);
bb_spi_cs
(
dev
->
bus
,
0
);
}
void
ad9910_trigger_update
(
struct
ad9910_device
*
dev
)
{
dev
->
trigger_io_update
(
dev
);
}
#define AD9910_REG_CFR1 1
#define AD9910_DEFAULT_CFR1 0x400820
int
ad9910_probe
(
struct
ad9910_device
*
dev
,
struct
spi_bus
*
bus
,
void
(
*
trigger_io_update
)(
struct
ad9910_device
*
dev
)
)
{
dev
->
bus
=
bus
;
dev
->
trigger_io_update
=
trigger_io_update
;
bb_spi_cs
(
dev
->
bus
,
0
);
ad9910_write
(
dev
,
0
,
0x02000002
,
32
);
// unidir mode for SDIO
ad9910_trigger_update
(
dev
);
uint32_t
id
=
ad9910_read
(
dev
,
AD9910_REG_CFR1
,
32
);
pp_printf
(
"AD9910 ID[%p]: 0x%x (expected 0x%x)
\n
"
,
dev
,
id
,
AD9910_DEFAULT_CFR1
);
return
(
id
==
AD9910_DEFAULT_CFR1
)
?
0
:
-
1
;
}
int
ad9910_program
(
struct
ad9910_device
*
dev
,
uint64_t
ftw_n
,
int
phase
,
int
fs_current
)
{
int
i
;
// formula (2) from AD9910 datasheet, page 22
uint64_t
ftw
=
ftw_n
;
uint64_t
prof0_cr
=
ftw
|
(
0x8b5ULL
<<
48
);
// pp_printf("ad9910_program [%08x%08x] asf %d!\n", (uint32_t)(prof0_cr >> 32), (uint32_t)prof0_cr, asf );
for
(
i
=
0
;
ad9910_default_config
[
i
].
addr
>=
0
;
i
++
)
{
struct
ad9910_config_reg
r
=
ad9910_default_config
[
i
];
if
(
r
.
addr
==
3
)
{
r
.
value
&=
0xffffff00
;
r
.
value
|=
fs_current
;
// Aux DAC control: DAC Full scale current
// pp_printf("auxdac %08x\n", (uint32_t) r.value );
}
else
if
(
r
.
addr
==
0xe
)
// profile 0
r
.
value
=
prof0_cr
;
ad9910_write
(
dev
,
r
.
addr
,
r
.
value
,
r
.
nbits
);
}
ad9910_trigger_update
(
dev
);
return
0
;
}
#define AD9910_SYNC_VERIF_DELAY_TAPS 0
void
ad9910_configure_sync
(
struct
ad9910_device
*
dev
,
int
enable
,
int
fine_delay_taps
)
{
uint32_t
r10
=
((
fine_delay_taps
&
0x1f
)
<<
3
)
|
(
enable
?
(
1
<<
27
)
:
0
)
|
(
AD9910_SYNC_VERIF_DELAY_TAPS
<<
28
)
|
(
1
<<
26
);
ad9910_write
(
dev
,
0xa
,
0
,
32
);
ad9910_write
(
dev
,
0x1
,
0x00000820
,
32
);
// CFR2, TW - enabled sync pulse timing validation
ad9910_trigger_update
(
dev
);
ad9910_write
(
dev
,
0x1
,
0x00000800
,
32
);
// CFR2, TW - enabled sync pulse timing validation
ad9910_write
(
dev
,
0xa
,
r10
,
32
);
ad9910_trigger_update
(
dev
);
}
dev/dev.mk
View file @
27afa141
...
...
@@ -21,6 +21,7 @@ obj-$(CONFIG_EMBEDDED_NODE) += \
dev/74x595.o \
dev/ad7888.o \
dev/ad951x.o \
dev/ad9910.o \
dev/clock_monitor.o
obj-$(CONFIG_WR_NODE) += \
...
...
include/dev/ad9910.h
0 → 100644
View file @
27afa141
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* 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/>.
*/
#ifndef __AD9910_H
#define __AD9910_H
#include <stdint.h>
#include <stdio.h>
#include "dev/gpio.h"
#include "dev/bb_spi.h"
struct
ad9910_device
{
struct
spi_bus
*
bus
;
void
(
*
trigger_io_update
)(
struct
ad9910_device
*
dev
);
};
struct
ad9910_config_reg
{
int
addr
;
uint64_t
value
;
int
nbits
;
};
int
ad9910_program
(
struct
ad9910_device
*
dev
,
uint64_t
freq_hz
,
int
phase
,
int
fs_current
);
uint64_t
ad9910_read
(
struct
ad9910_device
*
dev
,
uint32_t
reg
,
int
nbits
);
void
ad9910_write
(
struct
ad9910_device
*
dev
,
uint32_t
reg
,
uint64_t
value
,
int
nbits
);
int
ad9910_probe
(
struct
ad9910_device
*
dev
,
struct
spi_bus
*
bus
,
void
(
*
trigger_io_update
)(
struct
ad9910_device
*
dev
)
);
void
ad9910_trigger_update
(
struct
ad9910_device
*
dev
);
void
ad9910_configure_sync
(
struct
ad9910_device
*
dev
,
int
enable
,
int
fine_delay_taps
);
#endif
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