denebopetukius 0 11 марта, 2009 Опубликовано 11 марта, 2009 · Жалоба в общем навешал на BF532 кодек VS1053 кратко соединения: PF5 - XCS чипселект команд PF6 - XDCS чипселект данных PF7 - DREQ =0 когда занят MOSI,MISO,SCK и чипселекты подтянуты к питанию через резистор 4.7kOm грузится программа в L1 из eeprom - на PF2 программа ниже должна воспроизводить MIDI из массива MIDI[] использую 8 битную передачу без ДМА, просто через SPI_TDBR для начала пока хватит не работает!!! подскажите , верно ли с SPI работаю? #include <cdefBF532.h> #include <sysreg.h> #define u8 unsigned char #define u16 unsigned short int #define u32 unsigned long int #include "MIDI.c" void Delay(u32 D) { while(--D); } void LED(u8 led) { *pFIO_FLAG_S=(led&1); *pFIO_FLAG_C=((~led)&1); ssync(); } void Init_PLL(void) { *pSIC_IWR=0x00000001; *pPLL_CTL=0x5000; //VCO=CLKIN*40=400MHz, CLKIN=10MHz(Quartz) *pPLL_DIV=0x0003; //CCLK=VCO/1=400MHz, SCLK=VCO/3=133MHz ssync(); *pVR_CTL=0x00DB; //VLEV=1.2V, GAIN=20, FREQ=1MHz ssync(); idle(); } void Init_SDRAM(void) { while(!(*pEBIU_SDSTAT&1)); *pEBIU_SDSTAT|=0x10; *pEBIU_SDRRC=0x0408; *pEBIU_SDBCTL=0x0013; *pEBIU_SDGCTL=0x0091998D; *(u16*)0=0xBEEF; while(*pEBIU_SDSTAT&8); ssync(); } void Init_FIO(void) { *pFIO_DIR=0x0001; //PF0 на вывод, остальные на ввод *pFIO_INEN=0x0080; //PF7 входной буфер разрешён, для остальных запрещён ssync(); } void Init_SPI(void) { *pSPI_CTL&=(~(1<<14)); *pSPI_FLG=(1<<14)|(1<<13)|(1<<10)|(1<<6)|(1<<5)|(1<<2); *pSPI_BAUD=64; *pSPI_CTL=0x3C01; asm("ssync;"); *pSPI_CTL|=(1<<14); asm("ssync;"); } void XCS(u16 xcs) //XCS { *pSPI_FLG=(1<<14)|(xcs<<13)|(1<<10)|(1<<6)|(1<<5)|(1<<2); asm("ssync;"); } void XDCS(u16 xdcs) //XDCS { *pSPI_FLG=(xdcs<<14)|(1<<13)|(1<<10)|(1<<6)|(1<<5)|(1<<2); asm("ssync;"); } u8 DREQ(void) //DREQ { u8 dreq; dreq=(*pFIO_FLAG_D>>7)&1; asm("ssync;"); return dreq; } void OutVLSICommand(u8 Address,u16 Data) //Запись команды { XCS(0); *pSPI_TDBR=0x02; asm("ssync;"); while(!(*pSPI_STAT&1)); *pSPI_TDBR=Address; asm("ssync;"); while(!(*pSPI_STAT&1)); *pSPI_TDBR=(Data>>8); asm("ssync;"); while(!(*pSPI_STAT&1)); *pSPI_TDBR=(Data&0xFF); asm("ssync;"); while(!(*pSPI_STAT&1)); XCS(1); //while(!DREQ()); Delay(1000000); } void OutVLSIData(u8 Data) //Запись данных { XDCS(0); *pSPI_TDBR=Data; asm("ssync;"); while(!(*pSPI_STAT&1)); XDCS(1); //while(!DREQ()); Delay(100000); } void Init_Codec(void) { OutVLSICommand(0x00,0x0804|(1<<7)|(1<<4)); Delay(1000000); OutVLSICommand(0x00,0x0800|(1<<7)|(1<<4)); OutVLSICommand(0x02,0x0000); OutVLSICommand(0x03,0x8800); OutVLSICommand(0x05,44100|1); OutVLSICommand(0x0B,0x0000); } void main(void) { static u32 midi=0; Init_PLL(); Init_SDRAM(); Init_FIO(); Init_SPI(); LED(0); Init_Codec(); LED(1); while(1) { OutVLSIData(MIDI[midi]); midi++; if(midi>=819) midi=0; } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
boombox 0 11 марта, 2009 Опубликовано 11 марта, 2009 · Жалоба void XCS(u16 xcs) //XCS { *pSPI_FLG=(1<<14)|(xcs<<13)|(1<<10)|(1<<6)|(1<<5)|(1<<2); asm("ssync;"); } void XDCS(u16 xdcs) //XDCS { *pSPI_FLG=(xdcs<<14)|(1<<13)|(1<<10)|(1<<6)|(1<<5)|(1<<2); asm("ssync;"); } Не понятно что вы хотите сделать этими функциями. Если выбрать какой slave сейчас активен, то совершенно не верно. Устанавливая биты FLG вы выставляете состояние на портах(т.е. что записали то и будет на соответствующем пине). Также вы устанавливаете биты FLS2, FLS5, FLS6, т.е. на время передачи они у вас уходят в активное состояние одновременно. Если вы хотите именно выбирать текущее устройство, то надо сделать так void XCS(u16 xcs) //XCS { *pSPI_FLG=(1<<14)|(xcs<<13)|(1<<10); asm("ssync;"); } void XDCS(u16 xdcs) //XDCS { *pSPI_FLG=(xdcs<<14)|(1<<13)|(1<<10); asm("ssync;"); } либо void XCS(u16 xcs) //XCS { *pSPI_FLG=(1<<14)|(1<<13)|(1<<10)|(xcs<<5); asm("ssync;"); } void XDCS(u16 xdcs) //XDCS { *pSPI_FLG=(1<<14)|(1<<13)|(1<<10)|(xdcs<<6); asm("ssync;"); } Также установлен режим работы открытый коллектор бит WOM регистра SPI_CTL, а подтягивающий резистор есть на ноге MOSI. Вот тут лежит корявый но всё таки перевод HW BF53x на русский язык. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
denebopetukius 0 11 марта, 2009 Опубликовано 11 марта, 2009 · Жалоба boom, переправил функции XCS и XDCS - всеравно не работает :( и вообще мне логика флагов не понятна. там же написано что биты FLG нужны для assert(spi cs=0) и deassert(spi cs=1), а FLS для того чтоб активизировать нужный cs к примеру для PF5: SPI_FLG=(1<<5)|(cs<<13) где: 1<<5 - делаем активным PF5 для SPI CS#5 cs<<13 - =0/1 - assert/deassert SPI CS#5 по идее так. в ваших же примерах (в первых) биты FLG=0, значит cоответствующий CS не заэнаблится. исправьте, если я напутал... -------- по ходу разбирательств выяснил, что кодеку нужен SPI MODE 0 - значит CPOL=0, CPHA=0 а это значит невозможно вручную дергать чипселект для регистра контроля (там надо передать 4 байта с опущеным CS) получается, что чипселекты в моем случае нужно как программируемые флаги? И дергать их через FIO_FLAG_S,FIO_FLAG_D,FIO_FLAG_T так? тоесть надо организовать два типа передач по SPI: для команд(32 бита): 0x02,Address,Data[15..8],Data[7..0] XCS --------------|_______________________________|-------- и для данных: Data[7..0] XDCS-----------|________|------------- В кодеке по умолчанию биты передаются с MSB, заканчивая LSB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
denebopetukius 0 12 марта, 2009 Опубликовано 12 марта, 2009 · Жалоба кстати, могут ли быть проблемы, если я не читаю регистр приема SPI? и ещё : на miso/mosi/sck стоят подтягивающие резисторы на 4.7ком к питанию 3.3V на xcs,xdcs резисторы на 100ком тоже по питанию может ли в них дело быть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
denebopetukius 0 12 марта, 2009 Опубликовано 12 марта, 2009 · Жалоба кстати, в переводе перепутаны значения некоторых битов в SPI-регистрах. Берегитесь!!! :1111493779: :1111493779: :1111493779: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uriy 5 12 марта, 2009 Опубликовано 12 марта, 2009 · Жалоба Я дергаю CS только через флаги регистрами FIO_FLAG_S, FIO_FLAG_С. Не могу понять что за конструкция SPI_FLG=(1<<5)|(cs<<13) при чем тут cs и 13 чему равен cs? Лучше испльзуйте вот такие конструкции *pSPI_CTL = SPE | MSTR | CPOL | CPHA | EMISO | 1; *pFIO_DIR |= PF5|PF6|PF7; *pFIO_FLAG_S = PF5; //set PF5 *pFIO_FLAG_C = PF5; // clear PF5 эти маски продефайнены в cdefBF531.h и их названия совпадают с приведенными в HW Reference. Функция передачи/приема у меня выглядит вот так char AT45ByteTransfer(char ch) { char data; *pSPI_TDBR = ch; // transmit data while(!(*pSPI_STAT & RXS)); // wait for received data, if RXS = 0 test it again data = *pSPI_RDBR; // receive data return data; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
denebopetukius 0 12 марта, 2009 Опубликовано 12 марта, 2009 · Жалоба Не могу понять что за конструкция SPI_FLG=(1<<5)|(cs<<13) при чем тут cs и 13 чему равен cs? это значит бит 5=1, активируем SPISEL5 (битовое поле FLS) а cs<<13 - бит 13 - для assert/deassert SPICS5 (битовое поле FLG) Лучше испльзуйте вот такие конструкции *pSPI_CTL = SPE | MSTR | CPOL | CPHA | EMISO | 1; *pFIO_DIR |= PF5|PF6|PF7; *pFIO_FLAG_S = PF5; //set PF5 *pFIO_FLAG_C = PF5; // clear PF5 Поначалу нелегко использовать битовые поля. Мне пока проще в даташит залезть и посмотреть номера битов ;) Функция передачи/приема у меня выглядит вот так char AT45ByteTransfer(char ch) { char data; *pSPI_TDBR = ch; // transmit data while(!(*pSPI_STAT & RXS)); // wait for received data, if RXS = 0 test it again data = *pSPI_RDBR; // receive data return data; } спасибо! попробую - результат напишу. кстати, тот же кодек на арм9 работал со странностями - при передаче команд нужно было опрашивать регистр приёма SPI, а при передаче данных - можно было не опрашивать. вот рабочее на арм9: #define NPCS2 SPI_MR=0x00030011; //XCS #define NPCS3 SPI_MR=0x00070011; //XDCS #define VLSI_XCS(vlsi_xcs) \ { \ A_ODSR=(A_ODSR&0xFFFFFFDF)|(vlsi_xcs<<5); \ PIOA_ODSR=A_ODSR; \ } static void OutVLSICommand(u8 Address,u16 Data) //Запись команды { NPCS2 VLSI_XCS(0) SPI_TDR=Address|0x0200; while((SPI_SR&3)!=3); SPI_RDR; SPI_TDR=Data; while((SPI_SR&3)!=3); SPI_RDR; VLSI_XCS(1) while(!(PIOA_PDSR&0x00010000)); } static void OutVLSIData(u8 Data) //Запись данных, чипселект тут аппаратно { NPCS3 SPI_TDR=Data; while((SPI_SR&2)!=2); } //... SPI_CSR2=0x00001A82; //XCS 16bit SPI_CSR3=0x00000602; //XDCS 8bit OutVLSICommand(0x00,0x0804); Delay(1); OutVLSICommand(0x02,0x0000); OutVLSICommand(0x03,0x9000); OutVLSICommand(0x05,44100|1); OutVLSICommand(0x0B,0x0000); for(i=0;i<44;i++) { OutVLSIData(WAVHeader[i]); while(!DREQ()); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
boombox 0 12 марта, 2009 Опубликовано 12 марта, 2009 · Жалоба кстати, в переводе перепутаны значения некоторых битов в SPI-регистрах. Берегитесь!!! :1111493779: :1111493779: :1111493779: А я и написал, что корявый. Там много где ошибки, но для понимания достаточно. Конкретные регистры и их биты смотреть лучше в оригинально описании. ... Не могу понять что за конструкция SPI_FLG=(1<<5)|(cs<<13) при чем тут cs и 13 чему равен cs? Лучше испльзуйте вот такие конструкции *pSPI_CTL = SPE | MSTR | CPOL | CPHA | EMISO | 1; *pFIO_DIR |= PF5|PF6|PF7; *pFIO_FLAG_S = PF5; //set PF5 *pFIO_FLAG_C = PF5; // clear PF5 ... Согласен с uriy. SPI очень гибко позволяет настроить свои параметры. Первоначально я тоже довольно долго разбирался с SPI BlackFin'а, ну а теперь он у меня трудностей никаких не вызывает. Можете кстати попробовать использовать драйвер порта SPI вместе с System Sevice и Device Manager. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
denebopetukius 0 12 марта, 2009 Опубликовано 12 марта, 2009 (изменено) · Жалоба вот и я с вашей помощью пришел к выводу что чипселектами лучше рулить вручную через FIO. так как вариант с SPI_FLG не перекрывает всех вариантов CPOL,CPHA когда нужно осуществлять передачи более 16 бит при CS=0 кстати просветите плиз, на счёт: если у меня на mosi/miso/sck висят подтяжки на 4k7 на питание, будет ли лучше если я заактивирую режим Open Drain? если широковещательный режим не не требуется, можно не устанавливать EMISO ? Изменено 12 марта, 2009 пользователем denebopetukius Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fontp 0 12 марта, 2009 Опубликовано 12 марта, 2009 · Жалоба вот и я с вашей помощью пришел к выводу что чипселектами лучше рулить вручную через FIO. так как вариант с SPI_FLG не перекрывает всех вариантов CPOL,CPHA когда нужно осуществлять передачи более 16 бит при CS=0 кстати просветите плиз, на счёт: если у меня на mosi/miso/sck висят подтяжки на 4k7 на питание, будет ли лучше если я заактивирую режим Open Drain? если широковещательный режим не не требуется, можно не устанавливать EMISO ? В VDSP++ есть пример прямого программирования кодека SPI AD9866 Они используют для передачи функцию void Send(unsigned short data) { *pSPI_TDBR = data; asm("ssync;"); while (!(*pSPI_STAT & SPIF)); // wait until single-word transfer bit is set while (!(*pSPI_STAT & RXS)); // wait until receive buffer full bit is set stat = *pSPI_RDBR; } с ожиданием завершения и чтения и записи (в противном случае, если чтение не делать в регистре статуса будет выставлена ошибка чтения и если разрешено - даже произойдет прерывание по ошибке SPI) Нужно аккуратно выставить совместимый с кодеком режим работы(CPOL, CHPA, TIMOD_) - и всё должно заработать Аппаратный чипселект при CPHA=0 опускается автоматически при записи слова в регистр передачи, что для многих устройств неприемлемо - он должен быть общий для всего блока обмена. А при программном управлении (СPHA=1) нет никакой разницы - управлять чипселектами как SPI_FLG или как флагами. Без разницы чем махать SPI порт хоть и примитивный, но зато в отличие от SPORT он очень гибко программируется. Скорость и даже режимы работы возможно менять прямо на лету и всё работает (многие устройства требуют смены полярности прямо на лету при переходе от записи к чтению, sampling edge и shifting edge меняются местами). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
denebopetukius 0 12 марта, 2009 Опубликовано 12 марта, 2009 · Жалоба Обнаружил косяк с кодеком. по какой-то причине его нога DREQ после включения всей системы в низком лог. уровне- тоесть чип занят. выводится из этого состояния путём кратковременного закорачивания конденсатора цепочки сброса(100ком,0.1мкф) на землю. после этого DREQ=1 и в моменты передачи кратковременно уходит в 0. неужели еепром виноват? Обнаружил косяк с кодеком. по какой-то причине его нога DREQ после включения всей системы в низком лог. уровне- тоесть чип занят. выводится из этого состояния путём кратковременного закорачивания конденсатора цепочки сброса(100ком,0.1мкф) на землю. после этого DREQ=1 и в моменты передачи кратковременно уходит в 0. неужели еепром виноват? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
denebopetukius 0 13 марта, 2009 Опубликовано 13 марта, 2009 (изменено) · Жалоба как вы думаете, с чего начинать лечить эту проблему? может конденсатор в цепи сброса взять больше? или всё-таки дело в сильнотоковых подтяжках на 4k7? в схемах от vlsi ставят подтяжки на 100кОм(для кодека и сд-карты) сможет ли блекфин нормально грузиться с еепром при подтяжках на miso/sck 100ком?, 43ком? Вариант ресета с флага фина не предлагать - ибо сопли на плате не хочется :\ Изменено 13 марта, 2009 пользователем denebopetukius Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vik0 0 13 марта, 2009 Опубликовано 13 марта, 2009 · Жалоба может конденсатор в цепи сброса взять больше? Эээ. Простите, а вы и для фина reset формируете с помощью RC-цепочки? сможет ли блекфин нормально грузиться с еепром при подтяжках на miso/sck 100ком?, 43ком? Не вижу препятствий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
denebopetukius 0 13 марта, 2009 Опубликовано 13 марта, 2009 · Жалоба Для фина супервизор. пробовал резисторы менять и кондёр сброса-не помогло! нога кодека в нуле. иногда при подаче питания на плату-не уходит в нуль,но это редко. что делать? уже голову разбил! у меня возле разъёма питания кондёр на 220мкф или дело в фине который, возможно с spi 'неаккуратно' работает Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fontp 0 13 марта, 2009 Опубликовано 13 марта, 2009 · Жалоба Для фина супервизор. пробовал резисторы менять и кондёр сброса-не помогло! нога кодека в нуле. иногда при подаче питания на плату-не уходит в нуль,но это редко. что делать? уже голову разбил! у меня возле разъёма питания кондёр на 220мкф или дело в фине который, возможно с spi 'неаккуратно' работает А фин и его spi здесь причём, если кодек не становится в начальное состояние по ресету? В принципе, все SPI устройства (как и I2C) имеют такой недостаток, что после любой ошибки конечный автомат порта устройства становится боком и больше без ресета не работает У Вас он улетает незнамо куда уже при подаче питания Нужно 1) при отладке иметь отдельный ресет, как минимум завести его с ресета процессора или ещё с какой кнопки, хоть и проводом. Отлаживать серийную связь лучше всего с помощью логического анализатора (осцилографа). Особенно если связь двухсторонняя, а прибор достаточно сложный, чтобы охарактеризовать его состояние альтернативой работает-неработает (у меня у прибора больше 100 регистров и по поведению прибора очень трудно о чем-то судить, нужно видеть регистры) 2) после отладки ошибок уже не будет У меня SPI фина отлично работает (в смысле комманд) с аналоговским DDC по шлейфу 15 см с частотой до 15 мгц причем не только полингом, но и на прерываниях. На фин не надо гнать. Там SPI хоть и с прибабахами (недокументироваными фичами), но вполне работающий Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться