Перейти к содержанию
    

Добрый день, уважаемые эксперты.

Недавно взялся изучать ARM (на плате SAM7EX256). Возникла проблема с прерыванием от UART. Перелопатил примеры и точ то нашел на форуме. Ни в какую не хочет работать.

Для компиляции использую IAR 5.40.

Может еще какие настройки нужны? Нет ли (как в AVR) какой нибудь комады типа SEI?

Вот код:

#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_

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Во-первых, если у вас возникли проблемы с прерываниями, обязательно прикладывайте к сообщению стартап код, иначе советы давать бесполезно.

 

Далее:

if ((status & AT91C_US_RXBUFF) == AT91C_US_RXRDY)

Это условие не выполнится никогда.

 

Нет ли (как в AVR) какой нибудь комады типа SEI?

I_BIT                   EQU     0x80

mrs        r0, CPSR
bic        r0, r0, #I_BIT
msr        CPSR_c, r0

#include <intrinsics.h>

__enable_interrupt();

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

__enable_interrupt();

Оно то есть, но

1. обычно часто глобальное разрешение прерываний делается в стартапе.

2. CPSR из user mode менять нельзя.

 

автор имел в виду надо ли что-то дополнительно разрешать глобально или не надо в C main, ответ - не надо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообще-то в main прерывания разрешать надо. В main программа заходит обычно с запрещенными прерываниями.

 

В iare это __enable_irq();

 

Если стартап стандартный (т.е. хэндлер IRQ находится в нем и вызывает процедуру по адресу из AIC с сохраненнием регистров) - то ничего больше делать не надо, кроме как разрешить irq в main.

 

А если не стандартный - то разрешив прерывания - у вас все подвиснет капитально. И тогда процедуру обработки прерываний надо будет обрамлять атрибутом __irq __arm Name(void)

 

---

ЗЫ НЕ встречал стартапов, которые бы уводили main в user mode. Это самоубийство какое-то.

Изменено пользователем DpInRock

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

автор имел в виду надо ли что-то дополнительно разрешать глобально или не надо в C main, ответ - не надо.

Смелый ответ.

 

Вообще-то в main прерывания разрешать надо. В main программа заходит обычно с запрещенными прерываниями.

И этот тоже.

 

Вообще-то я не зря написал, что бесполезно давать советы, не видя стартапа. Их много разных, порой совершенно маразматических. Не надо заниматься гаданием.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ЗЫ НЕ встречал стартапов, которые бы уводили main в user mode. Это самоубийство какое-то.

Нескромный вопрос: а Вы кейл хоть раз видели?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нескромный вопрос: а Вы кейл хоть раз видели?

Скромно отвечу: и видеть не собираюсь. Хватает ИАР. Тем более что и топикастер о нем спрашивает.

 

И этот тоже.

Раз автор копается в примерах, то не встречал в атмеловских примерах user mode. Вообще ни в одном месте. Да и в иаровских примерах тоже. Подозреваю, что user мод никто не использует. Даже майкрософт.

http://www.wasm.ru/article.php?article=securewincearm

Не проверял, не знаю. Но нет причин не доверять.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Раз автор копается в примерах, то не встречал в атмеловских примерах user mode.

А почему именно атмеловские? Мало ли примеров в интернете.

 

Подозреваю, что 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

 

ИМХО, господа, ответственнее надо относится к раздаче советов. В частности, не нужно гадать, что там может быть написано в стартапе, если он не приложен к сообщению. И нет такого понятия, как "стандартный стартап", ибо стандарта на стартапы в природе нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А почему именно атмеловские?

Ибо очень логично использовать для атмеловского процессора именно атмеловские примеры.

Ну а при использовании ИАРа - иаровские, а не кейловские.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прошу прощения, за то что 2 дня не появлялся :(

 

Что такое sturt up?, где его искать? и в чем его писать?

Если можете, дайте ссылку почитать..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что такое sturt up?, где его искать?

Стартап - ассемблерный файл в составе проекта, содержащий точку входа, код начальной инициализации процессора и (обычно) вектора прерываний. Может называться startup.s, cstartup.s и т.п.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В ИАР, если руками не говорить про стартап, то его и не будет.

 

C:\Program Files\IAR Systems\Embedded Workbench 5.4 Evaluation\arm\examples\Atmel\at91lib\boards\at91sam7x-ek

 

Вот тут с расширением .s

 

И вообще, для начала оттуда берете и пробуете. Потом оставляете этот стартап для себя на пожизненно.

 

Он, кстати, оставляет main в систем режиме.

 

А примеры от NXP (чисто посмотрел у них примеры для usb) - действительно, загоняют кругом в user. При этом sys даже не планируется к использованию... Для всяких абортов стек определяют, а для сиса - нет. И прерывания разрешают. Ибо в стартапе делают все вообще.

Изменено пользователем DpInRock

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Потом оставляете этот стартап для себя на пожизненно.

Вредный совет. У этого стартапа отвратнейший обработчик прерываний.

 

При этом sys даже не планируется к использованию... Для всяких абортов стек определяют, а для сиса - нет.

SP для SYS и USER вообще-то один.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Про отвратнейший - да сойдет. Но для начала - очень нормально. И обработчики прерываний не задумываясь работают.

Да, и вход в сис с разрешенными прерываниями!!!! Типа надо помнить. Я у себя запрещаю.

Только стека на всякиий случай для начала не пожалейте.

 

 

Про один стек - новость. Буду знать.

"Как много нам открытий чудовищных..." (С) Сан Сергеич.

 

---

Для себя я сначала брал стартап в папке PowerPac. Он меня и приучил запрещать прерывания на входе. Токо для sam7x я что-то там не обнаружил стартапа отдельно.

Изменено пользователем DpInRock

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...