|
Sam7ex256 и UART, Не срабатывает прерывание |
|
|
|
Dec 9 2009, 08:05
|

Участник

Группа: Участник
Сообщений: 22
Регистрация: 26-11-09
Пользователь №: 53 887

|
Добрый день, уважаемые эксперты. Недавно взялся изучать ARM (на плате SAM7EX256). Возникла проблема с прерыванием от UART. Перелопатил примеры и точ то нашел на форуме. Ни в какую не хочет работать. Для компиляции использую IAR 5.40. Может еще какие настройки нужны? Нет ли (как в AVR) какой нибудь комады типа SEI? Вот код: CODE #include <board.h> #include <irq/irq.h> #include <usart/usart.h> #include <pmc/pmc.h> #include "lcd.h"
volatile int uart_count_rx_irq; //volatile int uart_count_rx_sim;
void InitFreq(void) { AT91C_BASE_MC->MC_FMR = AT91C_MC_FWS_1FWS ; AT91C_BASE_WDTC->WDTC_WDMR= AT91C_WDTC_WDDIS; AT91C_BASE_PMC->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x40 <<8) | AT91C_CKGR_MOSCEN )); while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)); AT91C_BASE_PMC->PMC_PLLR = AT91C_CKGR_USBDIV_1 | (16<<8) | (AT91C_CKGR_MUL & (72<<16)) | (AT91C_CKGR_DIV & 14); while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK)); while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 ; while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK ; while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); }
void InitPeriphery(void) { //enable the clock of the PIO AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOA; //enable the clock of the PIO AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOB;
// BUTTON SW1, SW2 AT91C_BASE_PIOB->PIO_ODR |= BIT24 | BIT25; //Configure in Input AT91C_BASE_PIOB->PIO_PER |= BIT24 | BIT25; //Enable PB24
//Joystick AT91C_BASE_PIOB->PIO_ODR |= BIT7 | BIT8 | BIT9 | BIT14 | BIT15; //Configure in Input AT91C_BASE_PIOB->PIO_PER |= BIT7 | BIT8 | BIT9 | BIT14 | BIT15; //Enable PB25 }
char U0ReadChar(void) { while(!(AT91C_BASE_US0->US_CSR & AT91C_US_RXRDY)); return (AT91C_BASE_US0->US_RHR & 0x1FF); }
void U0WriteChar(char sym) { while(!(AT91C_BASE_US0->US_CSR & AT91C_US_TXRDY)); AT91C_BASE_US0->US_THR = sym & 0x1FF; }
void U0_ISR(void) { unsigned int status;
status = AT91C_BASE_US0->US_CSR;
if ((status & AT91C_US_RXBUFF) == AT91C_US_RXRDY) { uart_count_rx_irq++; U0WriteChar(U0ReadChar()); } }
void U0Init(void) { unsigned int mode = AT91C_US_USMODE_NORMAL | AT91C_US_CLKS_CLOCK | AT91C_US_CHRL_8_BITS | AT91C_US_PAR_NONE | AT91C_US_NBSTOP_1_BIT | AT91C_US_CHMODE_NORMAL;
//For UART0 AT91C_BASE_PIOA->PIO_PDR = BIT0 | BIT1 | BIT27 | BIT28; AT91C_BASE_PIOA->PIO_ASR = BIT0 | BIT1 | BIT27 | BIT28; AT91C_BASE_PIOA->PIO_BSR = 0;
// Enable the peripheral clock in the PMC PMC_EnablePeripheral(AT91C_ID_US0);
//Disable Time Guard AT91C_BASE_US0->US_TTGR = 0; // Configure the USART in the desired mode @115200 bauds USART_Configure(AT91C_BASE_US0, mode, 115200, BOARD_MCK); // Configure the RXBUFF interrupt IRQ_ConfigureIT(AT91C_ID_US0, 0, U0_ISR); //Enable USART int AT91C_BASE_US0->US_IER = AT91C_US_RXRDY; //Enable AIC int IRQ_EnableIT(AT91C_ID_US0);
// Enable receiver & transmitter USART_SetTransmitterEnabled(AT91C_BASE_US0, 1); USART_SetReceiverEnabled(AT91C_BASE_US0, 1); }
void main() { InitFreq(); InitPeriphery(); U0Init(); InitSPI(); InitLCD(); Backlight(BKLGHT_LCD_ON); while(1) { //Left SW if(!((AT91C_BASE_PIOB->PIO_PDSR) & BIT24)) { Backlight(BKLGHT_LCD_ON); } //Right SW if(!((AT91C_BASE_PIOB->PIO_PDSR) & BIT25)) { Backlight(BKLGHT_LCD_OFF); } //Joy Center if(!((AT91C_BASE_PIOA->PIO_PDSR) & BIT15)) { char tmp[] = "000"; tmp[2] = uart_count_rx_irq % 10 + '0'; tmp[1] = (uart_count_rx_irq / 10) % 10 + '0'; tmp[0] = (uart_count_rx_irq / 100) % 10 + '0'; LCDPutStr(tmp, 104, 0, LARGE, BLACK, WHITE);
tmp[2] = uart_count_rx_sim % 10 + '0'; tmp[1] = (uart_count_rx_sim / 10) % 10 + '0'; tmp[0] = (uart_count_rx_sim / 100) % 10 + '0'; LCDPutStr(tmp, 88, 0, LARGE, BLACK, WHITE); } // if(AT91C_BASE_US0->US_CSR & AT91C_US_RXRDY) // { // U0WriteChar(U0ReadChar()); // uart_count_rx_sim++; // }
} }
Сообщение отредактировал Brain_ - Dec 9 2009, 08:06
|
|
|
|
|
Dec 9 2009, 14:00
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Во-первых, если у вас возникли проблемы с прерываниями, обязательно прикладывайте к сообщению стартап код, иначе советы давать бесполезно. Далее: Код if ((status & AT91C_US_RXBUFF) == AT91C_US_RXRDY) Это условие не выполнится никогда. Цитата(Brain_ @ Dec 9 2009, 11:05)  Нет ли (как в AVR) какой нибудь комады типа SEI? Код I_BIT EQU 0x80
mrs r0, CPSR bic r0, r0, #I_BIT msr CPSR_c, r0 Код #include <intrinsics.h>
__enable_interrupt();
|
|
|
|
|
Dec 10 2009, 14:13
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(aaarrr @ Dec 9 2009, 16:00)  __enable_interrupt(); Оно то есть, но 1. обычно часто глобальное разрешение прерываний делается в стартапе. 2. CPSR из user mode менять нельзя. автор имел в виду надо ли что-то дополнительно разрешать глобально или не надо в C main, ответ - не надо.
|
|
|
|
|
Dec 10 2009, 15:04
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(defunct @ Dec 10 2009, 17:13)  автор имел в виду надо ли что-то дополнительно разрешать глобально или не надо в C main, ответ - не надо. Смелый ответ. Цитата(DpInRock @ Dec 10 2009, 17:39)  Вообще-то в main прерывания разрешать надо. В main программа заходит обычно с запрещенными прерываниями. И этот тоже. Вообще-то я не зря написал, что бесполезно давать советы, не видя стартапа. Их много разных, порой совершенно маразматических. Не надо заниматься гаданием.
|
|
|
|
|
Dec 10 2009, 17:02
|

Гуру
     
Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515

|
Цитата Нескромный вопрос: а Вы кейл хоть раз видели? Скромно отвечу: и видеть не собираюсь. Хватает ИАР. Тем более что и топикастер о нем спрашивает. Цитата И этот тоже. Раз автор копается в примерах, то не встречал в атмеловских примерах user mode. Вообще ни в одном месте. Да и в иаровских примерах тоже. Подозреваю, что user мод никто не использует. Даже майкрософт. http://www.wasm.ru/article.php?article=securewincearmНе проверял, не знаю. Но нет причин не доверять.
--------------------
On the road again (Canned Heat)
|
|
|
|
|
Dec 10 2009, 17:15
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(DpInRock @ Dec 10 2009, 20:02)  Раз автор копается в примерах, то не встречал в атмеловских примерах user mode. А почему именно атмеловские? Мало ли примеров в интернете. Цитата(DpInRock @ Dec 10 2009, 20:02)  Подозреваю, что user мод никто не использует. Даже майкрософт. Вот кусочек из кейловского примера: Код Mode_USR EQU 0x10
; Enter User Mode and set its Stack Pointer MSR CPSR_c, #Mode_USR IF :DEF:__MICROLIB
EXPORT __initial_sp
ELSE
MOV SP, R0 SUB SL, SP, #USR_Stack_Size
ENDIF
; Enter the C code
IMPORT __main LDR R0, =__main BX R0 ИМХО, господа, ответственнее надо относится к раздаче советов. В частности, не нужно гадать, что там может быть написано в стартапе, если он не приложен к сообщению. И нет такого понятия, как "стандартный стартап", ибо стандарта на стартапы в природе нет.
|
|
|
|
|
Dec 11 2009, 10:35
|

Участник

Группа: Участник
Сообщений: 22
Регистрация: 26-11-09
Пользователь №: 53 887

|
Прошу прощения, за то что 2 дня не появлялся  Что такое sturt up?, где его искать? и в чем его писать? Если можете, дайте ссылку почитать..
|
|
|
|
|
Dec 11 2009, 11:40
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(DpInRock @ Dec 11 2009, 14:29)  Потом оставляете этот стартап для себя на пожизненно. Вредный совет. У этого стартапа отвратнейший обработчик прерываний. Цитата(DpInRock @ Dec 11 2009, 14:29)  При этом sys даже не планируется к использованию... Для всяких абортов стек определяют, а для сиса - нет. SP для SYS и USER вообще-то один.
|
|
|
|
|
Dec 14 2009, 09:03
|

Участник

Группа: Участник
Сообщений: 22
Регистрация: 26-11-09
Пользователь №: 53 887

|
Старт Ап нашел. Добавил прямо тот который был в C:\Program Files\IAR Systems\Embedded Workbench 5.4 Evaluation\arm\examples\Atmel\at91lib\boards\at91sam7x-ek Только вот его добавление ни к каким результатам не привело  Все так же молчание в обработчике прерываний.
|
|
|
|
|
Dec 14 2009, 11:28
|

Участник

Группа: Участник
Сообщений: 22
Регистрация: 26-11-09
Пользователь №: 53 887

|
C удовольствием  CODE /* IAR startup file for AT91SAM7X microcontrollers. */
MODULE ?cstartup
;; Forward declaration of sections. SECTION IRQ_STACK:DATA:NOROOT(2) SECTION CSTACK:DATA:NOROOT(3)
//------------------------------------------------------------------------------ // Headers //------------------------------------------------------------------------------
#define __ASSEMBLY__ #include "board.h"
//------------------------------------------------------------------------------ // Definitions //------------------------------------------------------------------------------
#define ARM_MODE_ABT 0x17 #define ARM_MODE_FIQ 0x11 #define ARM_MODE_IRQ 0x12 #define ARM_MODE_SVC 0x13 #define ARM_MODE_SYS 0x1F
#define I_BIT 0x80 #define F_BIT 0x40
//------------------------------------------------------------------------------ // Startup routine //------------------------------------------------------------------------------
/* Exception vectors */ SECTION .vectors:CODE:NOROOT(2)
PUBLIC resetVector PUBLIC irqHandler
EXTERN Undefined_Handler EXTERN SWI_Handler EXTERN Prefetch_Handler EXTERN Abort_Handler EXTERN FIQ_Handler
ARM
__iar_init$$done: ; The interrupt vector is not needed ; until after copy initialization is done
resetVector: ; All default exception handlers (except reset) are ; defined as weak symbol definitions. ; If a handler is defined by the application it will take precedence. LDR pc, =resetHandler ; Reset LDR pc, Undefined_Addr ; Undefined instructions LDR pc, SWI_Addr ; Software interrupt (SWI/SYS) LDR pc, Prefetch_Addr ; Prefetch abort LDR pc, Abort_Addr ; Data abort B . ; RESERVED LDR pc, =irqHandler ; IRQ LDR pc, FIQ_Addr ; FIQ
Undefined_Addr: DCD Undefined_Handler SWI_Addr: DCD SWI_Handler Prefetch_Addr: DCD Prefetch_Handler Abort_Addr: DCD Abort_Handler FIQ_Addr: DCD FIQ_Handler /* Handles incoming interrupt requests by branching to the corresponding handler, as defined in the AIC. Supports interrupt nesting. */ irqHandler: /* Save interrupt context on the stack to allow nesting */ SUB lr, lr, #4 STMFD sp!, {lr} MRS lr, SPSR STMFD sp!, {r0, lr}
/* Write in the IVR to support Protect Mode */ LDR lr, =AT91C_BASE_AIC LDR r0, [r14, #AIC_IVR] STR lr, [r14, #AIC_IVR]
/* Branch to interrupt handler in Supervisor mode */ MSR CPSR_c, #ARM_MODE_SYS STMFD sp!, {r1-r3, r4, r12, lr} MOV lr, pc BX r0 LDMIA sp!, {r1-r3, r4, r12, lr} MSR CPSR_c, #ARM_MODE_IRQ | I_BIT
/* Acknowledge interrupt */ LDR lr, =AT91C_BASE_AIC STR lr, [r14, #AIC_EOICR]
/* Restore interrupt context and branch back to calling code */ LDMIA sp!, {r0, lr} MSR SPSR_cxsf, lr LDMIA sp!, {pc}^
/* After a reset, execution starts here, the mode is ARM, supervisor with interrupts disabled. Initializes the chip and branches to the main() function. */ SECTION .cstartup:CODE:NOROOT(2)
PUBLIC resetHandler EXTERN LowLevelInit EXTERN ?main REQUIRE resetVector ARM
resetHandler:
/* Set pc to actual code location (i.e. not in remap zone) */ LDR pc, =label
/* Perform low-level initialization of the chip using LowLevelInit() */ label: LDR r0, =LowLevelInit LDR r4, =SFE(CSTACK) MOV sp, r4 MOV lr, pc BX r0
/* Set up the interrupt stack pointer. */ MSR cpsr_c, #ARM_MODE_IRQ | I_BIT | F_BIT ; Change the mode LDR sp, =SFE(IRQ_STACK)
/* Set up the SYS stack pointer. */ MSR cpsr_c, #ARM_MODE_SYS | F_BIT ; Change the mode LDR sp, =SFE(CSTACK)
/* Branch to main() */ LDR r0, =?main MOV lr, pc BX r0
/* Loop indefinitely when program is finished */ loop4: B loop4
END
|
|
|
|
|
Dec 14 2009, 17:02
|

Участник

Группа: Участник
Сообщений: 22
Регистрация: 26-11-09
Пользователь №: 53 887

|
Религия тут не при чем  На таймере тоже пробовал. В main же всю инициализаию и настройку прерываний я реализовываю в отдельных функциях потом из из main вызываю. В данном коде просто для наглядности запихнул прямо в main. Может есть у кого готовый пример (работающий конкрутно для Iar 5.4, заточенный под sam7ex) рализации UART-эхо через прерывания? Буду премного благодарен если скинете на почту. Просто тяжко как-то мне пока после AVR и MSP принимтаься за RISC процессоры
Сообщение отредактировал Brain_ - Dec 14 2009, 17:04
|
|
|
|
|
Dec 14 2009, 17:30
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Brain_ @ Dec 14 2009, 12:03)  Все так же молчание в обработчике прерываний. Во-первых, это - Код if ((status & AT91C_US_RXBUFF) == AT91C_US_RXRDY) - исправили? Во-вторых, как смотрите работу прерываний - по эху?
|
|
|
|
|
Dec 14 2009, 17:52
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Хорошо, передача отдельно работает?
Мне, если честно, лень разбирать правильность вызовов многочисленных "библиотечных" процедур, поэтому проверьте, не должно ли быть написано PMC_EnablePeripheral(1UL << AT91C_ID_US0) вместо PMC_EnablePeripheral(AT91C_ID_US0) и т.п. Еще лучше будет, если вы полностью откажетесь от их использования: вызывать "библиотку" для записи одного регистра, да еще и рискуя, как в приведенном примере, ошибиться - глупо.
P.S. Сейчас, наверное, набегут защитники "атмеловских библиотек". Не слушайте их.
|
|
|
|
|
Dec 14 2009, 18:13
|

Участник

Группа: Участник
Сообщений: 22
Регистрация: 26-11-09
Пользователь №: 53 887

|
Про все ужасы и минусы библиотечных функций я имею представление  Пример с atmelевского сайта (точнее то что было в папке с примерами самого Iar, пока различий не нашел) я пробовал запустить. Но ничего не получилось. Это и навело меня на мысль, что где то подвох, и побудило сюда отписаться. На мелкие ошибки типа PMC_EnablePeripheral(1UL << AT91C_ID_US0) я тоже проверял. не однократно. Завтра еще проверю для уверенности. Передача отдельно работает. Прием отдельно тоже работает (когда я в main пишу цикл ожидания символа и потом его читаю) Не хотят работать именно прерывания. PS Кстати, обязательно писать 1UL вместо 1? в памяти ведь они одинаково выглядят и при логических операциях тоже?
Сообщение отредактировал Brain_ - Dec 14 2009, 18:14
|
|
|
|
|
Dec 15 2009, 09:40
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Согласно вашему startup'у первые (8+5)*4 адреса содержат интересующие адреса. printf выводит результат, как правило, в USART DBG, который можно на любой терминальной программе увидеть. Прочитать таблицу: Код int *pt = (int *)0; int i = 13; while(i--) printf("%08X -> %08X\n", pt, *pt++); Получите: адрес -> содержимое ячейки по этому адресу
|
|
|
|
|
Dec 15 2009, 17:36
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Ну и сидит тут всякая фигня. Уж точно с адреса 0х20 по 0х34 должны сидеть адреса функций обработки соответствующих прерываний. Ну и на сладкое дизассемблированный текст: Код 00000000 180C0603 STMNEDA ip, {r0,r1,r9,r10} 00000004 180C0603 STMNEDA ip, {r0,r1,r9,r10} 00000008 180C0603 STMNEDA ip, {r0,r1,r9,r10} 0000000C 180C0603 STMNEDA ip, {r0,r1,r9,r10} 00000010 180C0603 STMNEDA ip, {r0,r1,r9,r10} 00000014 140A0502 STRNE r0, [r10], #-&502 00000018 140A0502 STRNE r0, [r10], #-&502 0000001C CC663319 STCGTL p3, c3, [r6], #-&64! 00000020 E8F47ABD LDMIA r4!, {r0,r2-r5,r7,r9,r11-lr}^ 00000024 E8F47ABD LDMIA r4!, {r0,r2-r5,r7,r9,r11-lr}^ 00000028 E8F47ABD LDMIA r4!, {r0,r2-r5,r7,r9,r11-lr}^ 0000002C E8F47ABD LDMIA r4!, {r0,r2-r5,r7,r9,r11-lr}^ 00000030 E8F47ABD LDMIA r4!, {r0,r2-r5,r7,r9,r11-lr}^ Вы, кстати, включите генерацию листинга startup-файла. Там увидите правильные коды команд по соответствующим адресам. Адресов функций там не будет, так как их позже подставляет linker, но эти адреса можно найти в map-файле, который можно заставить генерить linker (что очень часто бавает полезно)
|
|
|
|
|
Dec 17 2009, 10:47
|

Участник

Группа: Участник
Сообщений: 22
Регистрация: 26-11-09
Пользователь №: 53 887

|
Приношу свои извинения, по поводу компостирования умов, всем, кто участвовал в обсуждении. Мне удалось переделать пример с RTT под UART. прерывания заработали. Правда не могу понять почему. Все функции и библиотеки которые использовались у в RTT проекте я себе скопировал и добавил. Все настройки проекта проверил. Все один в один. Но пример(переделанный) работает, моя прога - нет  Видимо придется пока пользоваться этим проектом как стартовым  Всем спасибо.
Сообщение отредактировал Brain_ - Dec 17 2009, 10:48
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|