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

Allwinner T113-s3 уделал HiFi4 DSP. Смеяться или плакать?

HiFi4 DSP не сбрасывается вместе с CPU 0/1 при нажатии кнопки RESET.  Результат непредсказуем: после сброса DSP либо улетает в экспешн, либо  работает.  

Запись в регистр DSP_ALT_RESET_VEC_REG не приводит к положительному результату.

Вопрос:  как остановить DSP?

Код для запуска DSP в спойлере:

Spoiler
void sunxi_dsp_init(const void *img_addr,u32 img_size)
{
 sram_remap_set(1); //set system boot use local ram

 dsp_freq_default_set();

 //clock gating
 u32 reg_val=readl_dsp(CCU_BASE+CCMU_DSP_BGR_REG);
 reg_val|=(1<<BIT_DSP0_CFG_GATING);
 writel_dsp(reg_val,CCU_BASE+CCMU_DSP_BGR_REG);

 //reset
 reg_val=readl_dsp(CCU_BASE+CCMU_DSP_BGR_REG);
 reg_val|=(1<<BIT_DSP0_CFG_RST);
 reg_val|=(1<<BIT_DSP0_DBG_RST);
 writel_dsp(reg_val,CCU_BASE+CCMU_DSP_BGR_REG);

 writel_dsp(DSP0_START_ADDRESS,DSP0_CFG_BASE+DSP_ALT_RESET_VEC_REG);
 reg_val=readl_dsp(DSP0_CFG_BASE+DSP_CTRL_REG0);
 reg_val|=(1<<BIT_START_VEC_SEL);
 writel_dsp(reg_val,DSP0_CFG_BASE+DSP_CTRL_REG0);

 sunxi_dsp_set_runstall(1); //set runstall

 //set dsp clken
 reg_val=readl_dsp(DSP0_CFG_BASE+DSP_CTRL_REG0);
 reg_val|=(1<<BIT_DSP_CLKEN);
 writel_dsp(reg_val,DSP0_CFG_BASE+DSP_CTRL_REG0);

 //de-assert dsp0
 reg_val=readl_dsp(CCU_BASE+CCMU_DSP_BGR_REG);
 reg_val|=(1<<BIT_DSP0_RST);
 writel_dsp(reg_val,CCU_BASE+CCMU_DSP_BGR_REG);

 load_image(img_addr,img_size); //load image to ram

 sram_remap_set(0); //set dsp use local ram

 sunxi_dsp_set_runstall(0); //clear runstall
}

 

 

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, repstosw said:

HiFi4 DSP не сбрасывается вместе с CPU 0/1 при нажатии кнопки RESET.  Результат непредсказуем: после сброса DSP либо улетает в экспешн, либо  работает.  

Вопрос решён.

Проблема была в повторной инициализации регионов кеширования, которая приводила к эксепшену.  В функции _cache_config :

https://github.com/YuzukiHD/FreeRTOS-HIFI4-DSP/blob/master/arch/board-init.c#L11

Для повторных вызовов (при нажатии кнопки RESET на плате с T113-s3) нужно сделать инвалидацию кешей:

#include "hal.h"

static void _cache_config(void)
{
  //для корректной работы DSP после сброса T113-s3
  xthal_icache_all_invalidate();
  xthal_dcache_all_invalidate();

  /* 0x0~0x20000000-1 is non-cacheable */
  xthal_set_region_attribute((void *)0x00000000, 0x20000000, XCHAL_CA_WRITEBACK,0);
  xthal_set_region_attribute((void *)0x00000000, 0x20000000, XCHAL_CA_BYPASS,   0);
//...

 

По-хорошему, после сброса надо запрещать кеширование и отключать предвыборку(prefetch) и сбрасывать конвеер. Чтобы потом снова разрешать всё.

Вариант-минимум выше работает.

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

45 минут назад, repstosw сказал:

при нажатии кнопки RESET на плате с T113-s3) нужно сделать инвалидацию кешей:

Да уж, странно, после повторного перезапуска оно понятно, как перевод управления из бутлоадера в осн. программу, но после аппаратного сброса...

Такое впечатление, что аппаратный сброс != сброс ДСП)))

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

53 minutes ago, mantech said:

Да уж, странно, после повторного перезапуска оно понятно, как перевод управления из бутлоадера в осн. программу, но после аппаратного сброса...

Такое впечатление, что аппаратный сброс != сброс ДСП)))

 

Так в асмовском стартап-коде для Cortex A7   также запрещаются кеши и проводятся инвалидации.

Entry:
         MRC     p15, 0, r0, c1, c0, 0         @ Read CP15 System Control register
         BIC     r0, r0, #(0x1 << 12)          @ Clear I bit 12 to disable I Cache
         BIC     r0, r0, #(0x1 <<  2)          @ Clear C bit  2 to disable D Cache
         BIC     r0, r0, #0x1                  @ Clear M bit  0 to disable MMU
         BIC     r0, r0, #(0x1 << 11)          @ Clear Z bit 11 to disable branch prediction
         MCR     p15, 0, r0, c1, c0, 0         @ Write value back to CP15 System Control register

         MOV     r0,#0
         MCR     p15, 0, r0, c8, c7, 0         @ I-TLB and D-TLB invalidation
         MCR     p15, 0, r0, c7, c5, 6         @ BPIALL - Invalidate entire branch predictor array

 

Вопрос в том, как это правильно сделать для DSP и желательно - с особой педантичностью, чтобы в любых случаях положительный результат был 100%.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как-то понадобилось мне сделать задержки через DSP-таймер.  В board_init.c есть такая функция: uint64_t xbsp_get_ccount(void). Задержку решил сделать так:

