Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: программирование AD9954 через SPI посредством ADSP21364
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
WreWolf
В каком формате данные должны посылаться в ДДС,
и что необходимо для начала генерации.

ставлю I/O Synk в 1
Посылаю в MSBF
данные по 3-Wire в CFR1
I/O Update
данные PLL в CFR2
I/O Update
Записываю FTW0
снова I/O Update

где ошибка?
пробовал предварительно записать во все регистры 0x00
не помогло.

Смотрел времянку по которой с ДДС общаеться родной софт от АД. ничего нового не вижу.
Genadi Zawidowski
Не забыть снять в 0 IOSYNC сразу после установки перед дальнейшей работой.
Донышко микросхеме припаяли к земле?

Проект из сообщения в форуме http://forum.cqham.ru/viewtopic.php?p=274192#274192
скачайте - там есть обслуга AD9951 работающая - должен пойти, мне кажется. Потом доработаете.
Цитата
где ошибка?

Может быть что-то с выходным умножителем - не включйте ASF. Иначе придётся и его программировать.
0 засылать не надо - состояние после ресета вполне соответствует паспортным данным.
Adlex
На всякий случай проверьте, не загоняете ли ДДС в запрещенные режимы (программно), и попробуйте прочитать из чипа, что Вы в него записали.
Безусловно провериьь еще раз схему включения, наличия питания на всех ногах (1,8 и 3,3), земли на всех ногах.

Так ответить что-то конкретное трудно, не ясно даже это вина софта или железа...
Если укажите тип процессора управления, может кто-то вышлет Вам готовую рабочую прошивку
DpInRock
Формат описан абсолютно однозначно.

Как минимум, надо быть уверенным, что поступают клоки нужной амплитуды.
Genadi Zawidowski
Цитата(Adlex @ Aug 26 2009, 23:55) *
На всякий случай проверьте, не загоняете ли ДДС в запрещенные режимы (программно), и попробуйте прочитать из чипа, что Вы в него записали.
Безусловно провериьь еще раз схему включения, наличия питания на всех ногах (1,8 и 3,3), земли на всех ногах.

Так ответить что-то конкретное трудно, не ясно даже это вина софта или железа...
Если укажите тип процессора управления, может кто-то вышлет Вам готовую рабочую прошивку


Автор написал - ADSP21364.
Я бы предложил сперва методом ножкодрыгательства spi создать и писать в чип. Когда появится уверенность в том, что все коды правильные - осваивать SPI контроллер.
Ну, и для начала - снять единицу с вывода iosync перед программированием, вплоть до того, что заземлить провод.
Готовую программу для ножкодрыгательства на Cи я уж послал (ссылочку)... там всё проверенно.

Цитата
Формат описан абсолютно однозначно.

Присоединяюсь.
WreWolf
Ну скажем используються 2 платы EZ-LITE и Эвалюшен с ДДС
так что все припаяно правильно.
Использую штатный SPI на EZ-LITE
считать ничего не получаеться. Т.е. бит отвечаюший за передачу по 3 проводам не пишеться.
Genadi Zawidowski
Цитата(WreWolf @ Aug 29 2009, 11:23) *
Ну скажем используються 2 платы EZ-LITE и Эвалюшен с ДДС
так что все припаяно правильно.
Использую штатный SPI на EZ-LITE
считать ничего не получаеться. Т.е. бит отвечаюший за передачу по 3 проводам не пишеться.

Как говорится, телепаты в отпуске.

В писме не просматирваются знаачения управляющих слов, используемых для программирования dds, тактовая частота dds, проверьте положение перемычек (или сообщите тип платы и положение перемычек).
С ez-lite кто-нибудь да работал, им тоже поможет информация о том, как прогрммируется spi. Что мешает попробовать двумя ножками с GPIO выдать SPI?

Мои рекомендации по управлению учли? Я про iosync. Помогло?
WreWolf
про iosync попробую в понедельник.
а spi работает на осцилографе все как надо.
CLOCK
Данные и I/O Update после записи каждого регистра данных.
тактовая частота ддс 48Мег, но это не так важно. выдавать он должен. по крайней мере при программировании с PC все работает.
Genadi Zawidowski
Понедельник прошёл... Как дела с синтезатором?
WreWolf
ну тип процессора ADSP-21364
стоит на плате EZ-Lite
читать тоже нормально не получаеться. либо я что то неправильно делаю.

ustat3=rx_buf; dm(IISPI)=ustat3;
ustat3=@rx_buf; dm(CSPI)=ustat3;
ustat3=WL8?SPIMS?SPIEN?TIMOD2?MSBF; dm(SPICTL)=ustat3;
ustat3=SPIRCV?SPICHEN; dm(SPIDMAC)=ustat3;

по идее этот код должен принять столько байт, какой длинны массив rx_buf
если неправ поправьте.

Установка I/O Sync в 0 во время программирования ничего не дала.

подключение такое
клок к клоку
MISO к SDO
MOSI к SDIO
FLAG1 к FUD(I/O Update)
SPIDS к CS
на I/O Sync перемычка на землю.
WreWolf
я уже ничего не понимаю.
посмотрел все сигналы идушии с компа(при программировании ДДС)
повторил их на АДСП
и 0.

И еще странность в даташите на ддс указано что Chip Selekt инверсный вход. на времянке показано что он должен быть низким. соответственно его на 1 вешаем тогда от будет 0.
а комп наоборот его в 0 роняет.

так же никакой активности на выводах I/O Sync, P0, P1, OSK, CLKMODESEL,
но все работает.

П.С.
если можно еще пару слов про конфигурирвание DAI да вывод
Genadi Zawidowski
Цитата(WreWolf @ Sep 8 2009, 13:04) *
я уже ничего не понимаю.
посмотрел все сигналы идушии с компа(при программировании ДДС)
повторил их на АДСП
и 0.

И еще странность в даташите на ддс указано что Chip Selekt инверсный вход. на времянке показано что он должен быть низким. соответственно его на 1 вешаем тогда от будет 0.
а комп наоборот его в 0 роняет.


И вам так же (в ноль вольт переходить) надо делать... Вы хоть из интереса в предложенные мною исходники залезли бы - там на русском языке специально комментарии стоят...
P0, P1, OSK, CLKMODESEL шевелиться не должны. Без I/O update - вывод 1 - (без импульса единичного на нём) не будет обновления состояния dds запрограммированными данными.
WreWolf
Ну в исходники, то я сразу залез. Но много непонятного.
Просто из чтения даташита на ДДС.
Если установить бит автоматической очистки фазового акумулятора, то при перезаписи FTW0 автоматически должна поменяться частота генерации.
Итак. Программируем ДДС с компа(через родной софт) 1Мгц( 0x00AAAAAB),при частоте клока 48Мгц и коэф. х8 и влюченным VCO и Auto Clear Phase Accum.
отключаем плату DDS от LPT порта. Ставим ставим джампер на ресет(в землю) и переводим плату на ручное программирование(собственно мы отключаем буферные регистры(они дополнительно распаяны для программирования через ЛПТ)).
и шлем на SPI
0x04 // т.е. адресс FTW
и затем еще 32бита
0x01555555 т.е. частота 2МГц
затем дергаем I/O Update( он же FUD ) к единице на 20мкс и опускаем в 0
по даташиту Должна начаться генерация на новой частоте(2Мгц), но этого не происходит, частота как стояла на 1Мгц так и стоит...

куда копать уже не знаю.

Вот кусок даташита.
Пример программирования на генерацию
Цитата
SINGLE-TONE MODE
In this example, the part is programmed to output a 122 MHz
single-tone carrier, the device is clocked with a 20 MHz crystal
oscillator, and the clock multiplier is used to push the internal
system clock up to 400 MHz. Phase offsets are then added to
the carrier.
The programming steps include the following:
1. Write to Control Register 1 instructing the part to autoclear
the phase accumulator whenever the phase offset word
changes and issues an I/O update. Set Bit 13 in the CFR1
register. The address for CFR1 is 0; therefore, an instruction
byte of 0x00 is sent and 0x00 00 00 20 for data. Note that
users must write to all four bytes of the register.
2. Write to Control Register 2 setting the clock multiplier value
to 20, and the VCO range bit to its upper value. In CFR2,
Bit 7 to Bit 3 control the multiply value. To get a multiplied
value of 20 from 5 bits, the binary value is 10100. As
previously mentioned, also send Bit 2 to put the VCO into its
upper range (to get 400 MHz). Therefore, the instruction byte
is 0x01 and 0x00 00 A4 for data.
3. Calculate the tuning word to generate a 122 MHz output
from a 400 MSPS clock, load it into FTW0, and latch the
data written to the I/O buffers into their respective registers.
The frequency tuning word equation becomes (122 MHz/
400 MHz) × 232
, which yields 0x4E 14 7A E1. Send the
Instruction Byte 0x04 and four data bytes of 0x4E 14 7A E1.
Issue an I/O update, which transfers the data into the part.

