Перейти к содержанию
    

repstosw

Участник
  • Постов

    2 650
  • Зарегистрирован

  • Победитель дней

    2

Весь контент repstosw


  1. Неужели это деление тоже через интринсики надо писать? Очень неудобно. В том же Keil + STM32 с их поддержкой VFPv4 плавучка инлайнится напрямую без применения интринсиков..
  2. Это мне понятно. Непонятно, как заставить инлайниться во floating-point такой кусок кода: float A=0.4F; float B=0.223424F; float C; void main(void) { C=A/B; } Это простое деление, и оно должно инлайниться в инструкции , а не через CALL вызываться.
  3. Делаю расчёты в формате floating point. К примеру - делю одно на другое. В асм-листинге вижу такое: $C$RL64: ; CALL OCCURS {__c6xabi_divf} {0} ; [] |147| ;** --------------------------------------------------------------------------* CALLP .S2 __c6xabi_divf,B3 ; [B_Sb674] |147| Как это безобразие называется??? Аппаратная поддержка floating point? C6745 вообще поддерживает операции с плавающей точкой или нет? Я ожидал инлайнинга иструкций на ассемблере, а не вызов функций с черт-пойми каким содержимым. Как итог: программа тормозит, и скорее всего там идёт целочисленная эмуляция плавучки. Спецы, подскажите, как заставить генериться код с ассемблерными инструкциями плавучки?
  4. Настроил шину SPI для взаимодействия с SD-картой. Частота ядра - 456 МГц Максимальный делитель для тактовой частоты SPI - 256, что даёт : SYS_CLK2/256 = (456/2) / (255+1) = 890 кГц А для инита SD карты надо 400 кГц. Можно ли без изменения настроек PLL изменить временно SYS_CLK2 так, чтобы тактовая частота SPI была 400 кГц или ниже? Есть ли возможность затактировать SPI модуль не от SYS_CLK2, а от XTAL=24 МГц ? SPI0 не предлагать, на нём висит Boot EEPROM.
  5. Про рестрикты почитал. Не годятся для моих целей, так как регион памяти используется в других функциях - например своппинг байтов в словах. Тоже указатель. Пользуясь случаем, как раз на счёт свопинга спрошу, можно ли в настройках EDMA указать чтобы байты менялись местами - старший с младшим ? Когда шина дисплея 8 бит, а передача идёт 16- 32- и 64- разрядными словами, то DMA передаёт вначале старший байт, а надо младший! (иначе цвет точек некорректный) В STM32H743 такая возможность есть. Есть ли в C6745 ? P.S. при первом наборе постов не сохраняется форматирование, приходится редактировать. Движок форума можно пофиксить?
  6. Немного повысил скорость путём изменения режима работы EMIFA, выбран Strobe Mode вместо Normal Mode, тем самым, Write Strobe Width стало возможным укоротить без нарушения работы LCD: EMIFA_CE2CFG= (1<<31)| //Select Strobe (0 - Normal Mode) (0<<30)| //Extend Wait (0 - disabled) (0<<26)| //Write setup width 0..15 (0 - EMA_CLK/1) (0<<20)| //Write strobe width 0..63 (0 - EMA_CLK/1) (0<<17)| //Write hold width 0..7 (0 - EMA_CLK/1) (0<<13)| //Read setup width 0..15 (0 - EMA_CLK/1) (0<< 7)| //Read strobe width 0..63 (0 - EMA_CLK/1) (0<< 4)| //Read hold width 0..7 (0 - EMA_CLK/1) (0<< 2)| //Minimum Turn-Around time (min. num. of EMA_CLK cycles between reads & writes - 1) 0 ; //Asynchronous Data Bus Width (0 - 8 bit) Теперь так: 91 кадров в секунду - CPU 98 кадров в секунду - DMA Режимы(выбран вариант справа): А вот тут 60 FPS через SPI и площадь экрана в 2 раза меньше: https://retropie.org.uk/forum/topic/14519/fast-refresh-rates-up-to-60fps-with-an-spi-display-ili9341
  7. Меня эта проблема достала и на UART2 - то грузится, то нет. Замерил логические уровни на бут-пинах: там где должна быть лог. "1" напряжение 1.8V вместо положеных 3-3.3V. Подтягивающие резисторы на 9,1 кОм оказались многоваты. Заменил на 1,1 кОм - теперь лог. уровень 3.1V что в норме. Глючить перестало! А я уже думал что UART'ы подпаливаются )))
  8. Выкинул RESTRICT - всё заработало, но число кадров в секунду то же - 70
  9. Попробовал адаптировать Ваш последний фрагмент кода под свои нужды - приёмник LCD экран, без инкремента адреса: void LCD_Picture2(float const * restrict src,int n) { float * restrict dst=(float*)0x60004000; //LCD Data Port do { _amem8((void*)dst)=_amem8((void*)src); src+=2; } while(n-=2); } Вызов: LCD_Picture2((float const*)Picture,sizeof(Picture)>>2); Не работает как надо: экран вместо картинки показывает несколько строк, залитыми серым цветом.
  10. Сделал замеры скорости отрисовки кадра на дисплей через DMA и с помощью CPU. Дисплей: 480x320 16 бит на точку. Интерфейс - параллельная шина 8 бит. Клок шины 91.2 МГц . Времянки для дисплея на EMIFA такие: void EMIFA_Init(void) { EMIFA_CE2CFG= (0<<31)| //Select Strobe (0 - Normal Mode) (0<<30)| //Extend Wait (0 - disabled) (0<<26)| //Write setup width 0..15 (0 - EMA_CLK/1) (1<<20)| //Write strobe width 0..63 (0 - EMA_CLK/1) (0<<17)| //Write hold width 0..7 (0 - EMA_CLK/1) (0<<13)| //Read setup width 0..15 (0 - EMA_CLK/1) (1<< 7)| //Read strobe width 0..63 (0 - EMA_CLK/1) (0<< 4)| //Read hold width 0..7 (0 - EMA_CLK/1) (0<< 2)| //Minimum Turn-Around time (min. num. of EMA_CLK cycles between reads & writes - 1) 0 ; //Asynchronous Data Bus Width (0 - 8 bit) } Тоесть всё на максимуме, кроме Write Strobe Width. Если его укоротить до 0, то изображение начинает "ехать по горизонтали". Поэтому тестировался стабильный вариант. Ядро на 456 МГц, кеширование L1P, L1D ,L2 включены. Регионы SDRAM прокешированы. Адрес картинки в SDRAM выровнен на границу 256 бит. Трансфер идёт с SDRAM в порт LCD_Data. Дополнительно выставил максимальный размер бурста: CFGCHIP0=(2<<2)|2; //PLL MMRs unlock & TC1 64 byte & TC0 64 byte (DBS) Если выставить бурст 32 байта - скорость не меняется. Но если поставить 16 - то скорость немного падает. DMA отрисовывает 74 кадра в секунду. Это выходит скорость : 320*480*2*74 = 21,68 МБайт/с. CPU отрисовывает немного меньше - 70 кадров/с. Код отрисовки - через 64-битный указатель: void LCD_Picture(u32 o,u32 n) //64 bit transfer { n>>=3; register u64 *P=(u64*)&Picture[o]; while(n--)LCD_D64=*P++; } Если отрисовывать через 32- 16- и особенно 8- битные указатели - скорость линейно падает. Оптимизация компилятора - максимальная "5" по скорости. Регион портов LCD не кеширован. Кстати, отключал кеширование в разных комбинациях - DMA работает с одинаковой скоростью и на кеширование ему начихать. Вопрос собственно вот в чём - возможно ли получить бОльшую скорость отрисовки без изменения аппаратной части ? Включить Write Buffer для порта LCD или изменить политику кеширования? Или это предел? Можно ли разогнать EMIFA до 101,3 МГц ? - с такой тактовой скорость отрисовки уже выходит чуть больше.
  11. Разобрался. В CMD-файле надо было добавить секцию: /* Interrupt */ .vecs > EMIFBSDRAM Или вообще выкинуть из intvecs.asm объявление секции и слинковать как обычно: ; .sect ".vecs" --- закомментировано .align 1024 _intcVectorTable: _vector0: VEC_ENTRY _c_int00 ;RESET _vector1: VEC_ENTRY _vec_dummy ;NMI _vector2: VEC_ENTRY _vec_dummy ;RSVD ... Рабочий код таймера по прерываниям: #include <c6x.h> #include "Type.h" #define TIMER_TIM12 (*(IO u32*)0x01C20010) /* Timer Counter Register 12 */ #define TIMER_TIM34 (*(IO u32*)0x01C20014) /* Timer Counter Register 34 */ #define TIMER_PRD12 (*(IO u32*)0x01C20018) /* Timer Period Register 12 */ #define TIMER_PRD34 (*(IO u32*)0x01C2001C) /* Timer Period Register 34 */ #define TIMER_TCR (*(IO u32*)0x01C20020) /* Timer Control Register */ #define TIMER_TGCR (*(IO u32*)0x01C20024) /* Timer Global Control Register */ #define TIMER_REL12 (*(IO u32*)0x01C20034) /* Timer Reload Register 12 */ #define TIMER_REL34 (*(IO u32*)0x01C20038) /* Timer Reload Register 34 */ #define TIMER_INTCTLSTAT (*(IO u32*)0x01C20044) /* Timer Interrupt Control and Status Register */ #define INTMUX1 (*(IO u32*)0x01800104) /* Interrupt mux register 1 */ extern void _intcVectorTable(void); extern volatile u32 Timer_Flag; void Timer_Delay(u32 d); void Timer_INT_Init(u32 d); void Timer_INT_Init(u32 d) { d*=24000; TIMER_TGCR=0x00000004; //reset TIMER12 TIMER_TIM12=0; //reset count TIMER_PRD12=d-1; //period TIMER_TCR=0x00000080; //continuous mode INTMUX1=4; //Event #4 T64P0_TINT12 => INTSEL4 ISTP=(u32)_intcVectorTable; //set new Vector Table for Interrupt ICR=0xFFF0; //clear all interrupts, bits 4 thru 15 IER=(1<<1)|(1<<4); //enable NMI, INT4 interrupts _enable_interrupts(); TIMER_TGCR=0x00000005; //activate TIMER12 } volatile u32 Timer_Flag=0; interrupt void Timer_INT(void) { Timer_Flag=1; } //Использование: void main(void) { L1P_Config(L1_SIZE_32K); //Enable L1P L1D L2 Cache L1D_Config(L1_SIZE_32K); L2_Config(L2_SIZE_128K); SDRAM_Cacheable(CACHEABLE_ON); //Enable SDRAM Cacheable KICK0R=0x83E70B13; //Unlock KICK1R=0x95A4F1E0; PINMUX10=0x00000080; //GP3[0] PINMUX13=0x11000000; //EMIFA PINMUX14=0x00111111; PINMUX17=0x00000100; PINMUX18=0x00101010; PSC0_lPSC_enable(0,0); //enable EDMA3 Channel Controller PSC0_lPSC_enable(0,1); //enable EDMA3 Transfer Controller 0 PSC0_lPSC_enable(0,3); //enable EMIFA PSC1_lPSC_enable(0,3); //enable GPIO EMIFA_Init(); LCD_Reset(); LCD_Init(); LCD_Clear(0x0000); Picture_Reverse(); //Swap bytes L2WB=0x01; //Flush L2 Cache (for DMA) EDMA3_Init((void*)Picture,sizeof(Picture)); //Init EDMA3 Timer_INT_Init(1000); //1s interval while(1) { register u16 x=rand()%(480-128); register u16 y=rand()%(320-128); EDMA_Wait(); LCD_Position(x,y,x+(128-1),y+(128-1)); EDMA3_Run(); while(!Timer_Flag); Timer_Flag=0; } } Вышепреведённый код рисует через DMA картинки с интервалом 1 с.
  12. Пытаюсь задействовать прерывание от таймера TIMER 1:2 у C6745, но не работает. Сам таймер настроил и он работает. Не получается вызвать обработчик его прерывания - не видит и всё! Номер эвента от Timer1:2 = 0x04 , настраиваю INTMUX1 = 4 - связываю int4 с таймером. Код ниже: extern void _Vectors(void); void Timer_INT(void) { TIMER_TGCR=0x00000004; //сброс TIMER12 TIMER_TIM12=0; //сброс счётчика TIMER_PRD12=24000000-1; //установка периода ~1 с. TIMER_TCR=0x00000080; //многократный счёт TIMER_TGCR=0x00000005; //активируем TIMER12 TIMER_INTCTLSTAT=0x00000003; //сброс флага прерывания и разрешаем прерывания INTMUX1=4; //эвент таймера 0x4 на int4 //загружаем новую таблицу векторов ISTP=(unsigned int)_Vectors; /* clear all interrupts, bits 4 thru 15 */ ICR = 0xFFF0; IER=(1<<4)|(1<<1); //enable int4 & non-maskable int /* enable interrupts, set GIE bit */ _enable_interrupts(); Delay(100); } Сам обработчик прерывания такой: interrupt void _Int4(void) { while(1); //пока безнадёжно повисаем } Таблица векторов и обработчики : ; Global symbols defined here and exported out of this file .global _Vectors .global _c_int00 .global _vector1 .global _vector2 .global _vector3 .global _vector4 .global _Int4 .global _vector5 .global _vector6 .global _vector7 .global _vector8 .global _vector9 .global _vector10 .global _vector11 .global _vector12 .global _vector13 .global _vector14 .global _vector15 ; This is a macro that instantiates one entry in the interrupt service table. VEC_ENTRY .macro addr STW B0,*--B15 MVKL addr,B0 MVKH addr,B0 B B0 LDW *B15++,B0 NOP 2 NOP NOP .endm ; This is a dummy interrupt service routine used to initialize the IST. _vec_dummy: B B3 NOP 5 ; This is the actual interrupt service table (IST). .sect ".vecs" .align 1024 _Vectors: _vector0: VEC_ENTRY _Int4 ;RESET _vector1: VEC_ENTRY _Int4 ;NMI _vector2: VEC_ENTRY _Int4 ;RSVD _vector3: VEC_ENTRY _Int4 ;RSVD _vector4: VEC_ENTRY _Int4 ;isr0 _vector5: VEC_ENTRY _Int4 ;isr1 _vector6: VEC_ENTRY _Int4 ;isr2 _vector7: VEC_ENTRY _Int4 ;isr3 _vector8: VEC_ENTRY _Int4 ;isr4 _vector9: VEC_ENTRY _Int4 ;isr5 _vector10: VEC_ENTRY _Int4 ;isr6 _vector11: VEC_ENTRY _Int4 ;isr7 _vector12: VEC_ENTRY _Int4 ;isr8 _vector13: VEC_ENTRY _Int4 ;isr9 _vector14: VEC_ENTRY _Int4 ;isr10 _vector15: VEC_ENTRY _Int4 ;isr11 Пока сделал везде _Int4 (позже исправлю). Линковщик ругается на секцию: И самое весёлое: смотрю в MAP-файл и вижу: Вот какого черта он игнорирует мою таблицу векторов и считает её что она в ROM с адреса 0x00700000 ? Прерывание естественно НЕ работает! Как можно заставить прерывание от таймера работать?
  13. UART0 то работает, то нет. Переключился на загрузку с UART2 - работает стабильно: более 0.5 МБ гружу в SDRAM. Настроил EMIFA и прикрутил дисплей 480x320. Всё работает. С картой памяти наверное поступлю проще - повышаю её на SPI1 (на SPI 0 висит Boot EEPROM). Видео дисплея в работе: https://www.youtube.com/watch?v=CzOtunjHsSg Исходник проекта для CCS v6 ниже: LCD_ILI9486.rar
  14. Вы здОрово всё расписали, интересно было почитать! Вылезла другая проблема - с какого-то момента загрузка по UART0 перестала работать и включается очень редко. Ошибка такого плана: Но загрузка с SPI EEPROM при этом идёт! В чем может быть дело?
  15. У PRUSS своё мультиплексирование пинов, не совпадающее с GPIO. Контроллируется с помощью PINMUX0..19. Только вот в C6745 там в битовых полях стоит Reserved, а в C6748 уже обозначены GP PRU. В техасовских утилитах (которые пины помогают назначить) - также. Я упустил из виду, что PRUSS - отдельные процессоры и DMA действительно становится не нужен. Нужна параллельность отрисовки в дисплей. Тоесть используя часть линий McASP можно полностью реализовать SPI ? Тогда зачем SPI сделали отдельно?
  16. McASP он максимум 192 кГц и не годится. Это для звука больше. Да мне главное 4-битный режим задействовать. Надо будет читать видео-потоки с разной плотностью сжатия и отрисовывать на экране видео. Даташит говорит что целых два - PRU0 и PRU1. Но в референс мануале нет мультиплексирования GPO/GPI через PINMUX, что странно. В C6548 eсть и в утилите PINMUX тоже есть. Кое-как нашёл асм для PRUSS. Было бы здорово его задействовать для реализации интерфейса для SD карты (4 бита данные, CLK, CMD, CS) или LCD (8 бит, CS, WR, A0). Только как тогда DMA будет с этим всем работать? И какой максимально возможный SPI CLK допустим? В даташите пишут: SPI_Module_Clock/3. Только чему равен SPI_Module_Clock - не написали. Вместо SD карты ещё рассматриваю микроновскую SPI MT29F4G01ADAGDWB - на 133 МГц она лучше будет чем SD-карта на 25 МГц даже с 4 битами
  17. ЗдОрово! Я даже и это успел проспать! :) Нет, не поможет. Потому что в C6745 нет вывода GPO,GPI на GPIO (в PINMUX нет таких функций.) Зато в C6748 уже есть. И всё-же есть ли способ работать с SD-картой в режиме 4 бита способом кроме как SDIO?
  18. С самого сайта TI? Или в закрома лазить прийдётся? Нашёл csl-phytec-master там есть модуль для работы с MMCSD. Новая проблема: с ужасом заметил что пины для работы с SD-картой перекрывают EMIFA, которая тоже нужна. Мультиплексировать(разделять во времени) SDIO и EMIFA - не вариант. EMIFA будет в 8 битном режиме, можно только на запись, обязательно работа через DMA. На EMIFA будет LCD с 8 битной шиной. Для SD-карты нужен 4-ибитный режим. PRUSS поможет? Через него можно работать с SDIO, но так чтобы пины были переназначены на другие? Или только ногодрыгом проблема решается? И TI опять зажала PRUSS тулзы для C6745
  19. Подскажите, есть ли пример работы с SDIO у TMS320C6745 ? Планирую SD карту подключить и наладить общение с ней (на первых порах - инит, чтение, запись сектора). Может даже в сторону OMAP-L137 копнуть и пусть даже ARM-ядро (C он и в Африке Си)
  20. Это уже C++ с редактированием большого количества исходников :) Да, верно, ошибки 1) и 2). При исправленных, 3) не помогло - такого пункта нет в настройках. Проблема описана здесь и её решение: https://e2e.ti.com/support/tools/ccs/f/81/t/501095 Если вкратце: использовал CCS v5 с компилятором C6000 7.4.8. Штатный апдейт доводил до v. 7.4.24. Всё то же - нет опции -C99 в Dialog. Поставил 6-ю версию CCS (она также лечится путём удаления mdex.dll как и 5-я версия), которая имеет App Center, из которого удалось скачать версию компилятора 8.3.3. Переделал проект под 6-ю CSS и поставил компилятор 8.3.3. В опциях появилось C99: Теперь код такого типа компилируется без ошибок: int Test_Shlak(int n) { int m[n]; for(int i=0;i<n;i++)m[i]=m[1]; return m[3]; } Что и нужно было. Попутно поборолся с удалением неиспользуемых функций в проекте. В компиляторе поставил: В линковщике: И только тогда создаётся выходной файл без лишнего. Проверяем так: C:\CCS_DIR\ccsv6\tools\compiler\ti-cgt-c6000_8.3.3\bin\ofd6x.exe --func_info Project.out > Project.csv И смотрим Экселем полученный Project.csv - который содержит все объекты которые в бинарнике. Только тонкая оптимизация, только -C99, только хардкор! ))) P.S. А Страуструповское творение(C++) так и не умеет массивы переменной длины :)
  21. Пытаюсь в CCSv5 скомпилять следующий код: int read_and_process(int n) { int vals[n]; for (int i = 0; i < n; ++i) vals[i] = vals[2*i] return vals[3*i]; } Ругается на то что размер массива переменный (VLA) и на объявление переменной внутри цыкла. Если от второго ещё можно избавиться, опустившись на уровень Страуструповщины (переключив на C++), то VLA не хочет варится. Даже при включенном Enable GCC Extentions. Есть ли способ заставить компилятор варить Variable Length Arrays ? (must have для C99) Эмуляторописатели любят GNU-шные плюшки и при портировании прийдётся править много кода (к слову Visual DSP 5.1 и Keil ARM могут это). Выход? Скачать CSS по-старше чем v.5 ?
  22. Всё, я разобрался в чём дело. Когда в AISgen включена инициализация PLL и SDRAM и код грузится в SDRAM, загрузчик сам включает кеширование L1P и L1D. Это и послужило тому, что вначале подумал, что кеш инструкций не даёт выигрыша. Обнаружил это сперва принудительно записав в L1PCFG=0x0. А затем считал его значение и узнал, что загрузчик включает L1 на полную: по 32 кБ. А вот L2 остаётся выключенным - загрузчик его не трогает. И ещё он не трогает MAR192, отвечающий за кеширование адресов SDRAM. Программу раздувал так: #define REPEAT8(x) \ x; \ x; \ x; \ x; \ x; \ x; \ x; \ x; \ #define REPEAT64(x) REPEAT8(REPEAT8(x)) #define REPEAT4096(x) REPEAT64(REPEAT64(x)) void NoOp(void) { __asm("NOP"); } void main(void) { //..... while(1) { //...... REPEAT4096(NoOp()) //....... //..... } Попробовал принудительно отключать кеши и сделал замеры: L1P L1D L2 время выполнения 0 0 0 - 30 секунд 1 0 0 - 14 cекунд 0 1 0 - 12 cекунд 1 1 0 - 2 секунды 0 0 1 - 3 cекунды 1 0 1 - 3 cекунды 0 1 1 - 2 секунды 1 1 1 - 2 cекунды Удлинил тест для L2=1 и сделал второй тест: L1P L1D L2 время выполнения 0 0 1 - 52 cекунды 1 0 1 - 48 cекунды 0 1 1 - 34 секунды 1 1 1 - 34 cекунды Теперь я вижу, что L1P работает и в некоторых случаях очень сильно ускоряет работу. Есть ли способ жестко задать программе точку входа в main() или _c_int00() ? Адрес постоянно плавает. А мне надо свой загрузчик с SD-карты писать чтобы переходить на загруженную программу.
  23. Всё, разобрался. Оказывается UART Boot Host каким-то чудом понимает, что если все секции слинкованы в SDRAM, то и грузит туда. Получилось запустить код в SDRAM. Попробовал включить L1P (кеш кода), так: Но вот прироста в скорости выполнения кода я не особо заметил. Диод мигает с одинаковой скоростью - что при выключенном L1P, что при включенном. А вот ОТключение L1D тормозит выполнение из SDRAM в 10 раз примерно. Что я делаю не так? (с L1P) Как можно проверить что кеш кода (L1P) включен и он приносит пользу? 32 миллиона нопов заставить делать в SDRAM ? с кешем и без
  24. И кстати, техасцы назвиздели по поводу создания AIS в виде H-файла для встраивания в другие C-программы. Создаётся бинарник в любом случае! Речь об этом:
  25. Как можно заставить Bootloader C6745 грузить код в SDRAM? Посмотрел CMD - но там объявлены только адреса по которым линковщик размещает секции. А вот как толкнуть AIS в SDRAM? Возможно ли это сделать AISgen-ом? Или курить описание AIS формата надо и ваять самому AIS? Или самому надо писать код копирования бинарника в сдрам?
×
×
  • Создать...