u64 t=xbsp_get_ccount();
while(xbsp_get_ccount()-t<60000); //100 us wait (600 MHz timer)

Не работает  xbsp_get_ccount(): https://github.com/YuzukiHD/FreeRTOS-HIFI4-DSP/blob/master/arch/board-init.c#L130

Если использовать 32-битный таймер без учёта переполнения, то он переполнится через 7,15 секунд, что неприемлемо.

64 бита уже дадут переполнение через 355 839 cуток.

Сделал так:

Spoiler
u32 Timer_Get(void)
{
 u32 ccount;
 __asm__ __volatile__ ("rsr.ccount %0" : "=r"(ccount));
 return ccount;
}

u64 Timer_Get64(void) //get 64 bit timer value
{
 static u32 oldlo=0; //old LSW timer value
 static u32 oldhi=0; //MSW of 64 bit timer

 u32 curlo;
 u32 curhi;
 u64 tmr64;

 curlo=Timer_Get(); //get the 32 bit counter/timer value
 curhi=oldhi;       //get the upper 32 bits of the 64 bit counter/timer

 if(curlo<oldlo)curhi++; //detect rollover

 oldhi=curhi;
 oldlo=curlo;

 tmr64=curhi;
 tmr64<<=32;
 tmr64|=curlo;

 return tmr64;
}

 

 

 

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 часов назад, repstosw сказал:

Как-то понадобилось мне сделать задержки через DSP-таймер.  В board_init.c есть такая функция: uint64_t xbsp_get_ccount(void). Задержку решил сделать так:

И Ваш, и чей-то приведенный пример будут работать криво, если функцию будут юзать из нескольких потоков или из потока и ISR, т.к. она не потокобезопасна🙂

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 hours ago, Arlleex said:

И Ваш, и чей-то приведенный пример будут работать криво, если функцию будут юзать из нескольких потоков или из потока и ISR, т.к. она не потокобезопасна🙂

Согласен. Есть ли какие-нибудь идеи как сделать функцию реентабельной? :wink:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 часов назад, repstosw сказал:

Согласен. Есть ли какие-нибудь идеи как сделать функцию реентабельной? :wink:

Критическая секция? Или: сделать таймер все-таки 32-битным, а статическое 32-битное раширение (для 64-битного результата) создавать "по месту" в коде.

Хрень редьки не слаще - Вам все равно придется вызывать свою xbsp_get_ccount() чаще, чем раз в 7,15 секунд, иначе даже в однопоточном варианте эта функция сломается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Arlleex сказал:

чаще, чем раз в 7,15 секунд,

Честно не представляю, для чего нужна задержка больше 7 сек???  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 10/25/2023 at 9:54 AM, mantech said:

Честно не представляю, для чего нужна задержка больше 7 сек?

я ещё меньше понимаю зачем такие задержки в ISR 🙂 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

27 минут назад, sasamy сказал:

я ещё меньше понимаю зачем такие задержки в ISR 🙂 

Я акцентирую внимание не на задержках в ISR, разумеется, а на возможность вызова функции получения timestamp в ISR.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 10/24/2023 at 3:11 AM, repstosw said:

она не работает из-за макроса XTHAL_GET_CCOUNT()

https://github.com/YuzukiHD/FreeRTOS-HIFI4-DSP/blob/164696d952116d20100daefd7a475d2ede828eb0/arch/board-init.c#L133

https://github.com/YuzukiHD/FreeRTOS-HIFI4-DSP/blob/164696d952116d20100daefd7a475d2ede828eb0/include/xtensa/core-macros.h#L346

если вместо него использовать xthal_get_ccount() должно быть нормально

хотя тут помоему ошибка

https://github.com/YuzukiHD/FreeRTOS-HIFI4-DSP/blob/164696d952116d20100daefd7a475d2ede828eb0/arch/board-init.c#L137

в общем нафик она нужна вообще 🙂

Изменено пользователем sasamy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Arlleex сказал:

Я акцентирую внимание не на задержках в ISR, разумеется, а на возможность вызова функции получения timestamp в ISR.

При желании - можно сделать на двух сцепленных аппаратно 32-битных таймерах. С простой процедурой чтения 64-битного значения, состоящей из 3 чтений счётчиков и одного сравнения с возвратом (циклическим).

PS: Хотя конечно тратить аппаратные таймеры на такую ерунду это как то... по-ламерски что-ли....  :smile:

Но в то же время: в некоторых МК аппаратных таймеров - "хоть попой ешь".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, sasamy said:

если вместо него использовать xthal_get_ccount() должно быть нормально

хотя тут помоему ошибка

https://github.com/YuzukiHD/FreeRTOS-HIFI4-DSP/blob/164696d952116d20100daefd7a475d2ede828eb0/arch/board-init.c#L137

в общем нафик она нужна вообще 🙂

1.  пробовал - эффекта положительного не дало

2. да. Ошибка в алгоритме

3. того же мнения 🙂

 

22 minutes ago, jcxz said:

Но в то же время: в некоторых МК аппаратных таймеров - "хоть попой ешь".

Там есть прерывание по достижению конкретного значения. Можно инкрементировать переменную в обработчике.  Но это более ресурсоёмко, по сравнению с чтением одного волатильного регистра.  Делителя к сожалению нет, так как это счётчик тактов ядра.  

Использую AVS периферийный таймеры от T113-s3 с делителями.  Они тоже 32-битные, но с правильно установленными делителями там переполнение наступит не скоро.

 

P.S.  Кстати, вопрос всем.   Кто-нибудь  пробовал вместо прерываний IRQ  задействовать FIQ ?   Так называемые быстрые прерывания.   Можно ли GIC400 запапить на FIQ?

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...