Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Минимальный код для работы с портом AT91SAM7
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Vinterman
Всем доброго времени суток! Возникла необходимость перейти с AVR на ARM-ы. Вот тут сразу незадачка вышла. Прочитал, пересмотрел, перелопатил достаточно большое количество примеров программ, литературы (Бедного редькина и Англ даташит). Купил отладочную платку, SAM7-P64, Wiggler программаторик. "Стянул" IAR с интернета, "вылечил" его и приступил к работе. Для начала решил определиться, какой же минимум подключаемых файлов необходим, ибо все примеры пестрят ТАКИМ их количеством, что порой черт ногу сломит.
Вроде подразобрался, написал первую прогу и тут же сел в лужу wacko.gif

Как и водится, решил "поиграть" ножками для начала. Но перед тем как "зашивать", как водится запустил прогу в эмуляторе.
Эмулятор работает, прога на первый взгляд выполняется. НО!!!! В регистре PMC_SCSR после сброса (Выполнение программы только начинается) ВСЕ НУЛИ!! Когда флаг PCK (состояние тактирования процессора) должен быть установлен! И многие остальные регистры, так же не выходят на свое первоначальное состояние.
После выполнения записи в регистр PIO_SODR, как я полагаю, должны установиться соответствующие биты и в регистре PIO_ODSR. (а в PIO_SODR сброситься в окне эмулятора ????) Этого не происходит!!! Что за ерунда? Что я не правильно делаю? То же самое происходит и с остальными регистрами. Скажем при установки PIO_OER, не меняется PIO_OSR.... Программировать контроллер не программировал. Думал может надо разрешить тактирование PIO и процессора, дописал соответствующие команды, нифига. Пробовал записывать регистры состояния в отдельный регистр (считывал), думал может тут баг, ведь вроде они для чтения, но умом то понимал, что блин эмулятор должен показывать, как и ожидалось, ничего не произошло smile.gif считались НУЛИ smile.gif

Вот пример программы: (прошу не критиковать код ибо все получилось в результате безрезультатных попыток на скорую руку запустить эмулятор из имеющихся под рукой программ)

// *******************************************************
// 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!!!
Чего не хватает, где упущение, если можно , то образец минимального набора прикрипляемых файлов и кода программы хотелось бы посмотреть для управления ножками контроллера
aaarrr
Цитата(Vinterman @ Nov 6 2008, 12:01) *
Как и водится, решил "поиграть" ножками для начала. Но перед тем как "зашивать", как водится запустил прогу в эмуляторе.
...
Программировать контроллер не программировал.

Т.е. запустили в симуляторе, а не под эмуляцией. Бросьте это дело и забудьте про симуляцию периферии на ARM.


Цитата(Vinterman @ Nov 6 2008, 12:01) *
pPMC->PMC_SCER = 1 << 0;

Это явно лишнее, остального достаточно для ногодрыганья.
Vinterman
Цитата(aaarrr @ Nov 6 2008, 12:16) *
Т.е. запустили в симуляторе, а не под эмуляцией. Бросьте это дело и забудьте про симуляцию периферии на ARM.
Это явно лишнее, остального достаточно для ногодрыганья.


Благодарю за ответ. Рад что опытный глаз сделал ревизию моего кода, теперь я хоть знаю что иду в правильном направлении. Спасибо.

Сегодня вечером попробую "подрыгать лапкой". И если успеется, то опробую прерывание от таймера использовать, для тренировки и освоения работы с прерываниями. Ждите развития темы и новых вопросов smile.gif

Один из всплывших вопросов. Почему я вынужден из-за, на мой взгляд, корявого файла описателя "AT91SAM7S256.h" писать такие строки:

volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA;
pPIO->PIO_OER = 0xFFFF;

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

PIO_OER = 0xFFFF;

Или в ручную придется перелопачивать все ?
aaarrr
Цитата(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. Поиск->замена рулит.
Vinterman
Цитата(aaarrr @ Nov 6 2008, 12:47) *
А зачем так сложно? Можно написать:
AT91C_BASE_PIOA->PIO_OER = 0xffff;
или
*AT91C_PIOA_OER = 0xffff;

Можно перелопатить хидер, чтобы писать просто PIOA_OER = 0xffff. Поиск->замена рулит.


Ну просто с одной стороны лень каждый раз писать "приставку" AT91C_BASE_ или *AT91C_, да и код более ляпистый получается, хочется красоты в програмке хоть какой-то smile.gif Регистры же все равно не повторяются, поэтому я не понимаю зачем такую сложность ввели, вот в AVR-ках в этом отношении было просто, в прочем как и с установками флагов в регистрах. Тоже, понапридумывали по 3 регистра, 2 из которых управляют флагами, а результат и текущий статус вообще в 3-ем смотрится. По мне так не очень как то такие перемены. Вот и ищу более простые пути. С другой стороны с установкой флагов меньше мороки. Но стоит ли овчинка выделки ?
aaarrr
Цитата(Vinterman @ Nov 6 2008, 13:19) *
Тоже, понапридумывали по 3 регистра, 2 из которых управляют флагами, а результат и текущий статус вообще в 3-ем смотрится. По мне так не очень как то такие перемены. Вот и ищу более простые пути. С другой стороны с установкой флагов меньше мороки. Но стоит ли овчинка выделки ?

В многозадачной системе стоит без вариантов.
Vinterman
Цитата(aaarrr @ Nov 6 2008, 13:31) *
В многозадачной системе стоит без вариантов.


Возможно вы правы. И пока сам не напорюсь не удостоверюсь в собственном неведении smile.gif
А как проще и прозрачнее со стороны "бывалого" обрабатывать прерывания. Структурку накидать можно? smile.gif))))
Vinterman
КУЛ!!! Вчера таки запустил Внутрисхемный отладчик!! Все работает, программа пашет. Правда покаааааа настройки все настроил..... В общем забыл про "линковщик", попарился.
Теперь вот следующая трабла возникла, как запрограммировать с помощью Wiggler Флэш память контроллера????? Чтобы не в дебугере проект свой тестить, а уже в независимом не от кого железе.
aaarrr
Цитата(Vinterman @ Nov 6 2008, 13:37) *
А как проще и прозрачнее со стороны "бывалого" обрабатывать прерывания. Структурку накидать можно? smile.gif))))

Есть два варианта - с использоавнием вложенных прерываний и без него.

В любом случае ставим загрузку 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
Огромное спасибо за разъяснения! Сегодня разгреб время для дальнейшего освоения контроллера! Буду дальше разбираться !:)))
И чтоб я без вас делал?
cheers.gif
Vinterman
Замучали меня уже эти прерывания! ПОМОГИТЕ !!!
Как в "сях" вставить асмовый код, да еще к тому же и по нужному нам вектору
Ведь данную строчку то надо написать:
0x18 ldr pc, [pc, #-0xf20] ; IRQ[/QUOTE]

Я ее пытался написать, а IAR в свою очередь ругается на саму строчку. пишет "Синтаксическая ошибка операнда", но перед этим ругался на "метку" (думал что адрес - это метка), я использовал директиву org. После этого он стал выдавать мне синтаксическую ошибку, что незнает такой команды. Я уже и мытьем и катаньем эти прерывания... А они не сдаются. Помогите победить! Просто не хочу подключать кучу файлов типа cstartup и board, ведь проект то будет не на отладочную плату. К томуже я не очень то силен в том, что написано в асмовском файле стартапника, отчего и не могу доконца сам разобраться что к чему....
Мне надо либо образец, либо книгу нормальную, гдеб правильно были и грамотно расписаны функции, которые приводят к обработке прерываний, либо помощ... help.gif

Уже многое из периферии попробовал, а вот прерывания так и не могу "осилить"...... cranky.gif
Vinterman
Вроде разобрался с кодом на асме. Компилит сам код без ошибок вышеописанных, но блин, выдаются следующие ошибки:
Нажмите для просмотра прикрепленного файла
даже когда код на асме урезаю до

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

усе равно ошибка эта вылазит. Как только асмовский файл убиваю, так все тип топ и нормально дебугерется. sad.gif
help.gif



и еще, что означают вот эти строки ?

//* 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
Цитата(Vinterman @ Nov 19 2008, 06:57) *
Компилит сам код без ошибок вышеописанных, но блин, выдаются следующие ошибки:

Ну так добавьте этот самый entry point в стартап:

Код
    PUBLIC __program_start

__program_start:
InitReset:


Цитата(Vinterman @ Nov 19 2008, 06:57) *
что означают вот эти строки ?

Эти строки конфигурируют PIO и AIC через бредовую атмеловскую библиотеку.
Правильным решением будет изучить самостоятельно архитектуру процессора и
никогда не пользоваться AT91F_*.
Сергей Борщ
Цитата(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
Vinterman
Цитата(aaarrr @ Nov 19 2008, 10:04) *
Ну так добавьте этот самый entry point в стартап:

Код
    PUBLIC __program_start

__program_start:
InitReset:

Эти строки конфигурируют PIO и AIC через бредовую атмеловскую библиотеку.
Правильным решением будет изучить самостоятельно архитектуру процессора и
никогда не пользоваться AT91F_*.


Сенкс за ответ! smile.gif Архитектуру то я уже изучил, а вот что это за функции, описанные, как оказалось в библиотеке я знать не знал, пока саму оную не посмотрел. Все просто оказалось. Млин, Атмеловские коды написаны мягко говоря через одно место. Вектора обработчиков прерываний, в процессе инициализации в примерах атмела, модифицируются ДВА!!! раза. Каламбур да и только. лишняя перестраховка от ложных срабатываний кристалла.

Насколько я разобрался, ругался IAR из-за того, что небыл описан путь в опциях проекта - вкладках препроцесоров для Си и АСМА. Такое может быть? Ибо одно единственное различие между моим кодом и кодом атмеля осталось только в этом smile.gif))) Пойду домой проверять. Спасибо за ответы и советы! a14.gif

Цитата(Сергей Борщ @ 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



А заставило то, что я знать не знал как правильно код на асме в проекте записать. Теперь благодаря вам, - знаю smile.gif Мне еще много предстоит изучить и сделать ошибок. Примного благодарен! smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.