Whenever a phase change is desired, calculate and write the
phase offset word to the part and issue an I/O update. For
example, if the first value is 45°, the phase offset word is
(45/360) × 214
, or in decimal, 2048. Therefore, write an
instruction byte of 0x05 and Data Byte 0x0800. When an
I/O update is issued, the phase accumulator clears, which
starts it from a known phase of 0°. It again accumulates at a
122 MHz rate, except now phase shifting each and every
sample by 45°.
WreWolf
И еще вопрос, зачем делается повторное программирование CFR2 и CFR1 причем в таком порядке.
С какой частотой пихать данные по SPI. В даташите указано макс 25МГц Клока.
Я же пихаю по клоку 100кГц или 10кГц(на этой работает комп), но толку никакого.
Уже пробовал и в MSB и LSB отправлять.

П.С.
но даже кспириментально осцилографом видно что комп в MSB отправляет.
в чем же может быть проблема
Genadi Zawidowski
О, Вы на правильном пути! Когда у меня поначалу не работало, чужая писюковая программа помогала...

Auto Clear Phase Accum - если Вам нужен переход с частоты на частоту с разрывом фазы, тогда применяйте.

Скорее всего, у Вас что-то не так с чипселектом.
Делаем так - начальное состояние /CS (нога 39) и SCLK (нога 40) - логическая 1.

Переводим /CS (ногу 39) в 0. Устанавливаем данные побитно, каждый бит стробируем переходом в 0, а затем в 1 ноги 40.
После последнего битв переводим ногу 39 в 1. Чтобы изменения вошли в силу, дёрнуть ногу 1 в единицу а затем в 0.
После переключений могло что-то считаться микросхемой - сбросить ногой iosync (37).
Аббревиатуры FUD в даташите не нашёл.
Двойное программирование - это от AD9852 осталось, тут действительно нет необходимости.
Если не переводите в режим LSB first, то и прбовать не надо. Там MSB first после reset.
WreWolf
Т.е. вы имеете в виду перед программирование выставлять и SCLK и CS в 1
затем опускать CS в 0 и дергать iosync чтобы начать новый цикл программирования.
единственное еще не пробовал перед циклом программирования дергать iosync
Genadi Zawidowski
iosync один раз после завешения переключения интерфейсных частей на свою программу.
WreWolf
CODE

#include <def21364.h>
.section/dm seg_dmda;
.var FTW0_b[]= 0x04,0xFF,0xAA,0xAA,0xAB;
.var irx= 0x84; // инициализация приема
.var rx_buf[4];
.var rx_tcb1[4] = 0,4,1,rx_buf;
.global _main;
.segment/pm seg_pmco;
_main:


/* Init SPI MASTER TX DMA */
r0=0;
dm(SPICTL)=r0;
dm(SPIFLG)=r0;
dm(SPIDMAC)=r0;
r0=500; dm(SPIBAUD) = r0;
r0=DS0EN; dm(SPIFLG) = r0;
bit set flags FLG1O;
bit clr flags FLG1;
up:
ustat3 = DS0EN;//| /*enable SPI slave device select zero */
//SPIFLG3|SPIFLG2|SPIFLG1|SPIFLG0; /* Set SPIFLG0 low to */
dm(SPIFLG) = ustat3; /*select SPI slave on FLAG0 pin */
/*===FTW0 Transmit===*/
ustat3=0xFF;
dm(SPISTAT)=ustat3;
ustat3=FTW0_b; dm(IISPI)=ustat3;
ustat3=@FTW0_b; dm(CSPI)=ustat3;
ustat3=1; dm(IMSPI)=ustat3;
ustat3 = DMISO|WL8|SPIMS|SPIEN|TIMOD2|MSBF; dm(SPICTL)=ustat3;
ustat3=SPIDEN;
dm(SPIDMAC)=ustat3;
r0=dm(CSPI);
r0=pass r0;
if gt jump (pc,-2);
ustat3=dm(SPISTAT);
bit tst ustat3 SPIF;
if tf jump (pc,-2);
lcntr=12000, do (pc,6) until LCE;
nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
bit set flags FLG1;
lcntr=240, do (pc,10) until LCE;
nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
bit clr flags FLG1;
lcntr=8000, do (pc,10) until LCE;
nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
nop;nop;



//jump up;
//SPI reset
r0=0;
dm(SPICTL)=r0;
dm(SPIFLG)=r0;
dm(SPIDMAC)=r0;
r0=500; dm(SPIBAUD) = r0;
r0=DS0EN; dm(SPIFLG) = r0;

/*===irx Transmit===*/
ustat3=0xFF;
dm(SPISTAT)=ustat3;
ustat3=irx; dm(IISPI)=ustat3;
ustat3=@irx; dm(CSPI)=ustat3;
ustat3=1; dm(IMSPI)=ustat3;
ustat3 = DMISO|WL8|SPIMS|SPIEN|TIMOD2|MSBF; dm(SPICTL)=ustat3;
ustat3=SPIDEN;
dm(SPIDMAC)=ustat3;
r0=0;
dm(SPICTL)=r0;
dm(SPIFLG)=r0;
dm(SPIDMAC)=r0;
r0=500; dm(SPIBAUD) = r0;
r0=DS0EN; dm(SPIFLG) = r0;

ustat3=0xFF;
dm(SPISTAT)=ustat3;

ustat3=rx_buf; dm(IISPI)=ustat3;
ustat3=@rx_buf; dm(CSPI)=ustat3;
ustat3=1; dm(IMSPI)=ustat3;
ustat3 = DMISO|WL8|SPIMS|SPIEN|TIMOD2|MSBF; dm(SPICTL)=ustat3;
ustat3=SPIRCV;
dm(SPIDMAC)=ustat3;
_main.end: jump (pc,0);



деуствую вот так.
дергаю iosync руками после переключения.
ответа все равно никакого нет, впрочем как и генерации
Genadi Zawidowski
Я не увидел, где в вашей программе дёргается IOUPDATE. Или это на приём?

Цитата
SDIO — Serial Data I/O. Data is always written into the
AD9951 on this pin. However, this pin can be used as a
bidirectional data line. Bit 9 of Register Address 0x00 controls the configuration of this pin. The default is Logic 0, which configures the SDIO pin as bidirectional.


В каком состоянии находится Bit 9 of Register Address 0x00 после программирования?
Genadi Zawidowski
Да, хотел обратить внимание, что команда чтения из регистра 4 не 0x04, а 0x84. После выдчи в чип одного командного байта остальные читать... Чес слово, просто записать пять байтов проще.
WreWolf
Ну вот это махание ioupdate

bit set flags FLG1;
lcntr=240, do (pc,10) until LCE;
nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
bit clr flags FLG1;

а так это был полный листинг всего

Вот участок приема.
Инициализации, т.е. отправка 0х84
/*===irx Transmit===*/
ustat3=0xFF;
dm(SPISTAT)=ustat3;
ustat3=irx; dm(IISPI)=ustat3;
ustat3=@irx; dm(CSPI)=ustat3;
ustat3=1; dm(IMSPI)=ustat3;
ustat3 = DMISO|WL8|SPIMS|SPIEN|TIMOD2|MSBF; dm(SPICTL)=ustat3;
ustat3=SPIDEN;
dm(SPIDMAC)=ustat3;
r0=0;
dm(SPICTL)=r0;
dm(SPIFLG)=r0;
dm(SPIDMAC)=r0;
r0=500; dm(SPIBAUD) = r0;
r0=DS0EN; dm(SPIFLG) = r0;

ustat3=0xFF;
dm(SPISTAT)=ustat3;

И прием

ustat3=rx_buf; dm(IISPI)=ustat3;
ustat3=@rx_buf; dm(CSPI)=ustat3;
ustat3=1; dm(IMSPI)=ustat3;
ustat3 = DMISO|WL8|SPIMS|SPIEN|TIMOD2|MSBF; dm(SPICTL)=ustat3;
ustat3=SPIRCV;
dm(SPIDMAC)=ustat3;


П.С.
А считать ничего не получаеться, дергай не дергай iosync перед инициализации приема
WreWolf
Вот в конце концов родилось такое.
Более читаемый код, и больше прозрачности в работе.
Но вот только никакого результата.

Хотя все сделано по даташиту, может есть еще идеи?
CODE
#include <def21364.h>
.section/dm seg_dmda;
.var CFR1_d[]= 0x00,0x00,0x00,0x02,0x08;
.var CFR2_d[]= 0x01,0x00,0x00,0x44;
.var FTW0_d[]= 0x04,0xAF,0xAA,0xAA,0xAB;
.var irx= 0x84;
.var rx_buf[4];
.var rx_tcb1[4] = 0,4,1,rx_buf;
.global _main;
.segment/pm seg_pmco;
_main:

call init; //Начальная инициализация
up_up:




//Передача данных
call SPI_init;
ustat3=CFR1_d; ustat4=@CFR1_d; //Установка входныхх данных и их длинны
call SPI_init_TX;

call SPI_init;
ustat3=CFR2_d; ustat4=@CFR2_d; //Установка входныхх данных и их длинны
call SPI_init_TX;

call SPI_init;
ustat3=FTW0_d; ustat4=@FTW0_d; //Установка входныхх данных и их длинны
call SPI_init_TX;


//Инициализация
call SPI_init;
ustat3=irx; ustat4=@irx;
call SPI_init_TX;

//и прием данных из DDS
call SPI_init;
ustat3=rx_buf; ustat4=@rx_buf;
call SPI_init_RX;

jump up_up;
_main.end: jump (pc,0);


//Инициализация SPI перед новой транзакцией
SPI_init:
call SPI_reset;
call SPI_init_FLG_reset_error;
rts;

//Инициализация флагов и пр.
init:
bit set flags FLG1O;
bit clr flags FLG1;
call SPI_reset;
call SPI_init_FLG_reset_error;
rts;

//Сброс параметров SPI
SPI_reset:
r0=0; dm(SPICTL)=r0;
dm(SPIFLG)=r0;
dm(SPIDMAC)=r0;
r0=500; dm(SPIBAUD)=r0;
r0=DS0EN; dm(SPIFLG)=r0;
rts;

//Начальная инициализация регистра SPIFLG и сброс ошибок
SPI_init_FLG_reset_error:
r0 = DS0EN|
SPIFLG3|
SPIFLG2|
SPIFLG1|
SPIFLG0; dm(SPIFLG) = ustat3;
ustat3=0x01; dm(SPISTAT)=ustat3;
rts;

//Махание флагом I/O Update
FLAG_IO:
lcntr=12000, do (pc,FLAG_IO1) until LCE;
nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;FLAG_IO1:
bit set flags FLG1;
lcntr=240, do (pc,FLAG_IO2) until LCE;
nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;FLAG_IO2:
bit clr flags FLG1;
lcntr=12000, do (pc,FLAG_IO3) until LCE;
nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;FLAG_IO3:
rts;

//Ожидание окончания передачи/приема
waitSPI:
r0=dm(CSPI);
lcntr=r0, do (pc,waitSPI_c) until LCE;
waitSPI_c:call wait_for_SPIF;
rts;

//Инициализация процесса передачи
SPI_init_TX:
dm(IISPI)=ustat3;
dm(CSPI)=ustat4;
ustat3=1; dm(IMSPI)=ustat3;
ustat3 = DMISO|
WL8|
SPIMS|
SPIEN|
TIMOD2|
MSBF; dm(SPICTL)=ustat3;
ustat3=SPIDEN; dm(SPIDMAC)=ustat3;
call waitSPI;
call FLAG_IO;
rts;

//Инициализация процесса приема
SPI_init_RX:
dm(IISPI)=ustat3;
dm(CSPI)=ustat4;
ustat3=1; dm(IMSPI)=ustat3;
ustat3 = DMISO|
WL8|
SPIMS|
SPIEN|
TIMOD2|
MSBF|
SENDZ; dm(SPICTL)=ustat3;
ustat3 = SPIDEN|
SPIRCV; dm(SPIDMAC)=ustat3;
call waitSPI;
call FLAG_IO;
rts;

