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

ilkz

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

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

  • Посещение

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


  1. Чтением регистра статуса:

    uint8_t ad7799_ready(void)
    {
        unsigned char rdy = 0;
        rdy = ad7799_get_register(AD7799_REG_STAT, 1) & 0x80;
        return(!rdy);
    }
    
    uint32_t ad7799_read_data_raw(void)
    {
        return ad7799_get_register(AD7799_REG_DATA, 3);
    }
    
    void main(void)
    {
        ...
        ad7799_set_mode(AD7799_MODE_CONT);
        while(1)
        {
                if(ad7799_ready())
                {
                    adc_raw = ad7799_read_data_raw();
                    printf("%06x   %2.6fv\n", adc_raw, ad7799_to_volts(adc_raw));
                }
        }
    }

     

    Еще вопрос: если АЦП подключен по униполярной схеме, то как правильно задавать значения FULLSCALE и OFFSET? Судя по даташиту (When the ADC is configured for unipolar operation, the output code is natural (straight) binary with a zero differential input voltage resulting in a code of 00...00, a midscale voltage resulting in a code of 100...000, and a full-scale input voltage resulting in a code of 111...111.), их надо задать как OFFSET=0, FULLSCALE=FFFFFF (нулевое смещение и размах во всю шкалу). Но если я так сделаю, то из АЦП всегда читается FFFFFF при напряжении на входе, например, 0.7В.

  2. АЦП читается нормально - я это вижу по значениям регистров, вычитываемых после сброса: они соответствуют даташиту.

     

    Я вот что подумал: в даташите написано, что при измерении в канале AVDD само значение AVDD сначала ослабляется в 6 раз, потом выносится на подствку 1.17В (типа, чтобы лучше видеть пульсации напряжения). Означает ли это, что вместо сидящих на входе 5В я должен прочитать: (5/6)+1.17=2.003333 Вольта?

  3. Привет.

     

    Читаю AD7799 в униполярном режиме и получаю какую-то ересь, ну либо не понимаю как правильно преобразовать цифры. Для начала, пытаюсь читать AVDD.

    Вот код, которым настраиваю и читаю АЦП:

        ad7799_set_channel(AD7799_CH_AVDD_MONITOR);
    
        ad7799_set_burnout(0);
        ad7799_set_unipolar(1);
        ad7799_set_gain(AD7799_GAIN_1);
        ad7799_set_ref_det(0);
        ad7799_set_buffered(1);
        
        ad7799_set_psw(0);
        ad7799_set_rate(AD7799_RATE_4_17_HZ);
    
        ad7799_set_offset(0x000000);
        ad7799_set_fullscale(0xFFFFFF);
    
        ad7799_set_mode(AD7799_MODE_CONT);
        while(1)
        {
            if(ad7799_ready())
            {
                ad7799_dump_regs();
                printf("     offset = %f\n", ad7799_to_volts(ad7799_get_offset()));
                printf("  fullscale = %f\n", ad7799_to_volts(ad7799_get_fullscale()));
                printf("\n");
                adc_raw = ad7799_read_data_raw();
                printf("%06x   %2.6fv\n", adc_raw, ad7799_to_volts(adc_raw));
                for(i=0; i<20000000; i++);
            }
        }

     

    Вот так преобразую в вольты:

    uint32_t ad7799_read_data_raw(void)
    {
        return ad7799_get_register(AD7799_REG_DATA, 3);
    }
    
    #define VREF 2.5
    #define SPAN 0xFFFFFF
    #define GAIN 1
    
    float ad7799_to_volts(uint32_t value)
    {
        return (float)(value * (VREF / SPAN * GAIN));
    }
    
    float ad7799_read_data_volts(void)
    {
        return ad7799_to_volts(ad7799_read_data_raw());
    }

     

    Вот что выводит принтф:

         STAT = 0f
         MODE = 000f
         CONF = 1017
         DATA = aeff0c
           ID = 49
           IO = 00
       OFFSET = 800000
    FULLSCALE = 555500
    
         offset = 1.250000
      fullscale = 0.833321
    
    aeff0c   1.708948v

     

    На ноге AVDD при этом сидит реальных 4.85В.

    Всю голову уже сломал, помогите разобраться.

  4. Я бы подобрал отладочную плату с плисиной (ну допустим что-то наподобие Arria II GX FPGA Development Board), а к ней сделал внешнюю платку с выбранной АЦП'шкой (ну или попробовал состыковать АЦП'шный кит (если он есть) с плисовым китом. Это проще и быстрее.

  5. ... фифо с раздвижкой указателей на половину ...

     

    А можно вот тут подробнее? Впервые слышу. Мне всегда казалось что фифо это просто два тактово независящих друг от друга указателя (указатель rd, который всегда "догоняет" указатель wr, но не обгоняет его). Ну естественно, они развязаны через cdc друг относительно друга.

  6. Разобрался кажется

     

    было вот так:

        while (1) {
                mm_process_packets();
        }

     

    сделал вот так:

        while (1) {
            if(TM_USB_HIDDEVICE_GetStatus() == TM_USB_HIDDEVICE_Status_Connected)
                mm_process_packets();
            
            if(TM_USB_HIDDEVICE_GetStatus() == TM_USB_HIDDEVICE_Status_Disconnected)
            {
                TM_USB_HIDDEVICE_Init();
                Delayms(1000);
            }
        }

     

    Вроде работает.

    Всем спасибо!

  7. STM32F4-Discovery.

    В проекте использую либу TM_USB_HID_DEVICE для создания своего hid-девайса.

     

    После заливки поведение следующее:

    1. Сразу после заливки проект работает как надо: видится в винде, обменивается данными с прогой. После передерга питания/нажатия кнопки RESET все так же хорошо.

    2. Но если не выключая питание платы перевоткнуть USB, то второй раз девайс уже не определяется: винда пишет что устройство USB не опознано.

     

    Что делать - не знаю, уже прям всю голову сломал.

    Помогите - куда копать?

     

    Если нужны подробности - пишите какие именно, дам на посмотреть.

     

    Спасибо!

  8. Согласно даташиту должна быть 1.

     

    Точно. Заработало. Спасибо, друзья!!!

    В даташитах явно не указано что при записи OE должен быть единицей, это и сбило с толку.

     

    Подведу итог: моя ошибка была в том, что нужно было управлять не только своим OE, но и OE внешнего чипа (в моем случае это был сигнал phy_sloe).

  9. Ок, привожу полный код модуля:

    `include "timescale.v"
    
    // FX2LP-FPGA interface, slave-FIFO mode, FPGA is master
    // see Cypress AN61345
    module usb
       (
           input clk,
           input reset,
    
           output busy,
    
           input [15:0] data_i,
           input wr_data,
    
           output reg [15:0] data_o,
           output reg data_received,
    
           // FX2LP phy
           input phy_ifclk,        // 48MHz internal IF clock
           input phy_flaga,        // EP2 empty flag (EP2 - OUT, 512-bytes, 4x, bulk), EP_OUT: [HOST]->[FPGA]
           input phy_flagd,        // EP6 full flag (EP6 - IN, 512-bytes, 4x, bulk),    EP_IN: [HOST]<-[FPGA]
           output reg phy_slrd,
           output reg phy_slwr,
           output reg phy_sloe,
           output reg [1:0] phy_fifoadr,
           inout [15:0] phy_fd
       );
    
       wire ep_out_not_empty = phy_flaga;
       wire ep_out_empty = ~phy_flaga;
       wire ep_in_full = phy_flagd;
    
       localparam ST_FREE = 0;
       localparam ST_READ_OUT_EP = 1;
       localparam ST_WRITE_IN_EP = 2;
    
       reg [1:0] state;
       reg [15:0] phy_fd_reg;
       reg ep_out_not_empty_reg;
    
       always @(posedge phy_ifclk, posedge reset) begin
           if(reset) begin
               state <= ST_FREE;
               phy_fifoadr <= 0;
               phy_sloe <= 1;
               phy_slrd <= 1;
               phy_slwr <= 1;
               phy_fd_reg <= 0;
               data_o <= 0;
               data_received <= 0;
               ep_out_not_empty_reg <= 0;
           end
           else begin
               ep_out_not_empty_reg <= ep_out_not_empty;
    
               case(state)
                   ST_FREE:
                       begin
                           if(ep_out_not_empty) begin
                               phy_fifoadr = 0;
                               phy_sloe <= 0;
                               phy_slrd <= 0;
                               phy_slwr <= 1;
                               state <= ST_READ_OUT_EP;
                           end
                           else if(wr_data & (ep_in_full == 1)) begin
                               //phy_fd_reg <= data_i;
                               phy_fd_reg <= phy_fd_reg + 1;
                               phy_fifoadr = 2;
                               phy_sloe <= 0;
                               phy_slrd <= 1;
                               phy_slwr <= 0;
                               state <= ST_WRITE_IN_EP;
                           end
                       end
    
                   ST_READ_OUT_EP:
                       begin
                           data_o <= phy_fd;
                           if(ep_out_empty) begin
                               phy_fifoadr = 0;
                               phy_sloe <= 1;
                               phy_slrd <= 1;
                               phy_slwr <= 1;
                               data_received <= 0;
                               state <= ST_FREE;
                           end
                           else data_received <= 1;
                       end
    
                   ST_WRITE_IN_EP:
                       begin
                           //phy_fd_reg <= data_i;
                           phy_fd_reg <= phy_fd_reg + 1;
                           if(!wr_data) begin
                               phy_fifoadr = 0;
                               phy_sloe <= 1;
                               phy_slrd <= 1;
                               phy_slwr <= 1;
                               state <= ST_FREE;
                           end
                       end
    
                   default:
                       begin
                           phy_fifoadr <= 0;
                           phy_sloe <= 1;
                           phy_slrd <= 1;
                           phy_slwr <= 1;
                           data_received <= 0;
                           state <= ST_FREE;
                       end
               endcase
    
           end
       end
    
       assign busy = ep_out_not_empty | ep_out_not_empty_reg;
       //assign phy_fd = phy_fd_reg;
       assign phy_fd = !phy_slwr ? phy_fd_reg : 16'bz;
       //assign phy_fd = !phy_slwr ? data_i : 16'bz;
    
    endmodule
    

  10. Я что-то походу залип.

     

    Тривиальный код:

            output reg [15:0] data_o,
            input [15:0] data_i,
            inout [15:0] phy_fd
    ...
        reg [15:0] phy_fd_reg;
    
        always @(posedge phy_ifclk, posedge reset) begin
            if(reset) begin
                data_o <= 0;
                phy_fd_reg <= 0;
            end
            else begin
                            data_o <= phy_fd;
                phy_fd_reg <= data_i; // можно так
                //phy_fd_reg <= phy_fd_reg + 1; // а можно и так - без разницы
            end
        end
        
        assign phy_fd = !phy_slwr ? data_i : 16'bz;

     

    Это вырезка из автомата работы с CY7C68013A в режиме Slave FIFO.

     

    Вытаскиваю в сигналтап сигнал phy_fd. Вижу что во время вывода в порт буфер никогда не выставляет на свой выход значения (всегда сидят нули), хотя OE вроде бы подается (на акртинке показан вариант с счетчиком):

    post-67084-1449143612_thumb.png

     

    При этом на прием работает нормально.

    Я где-то неправ?

  11. Насколько я понял на данный момент: делать только TD_Init() - недостаточно.

    Нужно уметь отдавать дескрипторы, и крутить цикл с опросом TD_Poll().

    В моем случае TD_Poll() может быть пустым, т.к. использую режим Auto.

     

    Все верно?

     

    Так, я взял код из AN61345.

    Вот сейчас, например, он виснет на EZUSB_Discon(TRUE) - девайс перестает распознаваться системой.

  12. Коллеги, добрый день.

     

    Разбираюсь с CY7C68013A в режиме Slave FIFO. Данные принимает-передает ПЛИСка.

    AN61345 курил, вроде все более-менее понятно.

     

    Обмен данными провожу в USB Control Center.

     

    BULK OUT в EP2 OUT работает нормально - т.е., с компа в ПЛИСку данные прилетают - я это вижу в SignalTap.

    ПЛИСка в ответ отсылает те же данные: выставляет FIFOADDR=2 и записывает принятые данные в чип. Если теперь я выбираю BULK IN EP 0x86 и нажимаю Transfer Data In, то получаю ошибку: BULK IN transfer failed with Error Code:997.

     

    Чип настроен конфигом из AN61345. Код:

    #include "fx2.h"
    #include "fx2regs.h"
    #include "fx2sdly.h"
    
    void TD_Init( void )
    {
        CPUCS = 0x12; // CLKSPD[1:0]=10, for 48MHz operation, output CLKOUT
    
        PINFLAGSAB = 0x08;            // FLAGA - EP2EF
        SYNCDELAY;
        PINFLAGSCD = 0xE0;            // FLAGD - EP6FF
        SYNCDELAY;
        PORTACFG |= 0x80;
        SYNCDELAY;
        IFCONFIG = 0xE3; //Internal clock, 48 MHz, Slave FIFO interface
        SYNCDELAY;
    
        EP2CFG = 0xA0;                //out 512 bytes, 4x, bulk
        SYNCDELAY;                    
        EP6CFG = 0xE0;                // in 512 bytes, 4x, bulk
        SYNCDELAY;              
    
        SYNCDELAY;
        FIFORESET = 0x80;             // activate NAK-ALL to avoid race conditions
        SYNCDELAY;                    // see TRM section 15.14
        FIFORESET = 0x02;             // reset, FIFO 2
        SYNCDELAY;                    // 
        FIFORESET = 0x06;             // reset, FIFO 6
        SYNCDELAY;                    // 
        FIFORESET = 0x00;             // deactivate NAK-ALL
    
    
        SYNCDELAY;                    // 
        EP2FIFOCFG = 0x00;            // AUTOOUT=0, WORDWIDE=1
    
        SYNCDELAY;                    // 
        EP2FIFOCFG = 0x11;            // AUTOOUT=1, WORDWIDE=1
    
        SYNCDELAY;                    // 
        EP6FIFOCFG = 0x0D;            // AUTOIN=1, ZEROLENIN=1, WORDWIDE=1
    
        SYNCDELAY;
    
        OEA|=0x02; //Declare PA.1 as output
        SYNCDELAY;
        IOA|=0x02; //output 1 on PA.1
        SYNCDELAY;
    
        OEC|=0x01; //PC.0 as output (SYNC signal)
        SYNCDELAY;
        IOC|=0x00; //output 0 on PC.0...SYNC signal is LOW 
        SYNCDELAY;
        OEC&=0xFD; //PC.1 as input (Clock changing signal)
        SYNCDELAY;
    }
    
    void main(void)
    {
         TD_Init();
    }

     

    Также привожу снапшот времянки ПЛИС:

    post-67084-1449125003_thumb.png

    Здесь меня смущает что не дергается FLAG_D.

     

    И вдогонку еще один вопрос:

    Судя по коду конфига, после загрузки прошивки в чип, я должен видеть там только 2 ендпоинта: EP2 OUT и EP6 IN. Однако, их там на самом деле больше:

    post-67084-1449125143_thumb.png

    Такое ощущение, что прошивка либо не заливается (заливаю через Ppogram FX2->RAM, и он пишет что Programming succeded), либо я что-то не так делаю.

     

    Выручайте - уж очень хочется запустить обмен...

     

    Спасибо!

  13. Row=12, Col=9.

     

    Теперь возникла следующая проблема:

    Если процессору указать Reset vector на SDRAM, то NIOS не заливается: Downloading ELF Process failed.

     

    При заливке с ошибкой получается вот это:

    Using cable "USB-Blaster [USB-0]", device 1, instance 0x00
    Resetting and pausing target processor: OK
    Reading System ID at address 0x0200A060: 
        ID value was not verified: value was not specified
        Timestamp value was not verified: value was not specified
    Initializing CPU cache (if present)
    OK
    
    Downloading 01000000 ( 0%)
    Downloading 01001560 (95%)
    Downloaded 6KB in 0.0s        
    
    Verifying 01000000 ( 0%)
    Verify failed between address 0x1000000 and 0x1001463
    Leaving target processor paused

     

    Настройки системы:

    post-67084-1448019436_thumb.png

     

    При этом, если указать старт из Onchip RAM, то стартует нормально.

    Что это может быть? Может из-за того что память 16-битная?

     

    Убрал Clock Bridge - заработало. Видимо, разваливались тайминги. А что разве Qsys не умеет автоматом генерить констрейны для своих модулей?

  14. ну судя по функциональной схеме из даташита 2M*16*4 банка = 128

    12бит адреса = 4 095 байт т.е =32 760 бит, а значит 16*32000*4 банка = 128Mb и получается, что вы все верно рассчитали)

    а если мы добавим еще 13-ый бит адреса, то получится в два раза больше, а память-то на 128...

     

    у вас конечный адрес = FF FFFF - это и есть равно 16 Мбит, а должно быть = 7A1 2000

     

    Все заработало и почти все было корректно.

    Смотрим в даташит: H57V1262GTR series is organized as 4banks of 2,097,152 x 16, т.е. 134,217,728 бит => 16,777,216 байт.

    Теперь смотрим в QSys: конечный адрес равен 0xFF_FFFF, что как раз равно 16,777,216 байт. Адресуются же байты, а не биты. Видимо, вчера меня хорошенько переклинило :-).

     

    Таким образом, вся моя ошибка была лишь в неправильном задании ширины адресной шины в контроллере SDRAM.

     

    lait33, спасибо за помощь!

  15. Почему конечный адрес получился 1FF_FFFF, а не 7A1 2000- это как раз и будет 128Mbit

     

    1. А precharge flag не учавствует в формировании адреса? Зачем тогда его включают в адресную шину? Исправил:

    post-67084-1447850510_thumb.png

     

    Область памяти теперь получилась размером в 16Мбит. Не понимаю почему - ведь в настройках корки указано 128Мбит...

    Правильно ли я рассчитываю: 16 бит данных * 2^(12 бит адреса - 1 бит на precharge_flag) * 4 банка = 128 Мбит. Верно же?

    post-67084-1447850621_thumb.png

     

     

     

    У вас даже один банк полностью не заполнился. т.к один банк = 32Mbit, а заполнился на 8Mbit.

    И по идее тайминги wizzard выставляет сам

     

    Зато мемтест на этой короткой области памяти заработал:

    post-67084-1447850960_thumb.png

  16. Друзья, такой затык:

    Есть кит DVK600, а к нему платка с чипом H57V1262GTR-75С. Не получается полностью завести память из-под ниос. Если нужно, могу выложить проект.

     

    Собираю систему в Qsys, клок - 50МГц, констрейны кроме derive_pll_clocks и create_clock 50МГц никакие не заданы:

    post-67084-1447828074_thumb.png

    post-67084-1447828341_thumb.png

    post-67084-1447828345_thumb.png

     

    Далее собираю дефолтный проект simple memory test в ниосе:

    post-67084-1447828352_thumb.png

     

    При тестировании получаю ошибку:

    post-67084-1447828355_thumb.png

     

    Вычисления показывают, что работает лишь один банк из 4-х.

    Из даташита на память мне непонятно какие тайминги нужно задавать в настройках ядра в Qsys и удовлетворяют ли заданные там по умолчанию.

    И еще - как корректно законстрейнить память?

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