|
|
  |
Минимальный код для работы с портом AT91SAM7 |
|
|
|
Nov 6 2008, 09:01
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 3-03-08
Из: г.Томск
Пользователь №: 35 572

|
Всем доброго времени суток! Возникла необходимость перейти с 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!!! Чего не хватает, где упущение, если можно , то образец минимального набора прикрипляемых файлов и кода программы хотелось бы посмотреть для управления ножками контроллера
Сообщение отредактировал Vinterman - Nov 6 2008, 09:07
|
|
|
|
|
Nov 6 2008, 09:16
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Vinterman @ Nov 6 2008, 12:01)  Как и водится, решил "поиграть" ножками для начала. Но перед тем как "зашивать", как водится запустил прогу в эмуляторе. ... Программировать контроллер не программировал. Т.е. запустили в симуляторе, а не под эмуляцией. Бросьте это дело и забудьте про симуляцию периферии на ARM. Цитата(Vinterman @ Nov 6 2008, 12:01)  pPMC->PMC_SCER = 1 << 0; Это явно лишнее, остального достаточно для ногодрыганья.
|
|
|
|
|
Nov 6 2008, 09:39
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 3-03-08
Из: г.Томск
Пользователь №: 35 572

|
Цитата(aaarrr @ Nov 6 2008, 12:16)  Т.е. запустили в симуляторе, а не под эмуляцией. Бросьте это дело и забудьте про симуляцию периферии на ARM. Это явно лишнее, остального достаточно для ногодрыганья. Благодарю за ответ. Рад что опытный глаз сделал ревизию моего кода, теперь я хоть знаю что иду в правильном направлении. Спасибо. Сегодня вечером попробую "подрыгать лапкой". И если успеется, то опробую прерывание от таймера использовать, для тренировки и освоения работы с прерываниями. Ждите развития темы и новых вопросов  Один из всплывших вопросов. Почему я вынужден из-за, на мой взгляд, корявого файла описателя "AT91SAM7S256.h" писать такие строки: volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; pPIO->PIO_OER = 0xFFFF; Есть в нете, более грамотные описатели, чтобы можно было указывать сразу понравившийся регистр, в следующем формате: PIO_OER = 0xFFFF; Или в ручную придется перелопачивать все ?
|
|
|
|
|
Nov 6 2008, 09:47
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Vinterman @ Nov 6 2008, 12:39)  Один из всплывших вопросов. Почему я вынужден из-за, на мой взгляд, корявого файла описателя "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. Поиск->замена рулит.
|
|
|
|
|
Nov 6 2008, 10:19
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 3-03-08
Из: г.Томск
Пользователь №: 35 572

|
Цитата(aaarrr @ Nov 6 2008, 12:47)  А зачем так сложно? Можно написать: AT91C_BASE_PIOA->PIO_OER = 0xffff; или *AT91C_PIOA_OER = 0xffff;
Можно перелопатить хидер, чтобы писать просто PIOA_OER = 0xffff. Поиск->замена рулит. Ну просто с одной стороны лень каждый раз писать "приставку" AT91C_BASE_ или *AT91C_, да и код более ляпистый получается, хочется красоты в програмке хоть какой-то  Регистры же все равно не повторяются, поэтому я не понимаю зачем такую сложность ввели, вот в AVR-ках в этом отношении было просто, в прочем как и с установками флагов в регистрах. Тоже, понапридумывали по 3 регистра, 2 из которых управляют флагами, а результат и текущий статус вообще в 3-ем смотрится. По мне так не очень как то такие перемены. Вот и ищу более простые пути. С другой стороны с установкой флагов меньше мороки. Но стоит ли овчинка выделки ?
Сообщение отредактировал Vinterman - Nov 6 2008, 10:20
|
|
|
|
|
Nov 6 2008, 10:37
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 3-03-08
Из: г.Томск
Пользователь №: 35 572

|
Цитата(aaarrr @ Nov 6 2008, 13:31)  В многозадачной системе стоит без вариантов. Возможно вы правы. И пока сам не напорюсь не удостоверюсь в собственном неведении А как проще и прозрачнее со стороны "бывалого" обрабатывать прерывания. Структурку накидать можно?  ))))
|
|
|
|
|
Nov 7 2008, 10:02
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 3-03-08
Из: г.Томск
Пользователь №: 35 572

|
КУЛ!!! Вчера таки запустил Внутрисхемный отладчик!! Все работает, программа пашет. Правда покаааааа настройки все настроил..... В общем забыл про "линковщик", попарился. Теперь вот следующая трабла возникла, как запрограммировать с помощью Wiggler Флэш память контроллера????? Чтобы не в дебугере проект свой тестить, а уже в независимом не от кого железе.
|
|
|
|
|
Nov 7 2008, 15:06
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Vinterman @ Nov 6 2008, 13:37)  А как проще и прозрачнее со стороны "бывалого" обрабатывать прерывания. Структурку накидать можно?  )))) Есть два варианта - с использоавнием вложенных прерываний и без него. В любом случае ставим загрузку 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'а придется доработать.
|
|
|
|
|
Nov 12 2008, 08:03
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 3-03-08
Из: г.Томск
Пользователь №: 35 572

|
Огромное спасибо за разъяснения! Сегодня разгреб время для дальнейшего освоения контроллера! Буду дальше разбираться !:))) И чтоб я без вас делал?
|
|
|
|
|
Nov 18 2008, 08:12
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 3-03-08
Из: г.Томск
Пользователь №: 35 572

|
Замучали меня уже эти прерывания! ПОМОГИТЕ !!! Как в "сях" вставить асмовый код, да еще к тому же и по нужному нам вектору Ведь данную строчку то надо написать: 0x18 ldr pc, [pc, #-0xf20] ; IRQ[/QUOTE] Я ее пытался написать, а IAR в свою очередь ругается на саму строчку. пишет "Синтаксическая ошибка операнда", но перед этим ругался на "метку" (думал что адрес - это метка), я использовал директиву org. После этого он стал выдавать мне синтаксическую ошибку, что незнает такой команды. Я уже и мытьем и катаньем эти прерывания... А они не сдаются. Помогите победить! Просто не хочу подключать кучу файлов типа cstartup и board, ведь проект то будет не на отладочную плату. К томуже я не очень то силен в том, что написано в асмовском файле стартапника, отчего и не могу доконца сам разобраться что к чему.... Мне надо либо образец, либо книгу нормальную, гдеб правильно были и грамотно расписаны функции, которые приводят к обработке прерываний, либо помощ...  Уже многое из периферии попробовал, а вот прерывания так и не могу "осилить"......
|
|
|
|
|
Nov 19 2008, 03:57
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 3-03-08
Из: г.Томск
Пользователь №: 35 572

|
Вроде разобрался с кодом на асме. Компилит сам код без ошибок вышеописанных, но блин, выдаются следующие ошибки:
даже когда код на асме урезаю до 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) что это, и где ее исправлять ?
|
|
|
|
|
Nov 19 2008, 07:04
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Vinterman @ Nov 19 2008, 06:57)  Компилит сам код без ошибок вышеописанных, но блин, выдаются следующие ошибки: Ну так добавьте этот самый entry point в стартап: Код PUBLIC __program_start
__program_start: InitReset: Цитата(Vinterman @ Nov 19 2008, 06:57)  что означают вот эти строки ? Эти строки конфигурируют PIO и AIC через бредовую атмеловскую библиотеку. Правильным решением будет изучить самостоятельно архитектуру процессора и никогда не пользоваться AT91F_*.
|
|
|
|
|
Nov 19 2008, 09:02
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Vinterman @ Nov 19 2008, 05:57)  Вроде разобрался с кодом на асме. Компилит сам код без ошибок вышеописанных, но блин, выдаются следующие ошибки: А что вас заставило вставлять в проект именно этот файл, именно с таким названием модуля и описывать в нем вектор ресета, который и так есть в библиотеке? Ведь именно на это и ругается линкер, но вы почему-то это предупреждение игнорируете. Для вашей одной единственной команды надо было создать файл с именем вроде irq_handler.s79 и таким содержимым: Код COMMON INTVEC:CODE:ROOT CODE32; Always ARM mode after reset org 0x1c ldr pc,[pc,#-0xF20]; END
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 19 2008, 13:32
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 3-03-08
Из: г.Томск
Пользователь №: 35 572

|
Цитата(aaarrr @ Nov 19 2008, 10:04)  Ну так добавьте этот самый entry point в стартап: Код PUBLIC __program_start
__program_start: InitReset: Эти строки конфигурируют PIO и AIC через бредовую атмеловскую библиотеку. Правильным решением будет изучить самостоятельно архитектуру процессора и никогда не пользоваться AT91F_*. Сенкс за ответ!  Архитектуру то я уже изучил, а вот что это за функции, описанные, как оказалось в библиотеке я знать не знал, пока саму оную не посмотрел. Все просто оказалось. Млин, Атмеловские коды написаны мягко говоря через одно место. Вектора обработчиков прерываний, в процессе инициализации в примерах атмела, модифицируются ДВА!!! раза. Каламбур да и только. лишняя перестраховка от ложных срабатываний кристалла. Насколько я разобрался, ругался IAR из-за того, что небыл описан путь в опциях проекта - вкладках препроцесоров для Си и АСМА. Такое может быть? Ибо одно единственное различие между моим кодом и кодом атмеля осталось только в этом  ))) Пойду домой проверять. Спасибо за ответы и советы!  Цитата(Сергей Борщ @ Nov 19 2008, 12:02)  А что вас заставило вставлять в проект именно этот файл, именно с таким названием модуля и описывать в нем вектор ресета, который и так есть в библиотеке? Ведь именно на это и ругается линкер, но вы почему-то это предупреждение игнорируете. Для вашей одной единственной команды надо было создать файл с именем вроде irq_handler.s79 и таким содержимым: Код COMMON INTVEC:CODE:ROOT CODE32; Always ARM mode after reset org 0x1c ldr pc,[pc,#-0xF20]; END А заставило то, что я знать не знал как правильно код на асме в проекте записать. Теперь благодаря вам, - знаю  Мне еще много предстоит изучить и сделать ошибок. Примного благодарен!
Сообщение отредактировал Vinterman - Nov 19 2008, 13:33
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|