//WAIT FOR SPI Transfert 1 Byte
wait_for_SPIF:
ustat1=dm(SPISTAT);
bit tst ustat1 SPIF;
if not tf jump (pc,wait_for_SPIF);
wait_for_SPIF.end:
rts;
DpInRock
Поменяйте полярность SPI. На не по даташиту.
WreWolf
Я делаю так. По пунктам.
1 Программирую DDS с компа на 1МГц и устанавливаю бит Автоматической очистки акумулятора фазы( по ДШ он отвечает за автоматическую смену частоты генерации сразу после записи нового управляющего значения в регистр частоты FTW0)
2 Отсоединяю LPT кабель от платы DDS
3 Вешаю перемычку от reset на землю
4 Запрещаю работу логики на плате DDS (пареключаю перемычку) ( перевожу плату в режим Manua Data In)
5 Соединяю 2 платы
a Землю к Земле
b MISO к SDO
c MOSI к SDIO
d CLK к SCLK
e FLAG1_SW1 к FUD_Dut1( I/O Update первого DDS)
f SPDIS к CBS_Dut1 (Chip Select первого DDS)
6 Вручную провожу I/O Sync
7 Запускаю программу на ADSP
8 Контролирую на осциллографе данные
9 Выполняю I/O Update
10 В DDS ничего не меняеться

вот фото передачи данных
DpInRock
Либо данные правильно идут в DSS, либо - неправильно. Третьего не дано (Вообще то дано, конечно - идут НЕ ТЕ ДАННЫЕ и НЕ ТУДА - но этот момент мы исключаем - он не лечится).

Следовательно, данные идут неправильно.
Следовательно, то, что мы делаем якбы правильно - на самом деле - неправильно.
Следвательно, надо сделать все варианты неправильного. Среди них окажется один правильный вариант.
WreWolf
ну я тогда даже не знаю
пробовал подать только клок и данные на SDIO
и руками дергать ио апдейт между посылками данных регистров

а при программировании с компа на ножке клока клок, а на SDIO данные
я уже не знаю что делать maniac.gif
WreWolf
Теперь я научился вчитывать все что записал комп в ддс, но от этого не стало легце.
При попотке записи этой инфы в ддс, он все равно молчит и считать ничего уже не получаеться
Ivan Panov
Цитата(WreWolf @ Oct 13 2009, 10:17) *
Теперь я научился вчитывать все что записал комп в ддс, но от этого не стало легце.
При попотке записи этой инфы в ддс, он все равно молчит и считать ничего уже не получаеться


Если Вы, WreWolf уверены, что микросхемы AD9854 и AD9954 идентичны по интерфейсу обмена я могу прислать Вам заведомо рабочий исходник для AD9854 на С для AVR. Но я SPI симулирую программно.
Genadi Zawidowski
Так и я давал исходники для любых чипв... Оригинатор пытается аппаратный SPI приручить.
WreWolf
Все приручилось. К сожалению пока криво, но это временно.

Оказалось 1 лишняя строка кода и не совсем корректный режим передачи( нужно было насильствено заставить его работать с начальным высоким клоком)

и пока дергаю руками IO_SYNK все заработало.

Хотя ничего не изменял по сути.

Делаю ресет IO и пишу данные.
затем еще раз ресет IO и читаю
так все заработало.
вот только еще ощибка к даташате почемуто появилась.
ну или у меня чтото с мозгами.
Просто когда hex слова считал для отправки в ДДС, оно в 1 месте не сошлось с тем что прочиталось после программирования компом.
А комп считывает то что я сам считал.

Как сконфигурировать пин DAI на выход FLAG15

SRU(FLAG15_O,DAI_PB05_I);
SRU(HIGH,PBEN05_I); // или SRU(LOW,PBEN05_I);

чтобы программно дергать IO reset

как отлажу будет исходник
Genadi Zawidowski
А я про стробирование перепадами в 0 говорил ещё месяц назад...
iosync не надо дёргать, один раз пред инициализацией. Если обязательно требуется - разбирайтесь.
Не путать с ioupdate.
Цитата
вот только еще ощибка к даташате почемуто появилась.
ну или у меня чтото с мозгами.
Просто когда hex слова считал для отправки в ДДС, оно в 1 месте не сошлось с тем что прочиталось после программирования компом.
А комп считывает то что я сам считал

