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

TU-104

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

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

  • Посещение

Сообщения, опубликованные TU-104


  1. А кто-нибудь использует в sam-e70 sdram контроллер и внешнюю память?

    В новых даташитах вырезано всё, что связано с ней. Кто-то проверял новые чипы? Это только в документах вырезали, чтоб ошибки не исправлять или прям всё, кристалл переразвели.

    image.thumb.png.cf1f1ac6221315c7c20603f4c847f2c4.png

  2. On 9/15/2023 at 9:14 PM, _4afc_ said:

    Интересно как меняется эффект если по очереди (один из пунктов):

    1. VDPLL добавить на С30 10-1000пФ NP0 (замкнуть ВЧ)

    2. VDDOUT добавить на С36 30uF (замкнуть НЧ до BLM)

    3. Закоротить BLM т.к. броски потребления  тока переходят в пульсации напряжения из-за его сопротивления

    1. Ничего вроде не поменялось

    image.png.17c149ffbac90fc94923eb8a1f0fefba.png

    3. Что-то поменялось, немного "собраннее" что ли стал разброс, но все равно большой

    image.png.762aadcf4c5bc34861bcc396c905d5ca.png

    2(не совсем п.2). Пока L3 был закорочен, просто приложил большой электролит на VDDOUT

    image.png.d048fa507e14c56868f41004b44263bc.png

  3. 3 hours ago, _4afc_ said:

    Какой тип L3 у вас и L201 на демо плате? На демо плате эффект есть?

    Из спецификации демо: BLM18PG471SN1D  6  L200,L201....    Murata    IND FER BEAD 470 OHM@100MHZ 1A 25% 0603

    У нас то же самое (хотя на 100% не уверен, куплено по документам BLM18PG471SN1D ). Демо-платы пока нет под рукой

    Да, на демо-плате такой же эффект

    image.png.431f79e18d6c675fb036582aad06ace1.png

    image.png.e62c4f7233aa1eaba8e48afed2e601c5.png

     

     

  4. 14 hours ago, Vasily_ said:

    Значит надо LDO правильный применить ну и X5R ну тоже такое себе, да и тантал c низким ESR не мешает повесить.

    Так LDO там встроенный (выход VDDOUT 1.2В), вот из даташита кусок

    image.thumb.png.ab619a1d644b7f808d32ddde87fb1a76.png

    а что не так с X5R на столе в комнатных условиях?

  5. 20 hours ago, Михась said:

    Нестабильность питания PLL? Может на конденсаторы посмотреть на аналоговом домене?

    Спасибо за наводку!

    Выкладываю результаты.

    Начальное состояние такое, измерял так ():

    image.jpeg.af55e424ea6f7d1e033d6fdd44de8516.jpeg

    Дальше подписано, 10 мкФ на VDDOUT

    image.thumb.png.d8bfa9e9e1b12f652614ce0e7336e1ff.png

    Лучший результат 30мкФ на VDDPLL

    image.thumb.png.c047815c59c8139cbef7ad87d50f780e.png

     

    Но по даташиту и на демо-доске там только 0.1 мкФ. Вдруг оно(ядро или LDO) потом будет нестабильно запускаться?

     

  6. 3 hours ago, Михась said:

    Нестабильность питания PLL? Может на конденсаторы посмотреть на аналоговом домене?

    вроде как все выводы увешаны ими, примерно одинаково PLL|USBPLL.  Даже usbpll без дросселя напрямую к +3.3В

    Добавил 10uF X5R на VDDPLL, и правда стало лучше

     

    image.thumb.png.4d1e58b31b2fee28124b2ad10719646f.png

  7. On 9/7/2023 at 1:05 PM, TU-104 said:

    SAME70. Кто-нибудь использовал в нём выход частоты из встроенной PLLA? 

    вообще всё - и прерывания и какой-либо код (не относящийся к работе с pll и с  периферией портов). При этом с UPLL такого нет

    Перепроверил всё ещё несколько раз - запустил демо-пример на двух платах.

    При выводе PLLA на пин - есть джиттер. При выводе UPLL - нету.

    Если ядро отладчиком остановить - то частота на ножке стабильна.

    Если ядро работает (в примере опрашивает регистр уарта, ждёт нажатия кнопки), то появляется такой вот "джиттер":

    image.thumb.png.d03fc63721a5d25901d1f7a7483eee02.png

  8. Ну и ещё добавлю новость: в новой еррате написано не использовать SDRAM. И на страничке рекламы и в новом даташите сдрам контроллера нет...

    image.thumb.png.133736020d33eaaa7f027c50574b75e8.png

    зато цветные колонтитулы добавили

    image.thumb.png.7e1d78c9478e2ec9394e99c82b51e6fe.png

  9. SAME70. Кто-нибудь использовал в нём выход частоты из встроенной PLLA? 

    Почему-то у меня она получилась дёрганная и на это дёрганье как-то влияет FreeRTOS.

    Вот такая картинка в даташите, можно любой клок выдать на три определённых ноги PCK_0..2

    image.thumb.png.65fd41afcd06af18719878dc08081598.png

    Включаю выход PCK_1, источник выбираю PLL, делитель на 12 (300/12=25МГц)

      #define PIN_PCK_1  {PIO_PA17B_PCK1, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
    
      PMC->PMC_SCDR = PMC_SCDR_PCK1;  // disable PCK 1
      while ((PMC->PMC_SCSR)& PMC_SCSR_PCK1);
      PMC->PMC_PCK[1] = PMC_PCK_PRES(11)| PMC_PCK_CSS_PLLA_CLK; //PMC_PCK_CSS_MCK; //;
      PMC->PMC_SCER = PMC_SCER_PCK1;
      while (!((PMC->PMC_SR) & PMC_SR_PCKRDY1));

     

    В пустом проекте всё красиво выводится, осциллограф в режиме запоминания показывает сдвиги меньше 1 нс

    НО как только запускаю FreeRTOS, частота начинает "дёргаться" - фронты двигаются на  +-5нс.

     

    Пробовал убрать все задачи - дёрганья есть, т.е. не в моих задачах дело.

    Пробовал в xPortSysTickHandler() поставить return - дёрганья пропадают.

    Появляются где-то в этом 1мсек обработчике  xPortSysTickHandler

       portDISABLE_INTERRUPTS();
        {
            /* Increment the RTOS tick. */
            if( xTaskIncrementTick() != pdFALSE )
            {
                /* A context switch is required.  Context switching is performed in
                 * the PendSV interrupt.  Pend the PendSV interrupt. */
                portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
            }
        }
       portENABLE_INTERRUPTS();
    }

     

    PS. Если выводить 24МГц на ту же ногу, но от источника UPLL, то никаких дёрганий нет

    PPS убирал из этого обработчика по очереди всё что можно. Выяснил пока, что инструкции __DSB() ISB() в прерывании от СисТика "портят" частоту на ноге PCKxx. Как такое вообще может быть?

    ppps. Выглядит, что на дёрганье частоты PLLA влияет вообще всё - и прерывания и какой-либо код (не относящийся к работе с pll и с  периферией портов). При этом с UPLL такого нет

     

     

     

  10. PPS: Вот Си вариант, работает под cortex-M7 с float, под целые так и не переделал, не понадобилось

    // буфер 240(30мс) s16 элементов накапливаю для обработки Герцелем//  3 цикла ДМА
    #define RX_DSP_LEN        240
    // #define a1 :=2*cos(2*Pi*Ff/Fd);
    #define a1_1200         (float)1.1755705046   //1.1755705045849462583374119092781
    #define a1_1600         (float)0.6180339888   //0.61803398874989484820458683436564
    
    
    // вызывается из codec_work() при накоплении буфера 30мс
    void DSP_gertzel(){
      
      s32 Summ = 0;
      s16 DCoff;
      u16 Amp;
      u32 i;
      
      float D0, D1, D2;
      float Amp12, Amp16;
      
      for (i=0;i<RX_DSP_LEN; i++){
        Summ += Buf_DSP[i];
      }
      DCoff = Summ/RX_DSP_LEN; // среднее арифм. DC offset
      
      Summ = 0;
      for (i=0;i<RX_DSP_LEN; i++){
        Summ += abs(Buf_DSP[i]-DCoff);
      }  
      Amp = (u16) round(((float)(Summ/RX_DSP_LEN)*PI/2));
    
      
       // если общий уровень не в воротах, то просто считаю детекцию нулевой и выполняю что нужно
      if ((Amp<MIN_LVL_ADASE)||(Amp>MAX_LVL_ADASE)){
        Amp12 = 0;
        Amp16 = 0;
        //d0printD(DEBUG_DSP, "\rDC=%d Amp=%d       no proc xxx             xxx ", DCoff, Amp);
      }
      else {
        // *******   сам алгоритм   *********
        // **********   1200   **************
        D1 = 0;
        D2 = 0;
        for (i=0; i<RX_DSP_LEN; i++){
          D0 = Buf_DSP[i]+ a1_1200*D1-D2;
          D2 = D1;
          D1 = D0;
        }
        Amp12 = sqrt(D1*D1+D2*D2 - a1_1200*D1*D2);
        Amp12 = Amp12/(RX_DSP_LEN/2);
        // **********   1600   ************
        D1 = 0;
        D2 = 0;
        for (i=0; i<RX_DSP_LEN; i++){
          D0 = Buf_DSP[i]+ a1_1600*D1-D2;
          D2 = D1;
          D1 = D0;
        }
        Amp16 = sqrt(D1*D1+D2*D2 - a1_1600*D1*D2);
        Amp16 = Amp16/(RX_DSP_LEN/2);
        // *******************************     
        
      } // Amp в норме
      
    
      // дальше определяем, какая частота присутствует. общий уровень отфильтрован выше
      if((Amp12 > MIN_LVL_ADASE)&&(Amp16> MIN_LVL_ADASE)){
       (...)
        считаем на интервале 30мс обнаруженным
      }
        
        
    }

     

  11. 7 hours ago, smk said:

    С изменениями разобрался. Всеравно не то. Пример бы рабочий.

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

    Делал себе эмулятор когда-то, чтоб разобраться.

    В программе можно сгенерировать 2 частоты F0+F1, чтоб посмотреть, как алгоритм отрабатывает на таких сигналах.

    Для начала можно задать одну F0, тогда амплитуду F1 задать =0

    Кнопка "Генерировать" - создаёт массив точек сгенерированного сигнала (число точек задаётся, Fs у меня всегда 8000 Гц) и выводит график.

    Дальше задаётся длина интервала оценки, на которые будет разбит сигнал и на каждом будет запущен алгоритм Герцеля, задаётся искомая частота и нажимается кнопка "Gortc proc". Синим цветом у меня вычисляется амплитуда всего сигнала за вычетом DC на интервале, и при одной частоте видно как к концу интервала амплитуда равна числу, которое выдает алгоритм герцеля (он выдаёт амплитуду на искомой частоте)

    Для сравнения еще сделано в целых числах, результат почти такой же точности(оранжевый график, он перекрывает бирюзовый)

    image.thumb.png.e146fc4fdebe43c641231361f80b0b26.png

     

    В архиве ехе-шник и .pas, часть нужного кода вставляю сюда:

    Procedure Gortc_Proc();
      //const a1 = 0.618;      // 2•cos(2PI•k)   k=f/Fd
      var D0, D1, D2 : real;
       iD0, iD1, iD2 : Int64; //integer;
          i : integer;
          P : real;
          Ff: integer;
          a1: real;
          iA1: Int64;
          NumSamples : integer;  // число выборок для интервал оценки. с новым интервалом фильтр обнуляется
    
    begin
    
      Fmain.Chart1.Series[3].Clear;
      Fmain.Chart1.Series[4].Clear;
      Fmain.Chart1.Series[5].Clear;
    
      Ff := Fmain.SpinEditFfind.Value;
      a1 :=2*cos(2*Pi*Ff/Fd);
    
      NumSamples := Fmain.SpinEditInterval.Value;
    
    //  D0 := 0;
      D1 := 0;
      D2 := 0;
      for i:= 0 to NumPoints-1 do begin
        D0 := X_IN[i]+ a1*D1-D2;
        D2 := D1;
        D1 := D0;
    
        P := sqrt(D1*D1+D2*D2 - a1*D1*D2);
        P := P/(NumSamples/2);
    
    //    pp := round(P) div 10;
        Fmain.Chart1.Series[4].AddXY(i, P);
          // сброс коэффициентов через N мс
        if (i mod NumSamples) =0   // 80*125us = 10ms
        then begin
          mLog(IntToStr(i)+'. AMP(f) на интервале '+IntToStr(round(P)));
          D1:=0;
          D2:=0;
        end;
    
      end;
    
        
    
       //вариант с целыми
      iA1 := round(a1*256);
      iD1 := 0;
      iD2 := 0;
      for i:= 0 to NumPoints-1 do begin
        iD0 := X_IN[i]+ ((iA1*iD1) div 256) -iD2;
        iD2 := iD1;
        iD1 := iD0;
    
        P := sqrt(abs(iD1*iD1+iD2*iD2- iA1*iD1*iD2/256));
        P := P/(NumSamples/2);
    
    //    pp := round(P) div 10;
        Fmain.Chart1.Series[5].AddXY(i, P);
          // сброс коэффициентов через N мс с новым интервалом
        if (i mod NumSamples) =0   // 80*125us = 10ms
        then begin
          mLog(IntToStr(i)+'. AMP(f) на интервале '+IntToStr(round(P)));
          iD1:=0;
          iD2:=0;
        end;
    
      end;
    
    
    
    end;

     

    PS. Наверно можно и в экселе сделать всё то же самое, скопировав формулы в сотню строк

     

    dsp_detect_d10.zip

  12. 27 minutes ago, smk said:

    Как это использовать?
     

    void SampleFilter_init(SampleFilter* f) {
      int i;
      for(i = 0; i < SAMPLEFILTER_TAP_NUM; ++i)
        f->history[i] = 0;
      f->last_index = 0;
    }
    
    void SampleFilter_put(SampleFilter* f, double input) {
      f->history[f->last_index++] = input;
      if(f->last_index == SAMPLEFILTER_TAP_NUM)
        f->last_index = 0;
    }
    
    double SampleFilter_get(SampleFilter* f) {
      double acc = 0;
      int index = f->last_index, i;
      for(i = 0; i < SAMPLEFILTER_TAP_NUM; ++i) {
        index = index != 0 ? index-1 : SAMPLEFILTER_TAP_NUM-1;
        acc += f->history[index] * filter_taps[i];
      };
      return acc;
    }

     

    Так всё же понятно:

    - Завести переменную - структуру SampleFiler, передать её в начале в инит (там просто нулями заполняется массив сэмплов).

    - Очередной сэмпл положить в массив функцией ..._put()

    - Забрать c выхода фильтра тоже очередное значение .._get()

     

    Но вам тут выше посоветовали для вашей задачи (обнаружение частоты) - быстрее Гертцелем

     

  13. Тоже возник такой вопрос, в даташите на него ответа нет, в гугле только вот это для  GD32F103CBT6 :

    Quote

    SRAM sizes are 32KiB in each largest block (128 KiB total) - stores code, which means first 128KiB could be accessed faster than typical flash. GD32 chips with 20Kb of SRAM or less have no more than 128KiB of flash, so all flash content is served from SRAM. This might also mean that startup time is slower than one would expect. With this SRAM mirroring it is not surprising that GD32 is beating STM32 in performance even on the same frequency and loosing in idle & sleep power consumption. Consumption at full load is lower than STM32 due to better (smaller) manufacturing technology.

    Т.е. какое-то зеркалирование части флеш в SRAM

    И ещё вот тут немного, говорят, что область кода с нулевой задержкой доступа:

    Quote

    And ST Different ,GD Of Flash There is the concept of partition , front 256K,CPU Execute instruction zero wait , call code District , Outside this scope is called dataZ District . There is no difference between the two in erasure operation , But there is a big difference in read operation time ,code The area code takes zero and waits ,data There is a large delay in executing code in the area , Code execution is more efficient than code The area is one order of magnitude slower , therefore data Areas usually do not recommend running code that requires high real-time performance , To solve this problem , The method of decentralized loading can be used , For example, put the initialization code , Picture code, etc data District .

    И ещё документ "GD32 and STM32 Compatibility", тоже говорят про нулевые задержки в код-области и огромные в дата-области

    Quote

    GD32 flash consist of two areas: code area and data area. There is no difference in erasing and programing, but make difference in reading in two areas. Code area is zero wait for fetching instruction. Data area have a large delay in executing code. Thus, it is not recommend to run real time code solution Scatterloading, locate the real time code in flash code area;

     

  14.   // если хочется, то можно передать указатель на свои аргументы
      XDMAD_SetCallback(&Dma, dmaSSC_RXch, (XdmadTransferCallback)SSC_Rx_Cb, NULL);
      XDMAD_SetCallback(&Dma, dmaSSC_TXch, (XdmadTransferCallback)SSC_Tx_Cb, NULL);

    __________________________________________

      // без доп аргументов *arg
    static void SSC_Tx_Cb(uint32_t channel)
    {
      //dPIN_OFF(PIN_TEST1);  
      //d0print("SSCDMAcb tx ch:%u dmach:%u\n\r", channel, dmaSSC_TXch);  // потом убрать это
      //NVIC_DisableIRQ(XDMAC_IRQn);
      
      XdmacChid * CHID = &(Dma.pXdmacs->XDMAC_CHID[dmaSSC_TXch]);
      u32 i;
      
    
      if ( (CHID->XDMAC_CNDA) == (u32)&LLIview0_TX[0] )
      { 
        pF_bufTX_rdy = &F_bufTX[0];
        // в этот момент передаётся вторая часть буфера - по осциллу, и по выводу здесь       
      }
      else //if ((CHID->XDMAC_CNDA) == (u32)&LLIview0_TX[1])         
      {
        pF_bufTX_rdy = &F_bufTX[FBTX_LEN/2];    
      }
      

    Я сделал так, всё работает. (ps. same70)

  15. Пользуюсь проектом на основе примера atmel/lwip 1.3

    Всё в общем-то работает (ip+udp), кроме случая когда данных в пакете UDP меньше 3(трёх) байт.

    В регистре GMAC_DCFGR включаю бит  GMAC_DCFGR_TXCOEN

    Quote

    TXCOEN: Transmitter Checksum Generation Offload Enable
    Transmitter IP, TCP and UDP checksum generation offload enable. When set, the transmitter checksum generation engine 
    is enabled to calculate and substitute checksums for transmit frames. When clear, frame data is unaffected

     

    Затем формирую пакет udp для компьютера, отправляю, смотрю снифером (sam e70  >> PC )

    Если в поле контрольной суммы в подготовленном на отправку пакете содержится не ноль (0х0000), то:

      - для пакетов, в которых данных 3 байта и больше, контрольная сумма приходит правильная

      - для пакетов, в которых данных 0,1,2 байта, контрольная сумма приходит 0xFFFF

    Если в поле контрольной суммы в подготовленном на отправку пакете записать ноль (0х0000), то в приходящих на компьютер пакетах контрольная сумма ВСЕГДА правильная при любом количестве данных в UDP.

     

  16. - Может кто подскажет, а зачем сделаны 64-разрядными  шины DTCM (2x32) и ITCM(64)  ?

    В его ассемблере (я не изучал) есть инструкции для загрузки 64-битных данных?

    Посмотрел инструкции cortex-m7 по работе с памятью ADR/LDR - у них операнды 32-хразрядные. Если по этим шинам и так доступ без задержек, выполняется за 1 цикл, то зачем шина данных DTCM удвоенная? Как это можно использовать из Си-программы?

    - Можно ли область ITCM использовать под данные? (К примеру, если не нужно переносить код в память, а itcm+dtcm включаются вместе) 

  17. Вдруг кому пригодится. Пользуюсь примером от  Атмела  gmac_lwip GMAC lwIP Example.

    Включен аппаратный подсчет CRC на передачу и приём (биты GMAC_NCFGR_RXCOEN и GMAC_DCFGR_TXCOEN), программный подсчёт в lwip отключен.

    При отправке пакета UDP необходимо поле UDP checksumm занулять.

    Похоже, что МАС-контроллер пересчитывает её с учётом этих байтов, и если там уже лежит правильная сумма, то в пакет в эти поля вставляется FFFF.

    При этом для TCP и для ICMP ничего подобного не наблюдается, для IP-header checksumm тоже. 

     

    Похожее же было и с STM32, но там нужно было занулять поля чексуммы только для icmp, остальные нормально считались.

     

     

  18. 1 hour ago, KnightIgor said:

    Интересную вещь обнаружил.

    Кто-нибудь встречал такое?

    Встречал другое, в STM32_F_426 vgt(6 вроде) с размером флеш 1МБ

    У него есть есть возможность выбора режима флеш: 1 банк 1 МБ, либо 2 банка х 512КБ

    И это не просто логическое разделение 1х1МБ, либо 2х512, а действительно разные памяти флеш.

    Как проверено:

     - В режиме 1МБ заполнил флеш тестовыми данными

     - Переключил режим на 512+512КБ

     - Область №2 (вторые 512КБ) оказалась чистой (FF), заполнил и её

     - Переключил обратно на режим 1МБ, в области №2 оказались старые данные из п.1

    Т.е. получается памяти там 512КБ х3, и если нужно, то такими хитрыми извращениями можно что-то там хранить/спрятать

     

     

  19. Когда надо было через несколько маршрутов отправлять, ничего не нагуглить не получилось.

    Сделал "вручную": перед отправкой на конкретные адреса просто менял адрес шлюза netif_set_gw(...).

    Вроде ничего криминального в этом нет: при первом отправляемом пакете будет арп-запрос на этот новый шлюз, затем в таблицу арп будет внесена запись вида IPd_st = MACaddr_GW. Ну и при последующих отправках, лишних запросов на шлюз не будет.

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