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

    

shumerok

Участник
  • Публикаций

    54
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о shumerok

  • Звание
    Участник
  1. Проблема решилась вводом задержки в 1мкс в цикле опроса флага прерывания.
  2. Побайтный прием организовал. Но вылезла другая проблема. В дебаге и через RUN все работает. Зашиваю релиз - не работает. Процессор в релизе крутится, но данные не принимает. Новый код: CODE /* * code.c * * Created on: 04.12.2017 * Author: shumer */ #include <stdio.h> #include "xparameters.h" #include "xil_cache.h" #include "xbasic_types.h" #include "xtmrctr.h" #include "xuartlite.h" #include "xintc.h" #include "xil_exception.h" #define UARTRS_ID XPAR_UARTLITE_1_DEVICE_ID #define UARTRS_ESP XPAR_UARTLITE_2_DEVICE_ID #define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID #define UARTLITE_INT_IRQ_ID XPAR_INTC_0_UARTLITE_2_VEC_ID #define TMR_ID XPAR_TMRCTR_0_DEVICE_ID #define A 65 #define T 84 #define PLUS 43 #define C 67 #define I 73 #define P 80 #define M 77 #define U 85 #define X 88 #define S 83 #define E 69 #define R 82 #define V 86 #define RAVNO 61 #define ZPT 44 #define TEST_BUFFER_SIZE 1 // Function prototypes void SendHandler(void *CallBackRef, unsigned int EventData); void RecvHandler(void *CallBackRef, unsigned int EventData); int SetupInterruptSystem(XUartLite *UartLitePtr); void delay_us(Xuint32 Vremay); void delay_ms(Xuint32 Vremay); XUartLite UartLiteESP; XUartLite UartLiteRS; XIntc InterruptController; XTmrCtr Time; u8 SendBuffer[4] = {A,T,13,10}; u8 ReceiveBuffer[TEST_BUFFER_SIZE] = {0}; u8 SendBufferRS[6] = {S,E,R,V,13,10}; static volatile int TotalReceivedCount; static volatile int TotalSentCount; int flag = 0; unsigned int RecvByte; unsigned int SendByte; int Count = 0; int main() { int Status; int Index; int flagSend = 0; XTmrCtr_Initialize(&Time, TMR_ID); XTmrCtr_SetOptions(&Time, 0, XTC_DOWN_COUNT_OPTION); Status = XUartLite_Initialize(&UartLiteESP,UARTRS_ESP); if(Status != XST_SUCCESS){ return XST_FAILURE; } Status = XUartLite_Initialize(&UartLiteRS,UARTRS_ID); if(Status != XST_SUCCESS){ return XST_FAILURE; } Status = SetupInterruptSystem(&UartLiteESP); if (Status != XST_SUCCESS) { return XST_FAILURE; } XUartLite_SetSendHandler(&UartLiteESP, SendHandler, &UartLiteESP); XUartLite_SetRecvHandler(&UartLiteESP, RecvHandler, &UartLiteESP); XUartLite_EnableInterrupt(&UartLiteESP); delay_ms(1000); XIntc_Acknowledge(&InterruptController, UARTLITE_INT_IRQ_ID); Index = 0; XUartLite_Send(&UartLiteESP, SendBuffer, 4); while(1){ if(flag == 1){ SendBufferRS[0] = ReceiveBuffer[0]; XUartLite_Send(&UartLiteRS, SendBufferRS, 1); /*if(flagSend != 1){ ++Index; } else{ Index = 0; flagSend = 0; }*/ TotalReceivedCount = 0; flag = 0; } } return(0); } void SendHandler(void *CallBackRef, unsigned int EventData) { TotalSentCount = EventData; XIntc_Acknowledge(&InterruptController, UARTLITE_INT_IRQ_ID); } void RecvHandler(void *CallBackRef, unsigned int EventData) { TotalReceivedCount = EventData; flag = 1; //++Count; XUartLite_Recv(&UartLiteESP, ReceiveBuffer, 1); XIntc_Acknowledge(&InterruptController, UARTLITE_INT_IRQ_ID); } void delay_ms(Xuint32 Vremay) { XTmrCtr_SetResetValue(&Time, 0, Vremay * 50000); XTmrCtr_Start(&Time, 0); while(!(XTmrCtr_IsExpired(&Time, 0))){} XTmrCtr_Stop(&Time, 0); } void delay_us(Xuint32 Vremay) { XTmrCtr_SetResetValue(&Time, 0, Vremay * 50); XTmrCtr_Start(&Time, 0); while(!(XTmrCtr_IsExpired(&Time, 0))){} XTmrCtr_Stop(&Time, 0); } int SetupInterruptSystem(XUartLite *UartLitePtr) { int Status; /* * Initialize the interrupt controller driver so that it is ready to * use. */ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect a device driver handler that will be called when an interrupt * for the device occurs, the device driver handler performs the * specific interrupt processing for the device. */ Status = XIntc_Connect(&InterruptController, UARTLITE_INT_IRQ_ID, (XInterruptHandler)XUartLite_InterruptHandler, (void*)UartLitePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Start the interrupt controller such that interrupts are enabled for * all devices that cause interrupts, specific real mode so that * the UartLite can cause interrupts through the interrupt controller. */ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Enable the interrupt for the UartLite device. */ XIntc_Enable(&InterruptController, UARTLITE_INT_IRQ_ID); /* * Initialize the exception table. */ Xil_ExceptionInit(); /* * Register the interrupt controller handler with the exception table. */ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XIntc_InterruptHandler, &InterruptController); /* * Enable exceptions. */ Xil_ExceptionEnable(); return XST_SUCCESS; } Подозреваю, что есть разница в скорости работы проца в дебаге и релизе. Может кто сталкивался с подобным? Буду благодарен за любую помощь.
  3. Цитата(alexadmin @ Apr 28 2018, 14:11) Принимать по одному байту, складывать в буфер, выходить из прерывания, ждать следующего прерывания.Спасибо попробую так. Цитата(AVR @ Apr 28 2018, 14:15) Я уже давно с микробом не возился, могу не помнить что-то, но где в RecvHandler сброс флага прерывания? Вроде это руками надо делать, разве нет? Или оно прям виснет в этом обработчике? Так оно и должно там сидеть пока все 6 байт не скушает. Надо по 1 принимать, как правильно выше написали. Виснет пока не вычитает буфер. Если принимать по одному, то действительно надо сбрасывать флаг.
  4. Прошу прощения. Сам дурак. Не те символы в ASCII отправлял. Есть дополнительный вопрос: как в режиме прерывания принимать произвольное кол-во байт (неизвестно заранее кол-во). У меня выход из прерывания не происходит, пока буфер не заполнится.
  5. Добрый день уважаемые форумчане. В моем проекте два UARTа. Один работает по прерыванию с внешним модулем, второй только в режиме передачи выводит информацию на терминал ноута. Внешний модуль ESP8266. Я передаю ему команду "AT" и должен получить в ответ "OK". А я получаю ту же команду, что отправляю. Хотя ESP точно не может отправить обратно ту же команду. Получается, что в приемный буфер попадают данные из передающего. Проект собран в ISE. Код привожу ниже: CODE#include <stdio.h> #include "xparameters.h" #include "xil_cache.h" #include "xbasic_types.h" #include "xgpio.h" #include "xil_printf.h" #include "xuartlite.h" #include "xintc.h" #include "xil_exception.h" #include "xtmrctr.h" #define UART_ESP XPAR_UARTLITE_1_DEVICE_ID #define UART_RS232 XPAR_UARTLITE_0_DEVICE_ID #define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID #define UARTLITE_INT_IRQ_ID XPAR_INTC_0_UARTLITE_1_VEC_ID #define LED_ID XPAR_GPIO_0_DEVICE_ID #define TMR_ID XPAR_TMRCTR_0_DEVICE_ID #define TEST_BUFFER_SIZE 6 // Function prototypes void SendHandler(void *CallBackRef, unsigned int EventData); void RecvHandler(void *CallBackRef, unsigned int EventData); int SetupInterruptSystem(XUartLite *UartLitePtr); void delay_us(Xuint32 Vremay); void delay_ms(Xuint32 Vremay); XUartLite UartLiteESP; XUartLite UartLiteRS; XIntc InterruptController; XGpio LedTest; XTmrCtr Time; u8 SendBuffer[6] = {65, 84, 92, 114, 92, 110}; u8 ReceiveBuffer[TEST_BUFFER_SIZE]; u8 TotalReceivedCount; u8 TotalSentCount; int main() { int Status; int Index; XTmrCtr_Initialize(&Time, TMR_ID); XTmrCtr_SetOptions(&Time, 0, XTC_DOWN_COUNT_OPTION); delay_ms(1000); delay_ms(1000); for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) { ReceiveBuffer[Index] = 0; } Status = XUartLite_Initialize(&UartLiteESP,UART_ESP); if(Status != XST_SUCCESS){ return XST_FAILURE; } Status = XUartLite_Initialize(&UartLiteRS,UART_RS232); if(Status == XST_SUCCESS) { print("UART Init OK\r\n"); } Status = XGpio_Initialize(&LedTest, LED_ID); if (Status == XST_SUCCESS) { print(" Initialize GPIO OK\r\n"); } Status = SetupInterruptSystem(&UartLiteESP); if (Status == XST_SUCCESS) { print("Setup INT OK\r\n"); } XUartLite_SetSendHandler(&UartLiteESP, SendHandler, &UartLiteESP); XUartLite_SetRecvHandler(&UartLiteESP, RecvHandler, &UartLiteESP); //XUartLite_ResetFifos(&UartLiteESP); XUartLite_Recv(&UartLiteESP, ReceiveBuffer, TEST_BUFFER_SIZE); XUartLite_EnableInterrupt(&UartLiteESP); XUartLite_Send(&UartLiteESP, SendBuffer, 6); delay_ms(1); if (TotalSentCount == 6){ TotalSentCount = 0; print("Send OK\r\n"); } while(1){ if (TotalReceivedCount != 0) { print("Recive"); for (Index = 0; Index < TotalReceivedCount; Index++) { xil_printf(" %c", ReceiveBuffer[Index]); } TotalReceivedCount = 0; } } return(0); } void SendHandler(void *CallBackRef, unsigned int EventData) { TotalSentCount = EventData; XUartLite_ResetFifos(&UartLiteESP); } void RecvHandler(void *CallBackRef, unsigned int EventData) { TotalReceivedCount = EventData; XUartLite_Recv(&UartLiteESP, ReceiveBuffer, TEST_BUFFER_SIZE); } void delay_ms(Xuint32 Vremay) { XTmrCtr_SetResetValue(&Time, 0, Vremay * 50000); XTmrCtr_Start(&Time, 0); while(!(XTmrCtr_IsExpired(&Time, 0))){} XTmrCtr_Stop(&Time, 0); } void delay_us(Xuint32 Vremay) { XTmrCtr_SetResetValue(&Time, 0, Vremay * 50); XTmrCtr_Start(&Time, 0); while(!(XTmrCtr_IsExpired(&Time, 0))){} XTmrCtr_Stop(&Time, 0); } int SetupInterruptSystem(XUartLite *UartLitePtr) { int Status; /* * Initialize the interrupt controller driver so that it is ready to * use. */ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect a device driver handler that will be called when an interrupt * for the device occurs, the device driver handler performs the * specific interrupt processing for the device. */ Status = XIntc_Connect(&InterruptController, UARTLITE_INT_IRQ_ID, (XInterruptHandler)XUartLite_InterruptHandler, (void*)UartLitePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Start the interrupt controller such that interrupts are enabled for * all devices that cause interrupts, specific real mode so that * the UartLite can cause interrupts through the interrupt controller. */ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Enable the interrupt for the UartLite device. */ XIntc_Enable(&InterruptController, UARTLITE_INT_IRQ_ID); /* * Initialize the exception table. */ Xil_ExceptionInit(); /* * Register the interrupt controller handler with the exception table. */ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XIntc_InterruptHandler, &InterruptController); /* * Enable exceptions. */ Xil_ExceptionEnable(); return XST_SUCCESS; } Помогите кто чем может).
  6. Благодарю. Кстати, нашел описание от avnet. Там написано, что можно использовать bootloader от parallel flash. Для итого подключается библиотека xilif и команды работы с памятью в bootloadere заменяются на spi-ные.
  7. Добрый день. Имеется стартовый набор Spartan-3e Starter Kit. На плате имеется кристалл XC3S500E, Platform Flash, SPI Flash, Parallel NOR Flash, DDR SDRAM. Работаю с Microblaze. Шина PLB (AXI не поддерживается). Хочу хранить конфигурационные данные + программу во внешней памяти с последующей загрузкой программы в DDR. Зашел в тупик. Общий алгоритм, как я понял, следующий: прошивка состоит из bit-файла аппаратной платформы, bmm-файла блочной памяти и elf-файла загрузчика (bootloader), srec-файла основной программы (располагается по определенному адресу, указываемому в blconfig.h). Проблемы в следующем: 1. Попытка использовать SPI Flash. Используется контроллер XPS SPI. При данном подходе SDK автоматически не формирует файл загрузчика. 2. Попытка использовать Parallel Flash. С помощью SDK автоматом формируется файл загрузчика, в blconfig.h правится начальный адрес расположения SREC-файла. С помощью data2mem формирую новый bit-файл из старого bit, bmm и elf загрузчика (команда data2mem -bm my.bmm -bd code.elf -bt my.bit -o b new.bit). Далее в IMPACT генерирую PROM файл и добавляю в него SREC. Получаю mcs-файл, включающий в себя все, что нужно. Дальше тупик. Как прошить Parallel Flash? Ни по JTAG ни через кристалл она не доступна. 3. Можно ли использовать сформированный для Parallel Flash загрузчик для извлечения данных из SPI Flash? Надо ли в нем что-то менять? 4. И еще вопрос по Linker Script. Что должно стоять в разделе Section to Memory Region Mapping? Начальный адрес локальной шины, flash или DDR? Благодарю за любую помощь.
  8. В общем, завел сигнал с выхода проца на вход и подавал инвертирующийся с интервалом 5 сек сигнал. Контроллер прерывания срабатывает по фронту и по спаду. По поводу накопления прерываний в контроллере пока не скажу, надо создавать проект в ISE и там генерировать прерывания. Прерывания действительно ставятся в очередь даже если стоит запрет. После разрешения прерывания происходит обработка следующего в очереди.
  9. Цитата(iosifk @ Dec 8 2017, 17:35) Я не знаю как именно сделан контроллер прерываний в Микроблэйзе. Просто в данной ситуации у меня другой подход. Есть сигнал с дребезгом - ставлю фильтр. Десяток триггеров от многих тысяч роли не играет. Убираю дребезг в любом случае. На все медленные водные фронты. И не имею головной боли с "непонятками". Просто размениваю десять триггеров на десять дней работы над проектом, требуемых для разгадывания "непоняток" ... Если бы я делал какой-то проект, то не заморачивался бы и поставил фильтр. Но на данный момент я просто изучаю процессор и все, что к нему прилагается.
  10. Цитата(alexadmin @ Dec 8 2017, 17:14) Вряд ли там в контроллере копится очередь прерываний. Сработало прерывание, попали в обработчик, остановились. Переключатель там дальше "звенит", но этого никто не видит - признак прерывания так и висит. Пошли по шагам, сбросили прерывание, разрешили заново - в это время уже никакого дребезга нет. Не так? В понедельник проверю чистым сигналом с внутренней логики
  11. Цитата(iosifk @ Dec 8 2017, 17:51) А причем здесь это? У переключателя дребезг - милисекунды. У контроллера прерываний срабатывание за несколько тактов в десятки наносекунд... За этот период в милисекунды он найдет себе на кусочке импульса и "фронт" и "уровень" и вообще что угодно... Притом, что я работаю в дебаге и после срабатывания прерывания я выставляю его запрет. Причем тут дребезг? К моменту разрешения нового прерывания могут пройти десятки секунд.
  12. Цитата(iosifk @ Dec 8 2017, 17:37) Либо сделайте цифровой фильтр после переключателя, либо ловите прерывания от приемника uart. Клацнете на хосте - получите точно одно прерывание... Просто потом все равно приемник на прерывание повесите, так почему бы не сейчас? Ну и сделайте счетчик этих запросов и хоть 3 разряда выведите на светодиоды. для начала поклацаете на хосте, увидите, что счетчик шевелится. Видно так и придется делать. Просто я думал, что контроллер можно настроить на срабатывание по фронту либо по спаду.
  13. Цитата(Alex77 @ Dec 8 2017, 17:18) "дип-переключателя" имеют славную традицию "звенеть" - как следствие куча сигналов прерываний. Я тестирую в дебаге пошагово. В регистрах контроллера все устанавливается и сбрасывается правильно. Дребезг не прокатывает. Программа крутится в бесконечном цикле. Переключаюсь, допустим, с 0 в 1 - срабатывает прерывание. Далее пошагово иду иду по программе до возврата к бесконечному циклу. Опять программа крутится, пока не переключусь с 1 в 0. И так по кругу. Он точно срабатывает по обоим фронтам. Вот я и не знаю дело в контроллере или это славный софт от Xilinx.
  14. Добрый день. Работаю с прерываниями в microblaze на отладочнике Spartan3e. Прерывания формирую от дип-переключателя на плате. Подтверждение прерывания вывожу через uart на ноут. Проблема в следующем: прерывания происходят и по фронту и по спаду. Я так понимаю, что контроллеру без разницы. Он реагирует только на изменение состояния?
  15. Цитата(Alex77 @ Nov 25 2017, 02:36) Все регистры отображаются на память, а содержимое памяти можно вывести в окошко просмотра. С версии 13.1 "поломали" моделирование в моделсиме спартана3е+микроблаз+программа в браме. Когда починили и если вообще починили я не знаю. Спасибо за инфу, буду пробовать.