Некоторые программисты используют вычисления с плавающей точкой для получений слов программирования - и теряют при этом битики (и тчность).
Попробуйте целочисленно.
WreWolf
Да я пока не использую вычисления. Все забито руками.
И IO_Synk нормально помогло только после смены режима SPI.

И нормально чтение гарантируеться только после повторного IO_Synk
Genadi Zawidowski
Значит где-т битиков не досчитались.
Цитата
Asynchronous Active High Reset of the Serial Port Controller. When high, the current I/O operation is immediately terminated, enabling a new I/O operation ...

Что-то не то скормили микросхеме.
Да попробуйте же в ручную битиками пошевелить! Когда ясность с управляющими словами настанет, будете SPI дрессировать.
WreWolf
Ну с битиками то все в порядке.
На осциллографе все выглядит прекрасно, значит я думаю и для ДДС тоже.

А про сброс текущего IO я знаю, по этому и дергаю.

вот код. битиков лишних нет
CODE
#include <def21364.h>
.section/dm seg_dmda;

.var CFR1_d[]= 0x00,0x00,0x00,0x22,0x00;
.var CFR2_d[]= 0x01,0x18,0x00,0x44;
.var FTW0_d[]= 0x04,0x0F,0xAA,0xAA,0xAB;
.var irx= 0x84;
.var rx_buf1[5];
.var rx_buf2[4];
.var rx_buf3[3];
.var rx_buf4[2];
.var rx_buf5[5];
.var rx_buf6[3];
.var rx_buf7[5];

.global _main;
.segment/pm seg_pmco;
_main:

call init; //Начальная инициализация
up_up:




//Передача данных
call SPI_init;
ustat3=CFR1_d; ustat4=@CFR1_d; //Установка входныхх данных и их длинны
call SPI_init_TX;


call SPI_init;
ustat3=CFR2_d; ustat4=@CFR2_d; //Установка входныхх данных и их длинны
call SPI_init_TX;


call SPI_init;
ustat3=FTW0_d; ustat4=@FTW0_d; //Установка входныхх данных и их длинны
call SPI_init_TX;



// прием данных из DDS
call SPI_init;
ustat3=rx_buf1; ustat4=@rx_buf1; ustat2=0x80;
call read_reg;

call SPI_init;
ustat3=rx_buf2; ustat4=@rx_buf2; ustat2=0x81;
call read_reg;

call SPI_init;
ustat3=rx_buf3; ustat4=@rx_buf3; ustat2=0x82;
call read_reg;

call SPI_init;
ustat3=rx_buf4; ustat4=@rx_buf4; ustat2=0x83;
call read_reg;

_main.end: jump (pc,0);


//Инициализация SPI перед новой транзакцией
SPI_init:
call SPI_reset;
call SPI_init_FLG_reset_error;
rts;

//Инициализация флагов и пр.
init:
bit set flags FLG1O;
bit clr flags FLG1;
call SPI_reset;
call SPI_init_FLG_reset_error;
rts;

//Сброс параметров SPI
SPI_reset:
r0=0; dm(SPICTL)=r0;
dm(SPIFLG)=r0;
dm(SPIDMAC)=r0;
r0=500; dm(SPIBAUD)=r0;
r0=DS0EN; dm(SPIFLG)=r0;
rts;

//Начальная инициализация регистра SPIFLG и сброс ошибок
SPI_init_FLG_reset_error:
ustat3=0x01; dm(SPISTAT)=ustat3;
ustat3= DS0EN| /*enable SPI slave device select zero */
SPIFLG3|SPIFLG2|SPIFLG0;/* Set SPIFLG1 low to */
dm(SPIFLG) = ustat3; /*select SPI slave on FLAG0 pin */
rts;

