Antokha 0 30 марта, 2011 Опубликовано 30 марта, 2011 (изменено) · Жалоба Решил прикрутить к своей программе протокол x-modem и управление программой через hyperterminal. Взял за основу romboot от Atmel-a, который я уже сам компилировал с помощью gcc под линуксом (ubuntu). Программа к которой хочу прикрутить x-modem делалась в ИАР-е, поэтому создал проект в ИАР 5.11, добавил файлы romboot-а, поправил c_startup.s, asm-обработчик прерывания. Проект компилируется, но смущают восемь warning-ов на файл embedded_services.h на структуры в самом конце этого файла где написаны const. Ладно - под линуксом работало и здесь вроде бы тоже должно. Заливаю по X-modem-у в контроллер AT91RM9200. Не определяется флеш. Начинаю копать покомандно с выводом ошибок через printf: int main(void) { AT91PS_Buffer pXmBuffer; AT91PS_SvcComm pSvcXmodem; AT91S_SvcTempo svcUbootTempo; // Link to a AT91S_Tempo object unsigned int AddressToDownload, SizeToDownload; unsigned int DeviceAddress = 0; volatile int i = 0; char command = 0; unsigned int crc1 = 0, crc2 = 0; volatile int device; int NbPage; stdin = fopen(0, at91_dbgu_getc); stdout = fopen(at91_dbgu_putc, 0); pAT91 = AT91C_ROM_BOOT_ADDRESS; // Tempo Initialisation pAT91->OpenCtlTempo(&ctlTempo, (void *) &(pAT91->SYSTIMER_DESC)); //if (!pAT91->OpenCtlTempo(&ctlTempo, (void *) &(pAT91->SYSTIMER_DESC))) \ AT91F_DBGU_Printk("\n\rOpenCtlTempo(): OpenCtlTempo initialized\n\r"); //OK ctlTempo.CtlTempoStart((void *) &(pAT91->SYSTIMER_DESC)); //if ((ctlTempo.CtlTempoStart((void *) &(pAT91->SYSTIMER_DESC)))== 2 ) \ AT91F_DBGU_Printk("\n\rCtlTempoStart returns 2\n\r"); //OK // Attach the tempo to a tempo controler //ctlTempo.CtlTempoCreate(&ctlTempo, &svcUbootTempo); if ((ctlTempo.CtlTempoCreate(&ctlTempo, &svcUbootTempo)) == 1) AT91F_DBGU_Printk("\n\rthe software tempo wasn't created\n\r");\ else AT91F_DBGU_Printk("\n\rthe software tempo was created\n\r"); // svcUbootTempo.Start(&svcUbootTempo,100,0,NULL,NULL); На ctlTempo.CtlTempoCreate(&ctlTempo, &svcUbootTempo) выводит ошибку. Прошу поделиться опытом применения встроенного ПО контроллера. Чего не правильно уже понять не могу. В приложении мой проект для ИАРа. Так же не работает кроме SPI-флешки X-modem (имеется ввиду его реализация в бинарнике romboot-a: его функции: он не принимает бинарник). Romboot.rar Изменено 30 марта, 2011 пользователем Antokha Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Antokha 0 2 апреля, 2011 Опубликовано 2 апреля, 2011 (изменено) · Жалоба Попробовал изменить последовательность запуска этих сервисов: pAT91 = AT91C_ROM_BOOT_ADDRESS; // Tempo Initialisation pAT91->OpenCtlTempo(&ctlTempo, (void *) &(pAT91->SYSTIMER_DESC)); //if (!pAT91->OpenCtlTempo(&ctlTempo, (void *) &(pAT91->SYSTIMER_DESC))) \ AT91F_DBGU_Printk("\n\rOpenCtlTempo(): OpenCtlTempo initialized\n\r"); //OK ctlTempo.CtlTempoStart((void *) &(pAT91->SYSTIMER_DESC)); //if ((ctlTempo.CtlTempoStart((void *) &(pAT91->SYSTIMER_DESC)))== 2 ) \ AT91F_DBGU_Printk("\n\rCtlTempoStart returns 2\n\r"); //OK // Attach the tempo to a tempo controler //ctlTempo.CtlTempoCreate(&ctlTempo, &svcUbootTempo); if ((ctlTempo.CtlTempoCreate(&ctlTempo, &svcUbootTempo)) == 1) AT91F_DBGU_Printk("\n\rthe software tempo wasn't created\n\r");\ else AT91F_DBGU_Printk("\n\rthe software tempo was created\n\r"); // <<<<<<<<------------здесь в окне гипертерминала пишет the software tempo wasn't created // svcUbootTempo.Start(&svcUbootTempo,100,0,NULL,NULL); // Xmodem Initialisation pXmBuffer = pAT91->OpenSBuffer(&sXmBuffer); pSvcXmodem = pAT91->OpenSvcXmodem(&svcXmodem, (AT91PS_USART)AT91C_BASE_DBGU, &ctlTempo); //--- //pSvcXmodem = pAT91->OpenSvcXmodem(&svcXmodem, (AT91PS_USART)AT91C_BASE_US1, &ctlTempo); pAT91->OpenPipe(&xmodemPipe, pSvcXmodem, pXmBuffer); // System Timer initialization AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, // AIC base address AT91C_ID_SYS, // System peripheral ID AT91C_AIC_PRIOR_HIGHEST, // Max priority AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, // Level sensitive AT91F_ST_ASM_Handler ); // Enable ST interrupt AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS); // DataFlash on SPI Configuration AT91F_DataflashInit (); if ((ctlTempo.CtlTempoCreate(&ctlTempo, &svcUbootTempo)) == 1) AT91F_DBGU_Printk("\n\rthe software tempo wasn't created\n\r");\ else AT91F_DBGU_Printk("\n\rthe software tempo was created\n\r"); // <<<<<<<<------------здесь в окне гипертерминала пишет the software tempo was created // start tempo to start Uboot in a delay of 1 sec if no key pressed svcUbootTempo.Start(&svcUbootTempo, 1000, 0, AT91F_StartUboot, (void *)0); Результат: при втором запуске всё добавляется. Убираю первый запуск (оставляя второй, т.е. тот что после AT91F_DataflashInit ()) получаю опять сообщение "the software tempo wasn't created". Изменено 2 апреля, 2011 пользователем Antokha Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 3 апреля, 2011 Опубликовано 3 апреля, 2011 · Жалоба Я думаю проблемы с неправильной инициализацией железа. Перед вызовом сервисов его надо включить и сконфигурить ручками. Вот кусок кода из флэшлоадера: 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться