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

jenya7

Участник
  • Публикаций

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

  • Посещение

Репутация

0 Обычный

Информация о jenya7

  • Звание
    Профессионал

Посетители профиля

4 785 просмотров профиля
  1. Надёжность EFM32 и их АЦП

    не помню. могу проверить только вечером когда будет доступ к схеме и исходникам. о. нашел. без ИОН. насколько я вижу из кода калибровку не делал void ADC0_SetupSingle(char adc_chan) { if (adc_chan > 7) return; CMU_ClockEnable(cmuClock_ADC0, true); //CMU_ClockSelectSet(cmuClock_ADC0, cmuSelect_LFXO); ADC_Init_TypeDef adcInit = ADC_INIT_DEFAULT; ADC_InitSingle_TypeDef adcInitSingle = ADC_INITSINGLE_DEFAULT; // Init common issues for both single conversion and scan mode/ adcInit.warmUpMode = adcWarmupNormal; adcInit.lpfMode = adcLPFilterBypass; adcInit.timebase = ADC_TimebaseCalc(0); adcInit.prescale = ADC_PrescaleCalc(7000000, 0); ADC_Init(ADC0, &adcInit); // Init for scan sequence use //scanInit.reference = adcRefVDD; adcInitSingle.acqTime = adcAcqTime4; adcInitSingle.reference = adcRefVDD; adcInitSingle.resolution = adcRes12Bit; adcInitSingle.rep = false; //repeated sampling adcInitSingle.input = adc_chan; //adcSingleInpCh7; ADC_InitSingle(ADC0, &adcInitSingle); // Enable ADC single overflow interrupt to indicate lost samples ADC_IntEnable(ADC0, ADC_IEN_SINGLE); NVIC_EnableIRQ(ADC0_IRQn); //DMA_ConfigAdcSingle(); ///Start repetitive ADC single conversions //ADC_Start(ADC0, adcStartSingle); } хотя возможность калибрации присутствует static void ADC_CalibrateLoadSingle(ADC_TypeDef *adc, ADC_Ref_TypeDef ref) { uint32_t cal; /* Load proper calibration data depending on selected reference */ /* NOTE: We use ...SCAN... defines below, they are the same as */ /* similar ...SINGLE... defines. */ switch (ref) { case adcRef1V25: cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK); cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_GAIN_MASK) >> _DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT; cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_OFFSET_MASK) >> _DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT; adc->CAL = cal; break; case adcRef2V5: cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK); cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_GAIN_MASK) >> _DEVINFO_ADC0CAL0_2V5_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT; cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_OFFSET_MASK) >> _DEVINFO_ADC0CAL0_2V5_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT; adc->CAL = cal; break; case adcRefVDD: cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK); cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_GAIN_MASK) >> _DEVINFO_ADC0CAL1_VDD_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT; cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_OFFSET_MASK) >> _DEVINFO_ADC0CAL1_VDD_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT; adc->CAL = cal; break; case adcRef5VDIFF: cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK); cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_GAIN_MASK) >> _DEVINFO_ADC0CAL1_5VDIFF_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT; cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_MASK) >> _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT; adc->CAL = cal; break; case adcRef2xVDD: /* Gain value not of relevance for this reference, leave as is */ cal = adc->CAL & ~_ADC_CAL_SINGLEOFFSET_MASK; cal |= ((DEVINFO->ADC0CAL2 & _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_MASK) >> _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT; adc->CAL = cal; break; /* For external references, the calibration must be determined for the */ /* specific application and set explicitly. */ default: break; } }
  2. Надёжность EFM32 и их АЦП

    Работал с EFM32 в том числе и с их AЦП. Впечатления самые положительные. Сильная сторона их - малая энергопотребляемость. Делал водный счетчик на батарейке. Потребление 7 uA в ждущем режиме.
  3. STM32 CAN фильтр.

    по моему я понял где проблема. STID находиться в HIGH половине региста, сдвинутый на 5 влево. то есть если я хочу получать данные для ID = 0xXX64 (XX - don't care) - нужно настраивать HIGH. CAN_FilterInitStructure.CAN_FilterNumber = 0; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0064 << 5; CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x00FF << 5; CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitStructure);
  4. я работаю с этим компонентом. в реальном проекте он ведет себя нормально а в тестбенче нет. как так?
  5. где косяк? скорее всего тестбенч написан неправильно.
  6. так другие сигналы тоже не отражают написанное в тестбенче testbench.vhd
  7. его формирует модуль СПИ мастер. это клок для СПИ слейв.
  8. есть тестбенч begin --начало архитектуры clk_process :process begin s_clk <= '0'; wait for clk_period/2; s_clk <= '1'; wait for clk_period/2; end process; stim_proc: process begin s_mspi_cs <= '0'; --chip select low s_mspi1_wr_done_clr <= '0'; s_mspi1_wr_data <= X"0010"; --WORD_READ s_mspi1_wr_start_trig <= '1'; --send a byte while (s_mspi1_wr_done = '1') loop s_mspi1_wr_start_trig <= '0'; s_mspi1_wr_done_clr <= '0'; end loop; s_mspi1_wr_done_clr <= '1'; s_mspi1_wr_data <= X"0000"; --ADDR_MSB s_mspi1_wr_start_trig <= '1'; --send a byte while (s_mspi1_wr_done = '1') loop s_mspi1_wr_start_trig <= '0'; s_mspi1_wr_done_clr <= '0'; end loop; s_mspi1_wr_done_clr <= '1'; s_mspi1_wr_data <= X"0002"; --ADDR_LSB s_mspi1_wr_start_trig <= '1'; --send a byte while (s_mspi1_wr_done = '1') loop s_mspi1_wr_start_trig <= '0'; s_mspi1_wr_done_clr <= '0'; end loop; s_mspi1_wr_done_clr <= '1'; s_mspi1_wr_data <= X"0000"; --DUMMY s_mspi1_wr_start_trig <= '1'; --send a byte while (s_mspi1_wr_done = '1') loop s_mspi1_wr_start_trig <= '0'; s_mspi1_wr_done_clr <= '0'; end loop; s_mspi1_wr_done_clr <= '1'; s_mspi1_wr_data <= X"0000"; --DUMMY s_mspi1_wr_start_trig <= '1'; --send a byte while (s_mspi1_wr_done = '1') loop s_mspi1_wr_start_trig <= '0'; s_mspi1_wr_done_clr <= '0'; end loop; s_mspi1_wr_done_clr <= '1'; s_mspi_cs <= '1'; --chip select high wait; end process stim_proc; end; --конец архитектуры но если посмотреть на результат симуляции - полная фигня. делитель клока = 1 а s_mspi_clk не равен s_clk. ну и другие сигналы никак не отражают написанного в тестбенче.
  9. попробую сделать тестбенч. довольно емкий тестбенч получается. а как в тестбенче подождать поднятие флага? так - wait for (s_mspi1_wr_done = '1'); - выдает ошибку нашел while (s_mspi1_wr_done = '1') loop end loop;
  10. тут 100% есть рассинхрон посылаемых дами байт и возвращаемого значения. не получается синхронизировать
  11. Я посылаю команду прочесть переменную. Переменная два байта а SPI 8-битный. В первом процесе я принимаю команду case SspiState is when ST_SSPI_IDLE => sital_command <= (others => '0'); if (cs2 = '0') then --falling edge SspiState <= ST_SSPI_COM; end if; when ST_SSPI_COM => if(rx_rdy4 = '1') then sspi_command <= sspi_data; SspiState <= ST_SSPI_ADDR1; end if; when ST_SSPI_ADDR1 => if(rx_rdy4 = '1') then sspi_addr2 <= sspi_data; --MSB first SspiState <= ST_SSPI_ADDR2; end if; when ST_SSPI_ADDR2 => --LSB if(rx_rdy4 = '1') then sspi_addr1 <= sspi_data; case sspi_command is when X"10" => --word read sital_command <= WORD_READ; SspiState <= ST_SSPI_WAIT; when X"12" => --continius read sital_command <= CONT_READ; SspiState <= ST_SSPI_WAIT; when others => SspiState <= ST_SSPI_DATA1; end case; end if; when ST_SSPI_DATA1 => if(rx_rdy4 = '1') then sspi_data2 <= sspi_data; --MSB first SspiState <= ST_SSPI_DATA2; end if; when ST_SSPI_DATA2 => --LSB if(rx_rdy4 = '1') then sspi_data1 <= sspi_data; SspiState <= ST_SSPI_WAIT; case sspi_command is when X"11" => --word write sital_command <= WORD_WRITE; when others => SspiState <= ST_SSPI_WAIT; end case; end if; when ST_SSPI_WAIT => sital_command <= (others => '0'); if (cs2 = '1') then SspiState <= ST_SSPI_IDLE; end if; when others => SspiState <= ST_SSPI_IDLE; end case; Во втором выбираю переменную и выдаю ее наружу when ST_WORD_READ => when X"0002" => sspi_data_out <= X"0306"; -- buld in test, return constant when X"0004" => sspi_data_out <= X"5555"; -- buld in test, return constant when X"0006" => sspi_data_out <= X"AAAA"; -- buld in test, return constant when X"0020" => sspi_data_out <= "0000000000" & REG_F_LPTG_IN; dbg_val2 <= "00" & REG_F_LPTG_IN; State <= ST_SET_READ_1; when ST_SET_READ_1 => SSPI_TX_DATA <= sspi_data_out(15 downto 8); State <= ST_SET_READ_2; when ST_SET_READ_2 => SSPI_TX_DATA <= sspi_data_out(7 downto 0); dbg_val3 <= sspi_data_out(7 downto 0); State <= ST_IDLE; Но данные обновляются только на втором запросе. Выставил на входе 2 Opcode addr_msb addr_lsb dummy dummy response WORD_READ 00 20 00 00 0 //старое значение WORD_READ 00 20 00 00 2 WORD_READ 00 20 00 00 2 Выставил на входе 3 WORD_READ 00 20 00 00 2 //старое значение WORD_READ 00 20 00 00 3 WORD_READ 00 20 00 00 3 Причем dbg_val2 и dbg_val3 я вывожу на дисплей и вижу правильное обновление в той же посылке. а если считываю переменную по адресу 2 WORD_READ 00 04 - 03 00 WORD_READ 00 04 - 03 06 то есть второй байт sspi_data_out(7 downto 0); обновляется только на втором запросе. Не могу отловить проблему.
  12. я покопался в старых проектах, писанных до меня и нашел модуль SMI. я его еще не тестировал, так что не могу сказать насколько он рабочий. А что есть разница какой PHY? Протокол вроде универсальный. В данном случае я должен говорить с MARVELL Ethernet switch.
  13. как чувствовал. :) у меня эти выходы с entity мапируются на выходы в топ entity.
  14. спасибо. я читал что стоит избегать использование inout.
  15. я и сделал через промежуточный сигнал. все равно ошибка. этого я и хочу избежать.