//Махание флагом I/O Update
FLAG_IO:
lcntr=12000, do (pc,FLAG_IO1) until LCE;
nop;nop;nop;nop;nop;nop;nop;nop;nop;FLAG_IO1:nop;
bit set flags FLG1;
lcntr=240, do (pc,FLAG_IO2) until LCE;
nop;nop;nop;nop;nop;nop;nop;nop;nop;FLAG_IO2:nop;
bit clr flags FLG1;
lcntr=12000, do (pc,FLAG_IO3) until LCE;
nop;nop;nop;nop;nop;nop;nop;nop;nop;FLAG_IO3:nop;
rts;

//Ожидание окончания передачи/приема
waitSPI:
lcntr=5, do (pc,waitSPI_c) until LCE;
call wait_for_SPIF;
waitSPI_c:call wait_for_SPIF;
rts;

//Инициализация процесса передачи
SPI_init_TX:
dm(IISPI)=ustat3;
dm(CSPI)=ustat4;
ustat3=1; dm(IMSPI)=ustat3;
ustat3 = DMISO|
WL8|
SPIMS|
SPIEN|
TIMOD2|
CPHASE|
CLKPL|
MSBF;
dm(SPICTL)=ustat3;
ustat3=SPIDEN;
dm(SPIDMAC)=ustat3;
call waitSPI;
call FLAG_IO;
rts;


//WAIT FOR SPI Transfert 1 Byte
wait_for_SPIF:
ustat1=dm(SPISTAT);
bit tst ustat1 SPIF;
if not tf jump (pc,wait_for_SPIF);
wait_for_SPIF.end:
rts;


//----------------------------------------
//READ Register
read_reg:

r0=DS0EN|SPIFLG3|SPIFLG2|SPIFLG0;
dm(SPIFLG)=r0;

r0=5000;
dm(SPIBAUD)=r0;

r0=SPIEN|SPIMS|SENDZ|CPHASE|CLKPL|TIMOD2|WL8|MSBF;
dm(SPICTL)=r0;

dm(CSPI)=ustat4;
dm(IISPI)=ustat3;
r0=1;
dm(IMSPI)=r0;

dm(TXSPI)=ustat2;


r0=INTEN|SPIDEN|SPIRCV;
dm(SPIDMAC)=r0;

//Wait for SPI DMA to complete using polling------

wspi:ustat1=dm(SPIDMAC);
bit tst ustat1 SPIDMAS; // Check SPI DMA Status bit
IF TF jump (pc,wspi); // SPIDMAS = 1 when DMA in progress

//Disable DMA
r15=0;
dm(SPIDMAC)=r15;

//Disable SPI
dm(SPICTL)=r15;
dm(SPIFLG)=r15;
dm(SPIBAUD)=r15;

read_reg.end: rts;
Genadi Zawidowski
Цитата
Ну с битиками то все в порядке.
На осциллографе все выглядит прекрасно, значит я думаю и для ДДС тоже.

А про сброс текущего IO я знаю, по этому и дергаю.


Вот у меня с битиками всё в полном порядке - я IORESET дёргаю один раз - перед инициализацией DDS. Вся последующая работа идёт без этого. А у Вас, раз требутся выводить SPI интерфейс у микросхемы из "заклинившего состояяния - не в порядке.

SPI порт у Вашего процессора использует выводы совместно с GPIO ли они выделенные? Если совместно - ну на час максимум возни по написанию (или адаптации любого чужого, например моего) SPI драйверв к Вашему процессору. И проверьте всё.

Да, вопрос из любопытства - почему не используете язык "С" для написания некритичных по быстродействию кусков программы?
WreWolf
не с битиками проблем нет.
все уже работает без лишних сбросов.

просто была небольшая ошибка в коде(длинна не соответствовала отправляемым данным).

Теперь следующая часть марлезонского балета
Line Sweep режим

пишем в CFR1 разрешение Line Sweep
потом
FTW0 FTW1 NLSCW PLSCW
и в зависимости от ножки PS0 DDS определят направление sweep
truebest
Добрый день всем...Старая тема но уж также такаяже у меня задача. Неполучается инициализировать AD9954..

После прочитки этого форума понял что надо донышко микры припоять, а также более менее как дергать RESET CS i/o sync и i/o update

Мне хотелось чтобы ниже описали правильный алгоритм инициализации, а то размазали по форуму rolleyes.gif )
У меня CLKMODESELECT приварен к GND), генератор внешний на 20мгц. Управление реализовываю по 3 проводному SPI.

Заранее спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.