Vinterman 0 6 ноября, 2008 Опубликовано 6 ноября, 2008 (изменено) · Жалоба Всем доброго времени суток! Возникла необходимость перейти с AVR на ARM-ы. Вот тут сразу незадачка вышла. Прочитал, пересмотрел, перелопатил достаточно большое количество примеров программ, литературы (Бедного редькина и Англ даташит). Купил отладочную платку, SAM7-P64, Wiggler программаторик. "Стянул" IAR с интернета, "вылечил" его и приступил к работе. Для начала решил определиться, какой же минимум подключаемых файлов необходим, ибо все примеры пестрят ТАКИМ их количеством, что порой черт ногу сломит. Вроде подразобрался, написал первую прогу и тут же сел в лужу Как и водится, решил "поиграть" ножками для начала. Но перед тем как "зашивать", как водится запустил прогу в эмуляторе. Эмулятор работает, прога на первый взгляд выполняется. НО!!!! В регистре PMC_SCSR после сброса (Выполнение программы только начинается) ВСЕ НУЛИ!! Когда флаг PCK (состояние тактирования процессора) должен быть установлен! И многие остальные регистры, так же не выходят на свое первоначальное состояние. После выполнения записи в регистр PIO_SODR, как я полагаю, должны установиться соответствующие биты и в регистре PIO_ODSR. (а в PIO_SODR сброситься в окне эмулятора ????) Этого не происходит!!! Что за ерунда? Что я не правильно делаю? То же самое происходит и с остальными регистрами. Скажем при установки PIO_OER, не меняется PIO_OSR.... Программировать контроллер не программировал. Думал может надо разрешить тактирование PIO и процессора, дописал соответствующие команды, нифига. Пробовал записывать регистры состояния в отдельный регистр (считывал), думал может тут баг, ведь вроде они для чтения, но умом то понимал, что блин эмулятор должен показывать, как и ожидалось, ничего не произошло :) считались НУЛИ :) Вот пример программы: (прошу не критиковать код ибо все получилось в результате безрезультатных попыток на скорую руку запустить эмулятор из имеющихся под рукой программ) // ******************************************************* // Header Files // ******************************************************* #include "AT91SAM7S256.h" unsigned int a; int main (void) { while (1) { volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; // pointer to PIO data structure volatile AT91PS_PMC pPMC = AT91C_BASE_PMC; pPMC->PMC_PCER = 1 << AT91C_ID_PIOA; pPMC->PMC_SCER = 1 << 0; pPIO->PIO_PER = 4; // PIO Enable Register - allow PIO to control pins pPIO->PIO_OER = 0xFFFF; // PIO Output Enable Register pPIO->PIO_SODR = 12; // PIO Set Output Data Register pPIO->PIO_CODR = 4; a = pPIO->PIO_ODSR; // a = pPIO->PIO_CODR; } } Прошу помощи!!!!! HELP!!! Чего не хватает, где упущение, если можно , то образец минимального набора прикрипляемых файлов и кода программы хотелось бы посмотреть для управления ножками контроллера Изменено 6 ноября, 2008 пользователем Vinterman Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 64 6 ноября, 2008 Опубликовано 6 ноября, 2008 · Жалоба Как и водится, решил "поиграть" ножками для начала. Но перед тем как "зашивать", как водится запустил прогу в эмуляторе. ... Программировать контроллер не программировал. Т.е. запустили в симуляторе, а не под эмуляцией. Бросьте это дело и забудьте про симуляцию периферии на ARM. pPMC->PMC_SCER = 1 << 0; Это явно лишнее, остального достаточно для ногодрыганья. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 6 ноября, 2008 Опубликовано 6 ноября, 2008 · Жалоба Т.е. запустили в симуляторе, а не под эмуляцией. Бросьте это дело и забудьте про симуляцию периферии на ARM. Это явно лишнее, остального достаточно для ногодрыганья. Благодарю за ответ. Рад что опытный глаз сделал ревизию моего кода, теперь я хоть знаю что иду в правильном направлении. Спасибо. Сегодня вечером попробую "подрыгать лапкой". И если успеется, то опробую прерывание от таймера использовать, для тренировки и освоения работы с прерываниями. Ждите развития темы и новых вопросов :) Один из всплывших вопросов. Почему я вынужден из-за, на мой взгляд, корявого файла описателя "AT91SAM7S256.h" писать такие строки: volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; pPIO->PIO_OER = 0xFFFF; Есть в нете, более грамотные описатели, чтобы можно было указывать сразу понравившийся регистр, в следующем формате: PIO_OER = 0xFFFF; Или в ручную придется перелопачивать все ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 64 6 ноября, 2008 Опубликовано 6 ноября, 2008 · Жалоба Один из всплывших вопросов. Почему я вынужден из-за, на мой взгляд, корявого файла описателя "AT91SAM7S256.h" писать такие строки: volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; pPIO->PIO_OER = 0xFFFF; Есть в нете, более грамотные описатели, чтобы можно было указывать сразу понравившийся регистр, в следующем формате: PIO_OER = 0xFFFF; Или в ручную придется перелопачивать все ? А зачем так сложно? Можно написать: AT91C_BASE_PIOA->PIO_OER = 0xffff; или *AT91C_PIOA_OER = 0xffff; Можно перелопатить хидер, чтобы писать просто PIOA_OER = 0xffff. Поиск->замена рулит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 6 ноября, 2008 Опубликовано 6 ноября, 2008 (изменено) · Жалоба А зачем так сложно? Можно написать: AT91C_BASE_PIOA->PIO_OER = 0xffff; или *AT91C_PIOA_OER = 0xffff; Можно перелопатить хидер, чтобы писать просто PIOA_OER = 0xffff. Поиск->замена рулит. Ну просто с одной стороны лень каждый раз писать "приставку" AT91C_BASE_ или *AT91C_, да и код более ляпистый получается, хочется красоты в програмке хоть какой-то :) Регистры же все равно не повторяются, поэтому я не понимаю зачем такую сложность ввели, вот в AVR-ках в этом отношении было просто, в прочем как и с установками флагов в регистрах. Тоже, понапридумывали по 3 регистра, 2 из которых управляют флагами, а результат и текущий статус вообще в 3-ем смотрится. По мне так не очень как то такие перемены. Вот и ищу более простые пути. С другой стороны с установкой флагов меньше мороки. Но стоит ли овчинка выделки ? Изменено 6 ноября, 2008 пользователем Vinterman Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 64 6 ноября, 2008 Опубликовано 6 ноября, 2008 · Жалоба Тоже, понапридумывали по 3 регистра, 2 из которых управляют флагами, а результат и текущий статус вообще в 3-ем смотрится. По мне так не очень как то такие перемены. Вот и ищу более простые пути. С другой стороны с установкой флагов меньше мороки. Но стоит ли овчинка выделки ? В многозадачной системе стоит без вариантов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 6 ноября, 2008 Опубликовано 6 ноября, 2008 · Жалоба В многозадачной системе стоит без вариантов. Возможно вы правы. И пока сам не напорюсь не удостоверюсь в собственном неведении :) А как проще и прозрачнее со стороны "бывалого" обрабатывать прерывания. Структурку накидать можно? :))))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 7 ноября, 2008 Опубликовано 7 ноября, 2008 · Жалоба КУЛ!!! Вчера таки запустил Внутрисхемный отладчик!! Все работает, программа пашет. Правда покаааааа настройки все настроил..... В общем забыл про "линковщик", попарился. Теперь вот следующая трабла возникла, как запрограммировать с помощью Wiggler Флэш память контроллера????? Чтобы не в дебугере проект свой тестить, а уже в независимом не от кого железе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 64 7 ноября, 2008 Опубликовано 7 ноября, 2008 · Жалоба А как проще и прозрачнее со стороны "бывалого" обрабатывать прерывания. Структурку накидать можно? :))))) Есть два варианта - с использоавнием вложенных прерываний и без него. В любом случае ставим загрузку PC из AIC_IVR непосредственно на векторе: 0x18 ldr pc, [pc, #-0xf20] ; IRQ Если не использовать вложения, то дальше все просто (на примере таймера PIT): #define PIT_HZ 1000 #define PIT_PERIOD ((mck + PIT_HZ * 8) / (PIT_HZ * 16)) int main(void) { // Install System interrupt handler AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (u_int)sys_irq_handler; AT91C_BASE_AIC->AIC_IECR = (0x01 << AT91C_ID_SYS); AT91C_BASE_PITC->PITC_PIMR = AT91C_PITC_PITEN | AT91C_PITC_PITIEN | (PIT_PERIOD - 1); } __irq void sys_irq_handler(void) { AT91C_BASE_PITC->PITC_PIMR; ... // Что-то еще делаем ... AT91C_BASE_AIC->AIC_EOICR = 0; } С вложением придется добавить еще один уровень на асме: GET at91sam7x128.inc GET arm.inc ; *************************************************************************** ; * IMPORT sys_irq_handler EXPORT sys_irq_wrapper ; *************************************************************************** ; * AREA code0, CODE, READONLY ; *************************************************************************** ; * sys_irq_wrapper ;- Adjust and save LR_irq mode in IRQ stack sub r14, r14, #0x04 stmfd sp!, {r14} ;- Save SPSR and r0 in IRQ stack mrs r14, SPSR stmfd sp!, {r0, r14} ;- Enable Interrupt and Switch in SYS Mode mrs r14, CPSR bic r14, r14, #I_BIT orr r14, r14, #ARM_MODE_SVC msr CPSR_c, r14 ;- Save scratch/used registers and LR in User Stack stmfd sp!, {r1-r4, r12, r14} bl sys_irq_handler ;- Restore scratch/used registers and LR from User Stack ldmfd sp!, {r1-r4, r12, r14} ;- Disable Interrupt and switch back in IRQ mode mrs r0, CPSR bic r0, r0, #ARM_MODE_SYS orr r0, r0, #I_BIT :OR: ARM_MODE_IRQ msr CPSR_c, r0 ;- Mark the End of Interrupt on the AIC ldr r0, =AT91C_BASE_AIC str r0, [r0, #AIC_EOICR] ;- Restore SPSR_irq and r0 from IRQ stack ldmfd sp!, {r0, r14} msr SPSR_cxsf, r14 ;- Restore ajusted LR_irq from IRQ stack directly in the PC ldmfd sp!, {pc}^ END #define PIT_HZ 1000 #define PIT_PERIOD ((mck + PIT_HZ * 8) / (PIT_HZ * 16)) int main(void) { // Install System interrupt handler AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = PRIOR_SYSTEM; AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (u_int)sys_irq_wrapper; AT91C_BASE_AIC->AIC_IECR = (0x01 << AT91C_ID_SYS); AT91C_BASE_PITC->PITC_PIMR = AT91C_PITC_PITEN | AT91C_PITC_PITIEN | (PIT_PERIOD - 1); } void sys_irq_handler(void) { AT91C_BASE_PITC->PITC_PIMR; ... // Что-то еще делаем ... } Примеры для RealView, для IAR'а придется доработать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 12 ноября, 2008 Опубликовано 12 ноября, 2008 · Жалоба Огромное спасибо за разъяснения! Сегодня разгреб время для дальнейшего освоения контроллера! Буду дальше разбираться !:))) И чтоб я без вас делал? :cheers: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 18 ноября, 2008 Опубликовано 18 ноября, 2008 · Жалоба Замучали меня уже эти прерывания! ПОМОГИТЕ !!! Как в "сях" вставить асмовый код, да еще к тому же и по нужному нам вектору Ведь данную строчку то надо написать: 0x18 ldr pc, [pc, #-0xf20] ; IRQ Я ее пытался написать, а IAR в свою очередь ругается на саму строчку. пишет "Синтаксическая ошибка операнда", но перед этим ругался на "метку" (думал что адрес - это метка), я использовал директиву org. После этого он стал выдавать мне синтаксическую ошибку, что незнает такой команды. Я уже и мытьем и катаньем эти прерывания... А они не сдаются. Помогите победить! Просто не хочу подключать кучу файлов типа cstartup и board, ведь проект то будет не на отладочную плату. К томуже я не очень то силен в том, что написано в асмовском файле стартапника, отчего и не могу доконца сам разобраться что к чему.... Мне надо либо образец, либо книгу нормальную, гдеб правильно были и грамотно расписаны функции, которые приводят к обработке прерываний, либо помощ... Уже многое из периферии попробовал, а вот прерывания так и не могу "осилить"...... :cranky: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 19 ноября, 2008 Опубликовано 19 ноября, 2008 · Жалоба Вроде разобрался с кодом на асме. Компилит сам код без ошибок вышеописанных, но блин, выдаются следующие ошибки: даже когда код на асме урезаю до PROGRAM ?RESET RSEG INTRAMSTART_REMAP RSEG INTRAMEND_REMAP RSEG ICODE:CODE:ROOT(2) CODE32 ; Always ARM mode after reset reset org 0x18 ldr pc,[pc,#-0xF20]; org 0x1c ldr pc,[pc,#-0xF20]; ENDMOD END усе равно ошибка эта вылазит. Как только асмовский файл убиваю, так все тип топ и нормально дебугерется. :( и еще, что означают вот эти строки ? //* open FIQ interrupt AT91F_PIO_CfgPeriph(AT91D_BASE_PIO_SW,AT91B_SW1,0); AT91F_AIC_ConfigureIt ( pAic, AT91C_ID_FIQ, FIQ_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE, FIQ_init_handler); AT91F_AIC_EnableIt (pAic, AT91C_ID_FIQ); Скачал примеры от атмела. плин, черт ногу сломит. Компилю их же пример, ошибка: Fatal Error[e72]: Segment INTRAMEND_REMAP must be defined in a segment definition option (-Z, -b or -P) что это, и где ее исправлять ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 64 19 ноября, 2008 Опубликовано 19 ноября, 2008 · Жалоба Компилит сам код без ошибок вышеописанных, но блин, выдаются следующие ошибки: Ну так добавьте этот самый entry point в стартап: PUBLIC __program_start __program_start: InitReset: что означают вот эти строки ? Эти строки конфигурируют PIO и AIC через бредовую атмеловскую библиотеку. Правильным решением будет изучить самостоятельно архитектуру процессора и никогда не пользоваться AT91F_*. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 19 ноября, 2008 Опубликовано 19 ноября, 2008 · Жалоба Вроде разобрался с кодом на асме. Компилит сам код без ошибок вышеописанных, но блин, выдаются следующие ошибки:А что вас заставило вставлять в проект именно этот файл, именно с таким названием модуля и описывать в нем вектор ресета, который и так есть в библиотеке? Ведь именно на это и ругается линкер, но вы почему-то это предупреждение игнорируете. Для вашей одной единственной команды надо было создать файл с именем вроде irq_handler.s79 и таким содержимым: COMMON INTVEC:CODE:ROOT CODE32; Always ARM mode after reset org 0x1c ldr pc,[pc,#-0xF20]; END Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 19 ноября, 2008 Опубликовано 19 ноября, 2008 (изменено) · Жалоба Ну так добавьте этот самый entry point в стартап: PUBLIC __program_start __program_start: InitReset: Эти строки конфигурируют PIO и AIC через бредовую атмеловскую библиотеку. Правильным решением будет изучить самостоятельно архитектуру процессора и никогда не пользоваться AT91F_*. Сенкс за ответ! :) Архитектуру то я уже изучил, а вот что это за функции, описанные, как оказалось в библиотеке я знать не знал, пока саму оную не посмотрел. Все просто оказалось. Млин, Атмеловские коды написаны мягко говоря через одно место. Вектора обработчиков прерываний, в процессе инициализации в примерах атмела, модифицируются ДВА!!! раза. Каламбур да и только. лишняя перестраховка от ложных срабатываний кристалла. Насколько я разобрался, ругался IAR из-за того, что небыл описан путь в опциях проекта - вкладках препроцесоров для Си и АСМА. Такое может быть? Ибо одно единственное различие между моим кодом и кодом атмеля осталось только в этом :)))) Пойду домой проверять. Спасибо за ответы и советы! :a14: А что вас заставило вставлять в проект именно этот файл, именно с таким названием модуля и описывать в нем вектор ресета, который и так есть в библиотеке? Ведь именно на это и ругается линкер, но вы почему-то это предупреждение игнорируете. Для вашей одной единственной команды надо было создать файл с именем вроде irq_handler.s79 и таким содержимым: COMMON INTVEC:CODE:ROOT CODE32; Always ARM mode after reset org 0x1c ldr pc,[pc,#-0xF20]; END А заставило то, что я знать не знал как правильно код на асме в проекте записать. Теперь благодаря вам, - знаю :) Мне еще много предстоит изучить и сделать ошибок. Примного благодарен! :) Изменено 19 ноября, 2008 пользователем Vinterman Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться