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

VladislavS

Свой
  • Постов

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

  • Посещение

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

    9

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


  1. Chestor, компилировать программу надо с того адреса куда её загрузчик копирует. В твоём случае с 0x73f00000 (у тебя точно там DDRAM?). Прошивать образ в NAND и говорить загрузчику откуда и куда его копировать. Плюс к этому, надо в low_level_init твоей программы таблицу векторов прерываний скопировать на своё место.
  2. Если компилятор сам расположил структуру в памяти, то вне зависимости от директивы pack он должен корректно обращаться к памяти при доступе к любому полю.

     

    А вот если с указателями работать вольно, то запросто можно схлопотать ошибку доступа. Или вот так :)

     

    *((int *)0x40000007)=0;

  3. Для того чтобы получить 38 кГц на PD6 с помощью вот такой процедуры обработки прерываний

    interrupt [TIM1_COMPA] void timer1_compa_isr(void)
    {
       PORTD.6=!PIND.6;  
    }

    Надо настроить таймер, чтобы он делил на 97. Тогда частота на PD6 будет 7372800/97/2 = 38,004 кГц. Таймер настроить так:

      TCCR1A = 0;
      TCCR1B = (1<<WGM12)|(0<<CS12)|(0<<CS11)|(1<<CS10);
      OCR1AH = 0;
      OCR1AL = 97; 
      TIMSK = (1<<OCIE1A);

     

    Больше ничего не трогать и курить даташит. Не такой уж он большой и страшный, чтобы не утруждать себя его прочтением.

  4. Кусок кода, который используется и в прерывании, и в основном коде оформляете в виде функции. Озадачиваетесь вопросом что будет, если эта функция будет вызвана из прерывания во время её выполнения в основном коде. Ну и собственно всё.

  5. Зачем условие? Посмотри мой пример. Он от другой железки, но смысл не меняется. Накладываешь маску логическим AND и всё. Твоя задача только найти где взять эту маску. Либо она есть аппаратная в твоём чипе (кури даташит), либо переменную заведёшь под маску.

  6. Действительно, ничего юмористического. Вот есть у нас блочки, живущие на RS-485 кучкой или на RS-232 по одному. Соответственно все пакеты уже под сеть заточены, с адресацией, ответами и т.п.

     

    В один прекрасный момент приходит заказчик с чемоданчиком сами понимаете чего и говорит "хочу такие же N-штук, но у меня только RS-232". Ну ладно, цепляем "паровозиком", в прерывание приёма байта по UART добавляем команду отправки его же по UART и всё. Все блочки, включая и управляющее устройство, пакеты адресованные не ему откидывают по умолчанию.

     

    Надёжность такого решения чисто теоретически ниже, но на практике устройства, блокирующие правильную шину встречались, а порванный паровозик ещё нет. Хотя и применяли его считанные разы.

  7. Вижу какое-то глобальное недопонимание. Давай с начала по полочкам.

     

    Для компилятора разделение Release и Debug чисто условное. В обоих случаях ты можешь включать или нет отладочную информацию, менять степень оптимизации и прочие настройки проекта. Разница начинается уже после того как линкер собрал выходной файл.

     

    В варианте Debug скомпилированный файл прошивки, содержащий отладочную информацию, обычно загружается в ОЗУ и ему передаётся управление. Через J-tag осуществляется отладка. В принципе, ничто не мешает с помощью флэшлоадера поместить прошивку во FLASH и производить отладку, выполняя программу из FLASH. Нужен только флэшлоадер для твоего процессора и правильный конфигурационный макрос.

     

    Результатом сборки Relaese обычно является только файл прошивки без отладочной информации. Этот файл потом нужно как-то поместить во FLASH и сказать процессору стартовать из FLASH. Одни из вариантов записи во FLASH - использование флэшлоадера как в режиме отладки.

     

    Обрати внимание на следующее:

    1. При запуске программы из SRAM при отладке или из FLASH при штатной работе адресное пространство распределено по разному. Сегменты данных, кода, cтэки и векторы прерываний обязательно правильно разместить в памяти. Это всё надо в настройках проекта установить. Попросить линкер сделать map-файл и проверить по каким адресам он всё разместил.

    2. Я не работал с STM32, но беглый просмотр даташита говорит, что он может стартовать из FLASH, SRAM или системной памяти. После того как ты поместил прошивку во FLASH процессор надо перевести в режим старта из FLASH.

    3. Каким способом ты помещаешь готовую прошивку во FLASH (прошиваешь)? Это можно сделать либо флэшлоадером через J-tag, либо бутлоадером процессора через UART, либо ... Да мало ли как, но в любом случае, ты должен чётко понимать что (файл прошивки), как и по каким адресам надо прошить.

    4. Насчёт векторов прерываний. При старте из FLASH их не надо скопировать в SRAM?

     

    Что именно нужно сделать чтобы всё было?

    Хороший даташит и его полное прочтение, хэлпы от компилятора почитать внимательно. Сказать компилятору сделать программу в точности так как написано в даташите на процессор. Прошить и запустить :)

  8. Посмотрите платы от TERASIC.

     

    А где их брать с вменяемой стоимостью доставки? Думаю, мне DE0-Nano ($79) было бы за глаза для начала, но доставка $72 огорчает. Понятно, что если за >$500 плату брать, то не стоит сожалеть о цене доставки, но для Nano...

  9. Чисто теоретически, согласен. Наверное, правильнее *ram = *remap + 1;

    Но практически, я не представляю как это может стать источником проблем. Вероятность намного ниже, чем 1/sizeof(int). Потому что, или это значение туда записала программа из ROM, или оно само при включении там появилось. Ни в том ни в другом случае равномерного распределения нет.

  10. Если ремап был, то при записи в *ram это же значение появится и в *remap. Если не было, то в *remap будет содержимое ROM. Вроде всё верно.

     

    Плата периодически вела себя странно при старте

    А у вас что, плата сама может решить стартануть ремапнутой или нет?

  11. Я думаю проблемы с неправильной инициализацией железа. Перед вызовом сервисов его надо включить и сконфигурить ручками. Вот кусок кода из флэшлоадера:

      char *str;
      str=FlFindOption("-spi", 1, argc, argv); //Через параметр передаётся куда подключена
      
      if(str)
      {  
        AT91F_SPI_CfgPIO(); // PA0,PA1,PA2,PA3,PA4,PA5,PA6 ->A
        AT91F_SPI_CfgPMC();
        AT91C_BASE_SPI->SPI_CR=AT91C_SPI_SWRST;
        switch(*str)
        {
          case '0': //AT45 at NPCSO    
            AT91C_BASE_SPI->SPI_MR=AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS | (AT91C_SPI_PCS&(0<<16));        
            AT91C_BASE_SPI->SPI_CSR[0]=(0x01 << 24)|(0x18 << 16)|(4<<8)|(0<<1)|(1<<0); //DLYBCT DLYBS SCBR NPCHA CPOL        
            break;
          case '1': //AT45 at NPCS1
            AT91C_BASE_SPI->SPI_CSR[1]=(0x01 << 24)|(0x18 << 16)|(4<<8)|(0<<1)|(1<<0); //DLYBCT DLYBS SCBR NPCHA CPOL
            AT91C_BASE_SPI->SPI_MR=AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS | (AT91C_SPI_PCS&(1<<16));
            break;
          case '2': //AT45 at NPCS2
            AT91C_BASE_SPI->SPI_CSR[2]=(0x01 << 24)|(0x18 << 16)|(4<<8)|(0<<1)|(1<<0); //DLYBCT DLYBS SCBR NPCHA CPOL
            AT91C_BASE_SPI->SPI_MR=AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS | (AT91C_SPI_PCS&(3<<16));      
            break;
          case '3': //AT45 at NPCS3
            AT91C_BASE_SPI->SPI_CSR[3]=(0x01 << 24)|(0x18 << 16)|(4<<8)|(0<<1)|(1<<0); //DLYBCT DLYBS SCBR NPCHA CPOL
            AT91C_BASE_SPI->SPI_MR=AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS | (AT91C_SPI_PCS&(7<<16));      
            break;
          default:
            return RESULT_ERROR;
        }
        
        AT91C_BASE_SPI->SPI_CR=  AT91C_SPI_SPIEN;
        AT91C_BASE_SPI->SPI_PTCR=AT91C_PDC_TXTDIS|AT91C_PDC_RXTDIS; //TXTDIS RXTDIS
        AT91C_BASE_SPI->SPI_TNPR=0; AT91C_BASE_SPI->SPI_TNCR=0;
        AT91C_BASE_SPI->SPI_RNPR=0; AT91C_BASE_SPI->SPI_RNCR=0;  
        AT91C_BASE_SPI->SPI_TPR=0; AT91C_BASE_SPI->SPI_TCR=0;
        AT91C_BASE_SPI->SPI_RPR=0; AT91C_BASE_SPI->SPI_RCR=0;
        AT91C_BASE_SPI->SPI_PTCR=AT91C_PDC_TXTEN|AT91C_PDC_RXTEN; //TXEN RXEN 
        AT91F_SPI_DisableIt(AT91C_BASE_SPI,0x000000FF);
        
        pAT91 = AT91C_ROM_BOOT_ADDRESS;
    
        svcDataFlash.pDevice = &DeviceAT45DB;
        pAT91->OpenSvcDataFlash (AT91C_BASE_PMC, &svcDataFlash);
        
        AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SPI, 0, 0, &AT91F_SPI_Handler);
        AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SPI);
        
        __enable_interrupt();
            
        AT91F_DataFlashWaitReady();      
        //Детект Флэш    
        unsigned char type = ((svcDataFlash.DataFlashDesc.DataFlash_state >> 2) & 0x0F);
        
        switch(type)
        {
          case AT45DB321:
            DeviceAT45DB.pages_number = 8192;
            DeviceAT45DB.pages_size   = 528;
            DeviceAT45DB.page_offset  = 10;
            DeviceAT45DB.byte_mask    = 0x300;
            LCD_Printx(0,"AT45DB321 found on NPCS"); LCD_Print_Char(*str); 
            break;
          case AT45DB642:
            DeviceAT45DB.pages_number = 8192;    // number of pages
            DeviceAT45DB.pages_size   = 1056;    // page size (bytes)
            DeviceAT45DB.page_offset  = 11;        // page low bit offset
            DeviceAT45DB.byte_mask    = 0x700;    
            LCD_Printx(0,"AT45DB642 found on NPCS"); LCD_Print_Char(*str);
            break;
          default:
            LCD_Printx(0,"AT45 not found on NPCS"); LCD_Print_Char(*str);
            return RESULT_ERROR;
        }

     

    Ну и про обработчики прерываний не забываем

    void AT91F_SPI_Handler(void)
    {
        int status;
        status = AT91C_BASE_SPI->SPI_SR; 
        status&= AT91C_BASE_SPI->SPI_IMR;
        svcDataFlash.Handler(&svcDataFlash, status);
        
    }
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    __irq __arm void IRQ_Handler(void)
    {  
      void (*interrupt_task)();
      unsigned int vector;
      vector = AT91C_BASE_AIC->AIC_IVR; // Get interrupt vector.
      interrupt_task = (void(*)())vector;
      AT91C_BASE_AIC->AIC_IVR = 0; // Acknowledge interrupt in VIC.
    // __enable_interrupt(); // Allow other IRQ interrupts to be serviced from this point.
      (*interrupt_task)(); // Execute the task associated with this interrupt.
      AT91C_BASE_AIC->AIC_EOICR=0;
      return;
    }
    #ifdef __cplusplus
    }
    #endif

  12. Есть какие-то существенные ограничения в плане обучения из-за того что они старые?

    Или просто более сложные/производительные проекты можно делать на более современных чипах?

  13. Надо погрузиться в мир FPGA. Посмотрите, пожалуйста, стоит такое взять для изучения практически с нуля.

     

    Вот такие на Cyclone II

    Номер раз

    Номер два

    Номер три

    Номер четыре

    Какими-то малоуловимыми нюансами отличаются. Нужен ли ЖКИ графический, потянет он его?

     

    Или такой Spartan3 например?

    Номер пять

     

    Может кто что-то ещё недорогое посоветует?

     

    Пойти по пути Altera или Xilinx пока что всё равно.

     

    Имею большой опыт с разными микропроцессорами и микроконтроллерами. По необходимости с CPLD тоже работал.

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