Dreamer_0x01
Участник-
Постов
52 -
Зарегистрирован
-
Посещение
Репутация
0 ОбычныйИнформация о Dreamer_0x01
-
Звание
Участник
- День рождения 03.01.1980
Контакты
-
Сайт
Array
-
ICQ
Array
Информация
-
Город
Array
Посетители профиля
-
Здравствуйте. Разбираюсь с устройтвом, собранном на основе STPM32 (https://www.st.com/en/data-converters/stpm32.html), пишу программу для конфигурирования и получения данных. Запутался с регистрами, в которых сохраняются RMS-значения тока и мощности - не очень понимаю, на что их нужно домножать. Точнее, понимаю, что значения с них считываю вдвое и вчетверо меньшие, чем должны быть, но запутался в регистрах и коэффициентах усиления. Может, кто-то работал вживую с этой микросхемой и сможет несколько подсказок дать? Также есть вопросы по протоколу обмена, почему-то устройство стабильно работает, если считывать информацию в виде единого блока регистров (как это делает их GUI-утилита от производителя), и не стабильно, если запрашивать регистры по отдельности. Спасибо.
-
Reinvoke ISP, LPC2388
Dreamer_0x01 ответил Dreamer_0x01 тема в ARM
Читал. Вычитал, что загрузчик использует управление протоколом XON/XOFF. Но в этом случае меня смущает, зачем ваша программа при запуске делает вот это? Или я что-то опять не дочитал? Если так, просьба ткнуть носом в нужное место. Если это так, как лучше ити сбои найти? В проводах все нормально, так как при ресете работает и штатный прошиватель, и пересылка данных из моей программы, причем на самых разных, больших и маленьких скоростях. Есть, правда, еще одно НО - СОМ-порт у меня не честный, а в виде usb-схемки на контроллере Silicon Labs CP2103. И там могут быть достаточно большие задержки между соседними байтами, так как у нее есть свои внутренние буферы. -
Reinvoke ISP, LPC2388
Dreamer_0x01 ответил Dreamer_0x01 тема в ARM
Да уж, попадалово... Анализирую ситуацию - почему-то всегда успешно проходит автобод, запрос версии загрузчика и т.д. Даже "портить" программу получается. Проблемы возникают именно на стадии записи во флеш. Подумал вот что. Каким образом программа-прошиватель ожидает ответ от процессора во время такой команды? По таймауту, или по состоянии линии CTS/RTS. Дело в том, что у меня эти линии не подключены, и можно предположить, что они используются при работе прошивателя. Однако, все же странно, почему в случае запуска сразу при включении запись флеша проходит нормально. Я его использую для порта 2, так как для портов 0 и 1 в инклюдах соответствующие макросы есть, а для номеров 2 и выше - только FIOXXX. -
Reinvoke ISP, LPC2388
Dreamer_0x01 ответил Dreamer_0x01 тема в ARM
Переделал почти как вы сказали (почти - потому что процессор, инклюды и макросы в них у меня другие.) Что-то не входит в загрузчик (или входит, но автобод не проходит)... Сделал так: typedef void ( * RSTFN)(); RSTFN rstfn = (RSTFN)0; //................................................................................ ....... VICINTENCLEAR = 0XFFFFFFFF; while( (U0LSR & LSR_TEMT) == 0 ); temp = 0x00000000; VICINTSELECT = temp; for( i=0, k=VICVECTADDR0; i<= 31; i++, k += 4 ) k = temp; PINSEL0 = 0; //all to gpio PINSEL4 = 0; //all to gpio // Select P2.10 as an output and (RXD0)P0.3 //настраиваем все на вход, как при ресете IO0DIR = 0; IO0DIR |= 1 << 2; //txd - p0.2 //настраиваем P2.10 на выход и сбрасываем его в 0. FIO2DIR = 1 << 10; FIO2CLR = 1 << 10; temp = 0; // Turn off the FIFO's and clear the buffers. U0FCR = temp; // Disconnecting the PLL PLLCON = temp; PLLFEED = 0xAA; PLLFEED = 0x55; // MAM Disable; MAMCR = 0;//MAM_MODE_OFF; // Set the VPB divider to 1/4 if your application changes the VPBDIV value. // The bootloader is hard-coded to use the reset value of VPBDIV register CCLKCFG = temp; // Restore reset state of Timer1 T1PR = temp; T1MCR = temp; T1CCR = temp; MEMMAP = 0x00; //... и пошли на нулевой адрес rstfn(); -
Reinvoke ISP, LPC2388
Dreamer_0x01 ответил Dreamer_0x01 тема в ARM
Пока хороших мыслей в голову не приходит. Приходят плохие ;) Попробую зайти с другой стороны. Ведь после передергивания питания прошивка работает. Что если вместо использования invoke isp сделать программно reset, до этого к примеру испортив контрольную сумму, вызвав соответствующую команду IAP - тогда при ресете должно отдаться управление штатному загрузчику. Вопрос в том, как грамотно сделать такой reset ? Как watchdog, так и вызов функции по нулевому указателю не вернет все устройства в исходные состояния, соответствующее включению устройства. -
Reinvoke ISP, LPC2388
Dreamer_0x01 ответил Dreamer_0x01 тема в ARM
Включен: MAMCR = 0; MAMTIM = 4; MAMCR = 2; -
Reinvoke ISP, LPC2388
Dreamer_0x01 ответил Dreamer_0x01 тема в ARM
Есть, но мои значения как раз в это ограничение вписываются: -
Reinvoke ISP, LPC2388
Dreamer_0x01 ответил Dreamer_0x01 тема в ARM
Да, в этом случае программируется нормально. Почему не то? Взял этот калькулятор (имеется в виду экселевская табличка на сайте nxp?), взял значение из самой верхней строки: В документации сказано, что в регистрах хранятся не сами константы M, N, CPUDivide, а их значения, уменьшенные на 1. Отсюда получились значения 11, 0, 3. Инициализирую PLL так: #define PLL_M 11 #define PLL_N 0 #define CCLK_DIV 3 #define USBCLK_DIV 5 if(PLLSTAT & (1 << 25)) { PLLCON = 1; // Enable PLL, disconnected. PLLFEED = 0xaa; PLLFEED = 0x55; } PLLCON = 0; // Disable PLL, disconnected. PLLFEED = 0xaa; PLLFEED = 0x55; SCS |= 0x20; // Enable main OSC. while(!(SCS & 0x40)); // Wait until main OSC is usable. CLKSRCSEL = 0x1; // Select main OSC, 12MHz, as the PLL clock source. PLLCFG = PLL_M | (PLL_N << 16); PLLFEED = 0xaa; PLLFEED = 0x55; PLLCON = 1; // Enable PLL, disconnected. PLLFEED = 0xaa; PLLFEED = 0x55; CCLKCFG = CCLK_DIV; // Set clock divider. USBCLKCFG = USBCLK_DIV; // Usbclk = 288 MHz/6 = 48 MHz. while (((PLLSTAT & (1 << 26)) == 0)); // Check lock bit status. do { m_value = PLLSTAT & 0x00007FFF; n_value = (PLLSTAT & 0x00FF0000) >> 16; } while ((m_value != PLL_M) && ( n_value != PLL_N) ); PLLCON = 3; // Enable and connect. PLLFEED = 0xaa; PLLFEED = 0x55; while ( ((PLLSTAT & (1 << 25)) == 0) ); // Check connect bit status. -
Reinvoke ISP, LPC2388
Dreamer_0x01 ответил Dreamer_0x01 тема в ARM
Хорошая программа, спасибо. Как задается частота, разобрался. Но чем больше читаю документацию, тем больше путаницы. Размышляю вот над этой фразой: В настройках PLL Fcclk у меня 72 мегагерца. Получается, что когда я пытаюсь программироваться через Invoke ISP и при этом PLL не отключаю, нужно задавать частоту осциллятора 72 мегагрца? Задаю, запускаю программу, не прошивается, получаю вот такой результат: Получается, что-то я еще не учел... Не могу понять, что? Разумеется, при передергивании питания и повторном запуске все прошивается, так как там не требуется задавать частоту. Еще закралось подозрение, что я неправильно посчитал константы для PLL, но уже сколько раз перепроверил, замыленным глазом ошибок не нашел. Кварц у меня стоит 12 мегагерц. Константы для PLL вот такие: PLL_M 11 PLL_N 0 CCLK_DIV 3 -
Reinvoke ISP, LPC2388
Dreamer_0x01 ответил Dreamer_0x01 тема в ARM
Так оно понятно, что все беды от этого. Вопрос только, где именно ;) Пытаюсь указать эту частоту. Действую четко по юзер-мануалу: Все проходит именно до момента ввода частоты после получения "OK<CR><LF>" от процессора. Ввожу "<чило><CR><LF>" - получаю ответ "1<CR><LF>", что соответствует "Invalid Command". Причем, это происходит и в случае Invoke из программы, и в случае самомтоятельного исполнения загрузчика после передергивания питания. Получается, частота задается каким-то другим образом, но каким - не нашел. Или не там искал. Я пробовал отключить его программно до вызова InvokeISP. Не помогло. Кстати, есть ли какая-то альтернатива ФлешМеджику, в которой виден будет протокол обмена? Хочется увидеть, на каком этапе происходит сбой, а кроме того, каким образом он все-таки задает эту самую пресловутую частоту. Конечно, имеется осциллограф, но хочется менее мучительных решений. А вообще спасибо за участие. -
Reinvoke ISP, LPC2388
Dreamer_0x01 ответил Dreamer_0x01 тема в ARM
Что-то чем дальше, тем менее понятно. Итак, в обеих случаях бутлоадер запускается. Об этом свидетельствуют ответы в терминале: посылаю '?', получаю ответ "Synchronized", отвечаю "Synchronized" - получаю ответ "ОК". Далее по юзермануалу я должен послать значение CCLK. Посылаю, но на любое число получаю ответ "1". При этом, уже начинают работать команды "K" и "J" - получаю номер бутлоадера и номер кристалла. Получается, что либо значение частоты загрузчику либо нафиг не нужно, либо его надо передавать как-то по-другому. А флешмеджиком воспроизвести программирование "с первого захода" по-прежнему не получается. -
Reinvoke ISP, LPC2388
Dreamer_0x01 опубликовал тема в ARM
Здравствуйте. Хочу в процессе выполнения программы запустить бутлоадер и перепрошить программу. Для этого в нужном мне месте программы вызываю команду загрузчика "Reinvoke ISP", старался делать все по юзер мануалу, но видимо, что-то недоделал. Вот код: #define IAP_LOCATION 0x7ffffff1 unsigned long command[5]={0}; unsigned long result[3]={0}; typedef void (*IAP)(unsigned int[],unsigned int[]); IAP iap_entry = (IAP)IAP_LOCATION; #define ISP_OPTION_2 void PrepareProgCPU() { VICINTENCLEAR = 0xFFFFFFFF; // Disable all interrupts #ifdef ISP_OPTION_2 //по документации - в этом случае надо выключать плл и выбрать внутренний IRC MAMCR = 0; //читал, что в ранних ревизиях нужно отключать MAM, у меня ревизия B PLLCON = 0x00; PLLFEED = 0xAA; PLLFEED = 0x55; CLKSRCSEL=0; #endif //иначе исполняем с опцией "1" - pll не выключаем command[0] = 57; iap_entry(command,result); } В результате получаем следующую картину. Вызываем в программе указанную функцию. Открываем терминал. Настраиваем (пока пользуюсь скоростью 9600). Шлем в терминал символ "?". Получаем ответ "Synhronized". Получается, что боотлоадер запустился и отвечает на команды. Закрываем терминал, открываем флешмеджик. Настраиваем на те же параметры, делаем старт. Происходит стирание флеша (в статусной строке проскакивают сообщения "Erasing block"). Далее в статусной строке пишется "Programming..." После чего выводится сообщение "Anable to communicate (transmit/receive)". Программирование прекращается, если запустить терминал, на команды больше не отвечаем. Далее отключаю питание. Включаю. Процессор не исполняет рабочую программу, находится в редиме загрузчика. Проверяю - запускаю флешмеджик, делаю "старт" - программируется "на ура", причем с любой скоростью. Компилирую программу с "#define ISP_OPTION_1". Это допустимо, как утверждается в документации, при этом должна установиться PCLK = CCLK/4. У меня используется частота 72 мегагерца, если поделить на 4, получается 18, для скорости 9600 это допустимое значение. Тестируем, получаем абсолютно идентичный результат. Получается, что я перед вызовом "Reinvoke ISP" что-то не вернул в исходное состояние. Вопрос, что? ЗЫ. Компилятор - IAR 5.4. -
LPC2388 External Memory Controller
Dreamer_0x01 ответил Dreamer_0x01 тема в ARM
Сам же и разобрался. Попросту забыл проинициализировать OE и CS для работы с внешней памятью. Теперь все работает. Код инициализации такой: PCONP |= 0x00000800; // Turn on EMC PCLK. PINSEL6 = 0x5555; // D0-D7. 0101010101010101(b) PINSEL8 = 0x55555555; // A0-A15. PINSEL9 = (0x01 << 16) | (0x02 << 18) | (0x01 << 28) | (0x01 << 30); EMCCONTROL = 0x00000001; // Enable EMC. SCS |= 0x00000002; // Reset EMC. -
LPC2388 External Memory Controller
Dreamer_0x01 опубликовал тема в ARM
Здравствуйте. Пытаюсь запустить EMC на процессоре LPC2388, ревизия "B". Сделал инициализацию, пытаюсь выполнить чтение - тишина. Тыкаюсь осциллографом - ножки OE и CS всегда в единице. Скорее всего, кривая инициализация. У кого-то есть готовый работающий пример инициализации EMC на этом контроллере? Я делаю так. //перед вызовом этой функции запускается инициализация PLL. void Init_EMC(void) { SCS |= 0x00000002; // Reset EMC. EMCCONTROL = 0x00000001; // Enable EMC. PCONP |= 0x00000800; // Turn on EMC PCLK. PINSEL6 |= 0x5555; // D0-D7. 0101010101010101(b) PINSEL8 = 0x55555555; // A0-A15. } #define EMC_BASE 0x80000000 //запись void inline WriteEMCFPGA(unsigned int addr, unsigned char dtx) { unsigned char * p; p = (unsigned char*)(addr + EMC_BASE); *p=dtx; } //чтение unsigned char inline ReadEMCFPGA(unsigned int addr) { unsigned char * p; p = (unsigned char*)(addr + EMC_BASE); return *p; } Что делаю не так или чего не делаю? Спасибо. -
Сергей Борщ. Вы абсолютно правильно меня поняли. Модифицировать эти данные мне действительно не нужно. Сначала (до поднятия темы на форуме) было сделано так: 1. Функции принимали значения на НЕ КОНСТАНТЫ, так как в зависимости от других параметров в ней возможна модификация. 2. Были объявлены дефолтные значения структур как const . 3. Перед вызовом функции делалось следующее - в стеке создавался экземпляр структуры НЕ константной, с помощью memcpy в него копировалось значение константной структуры, и вызывалась пресловутая функция. Во многих местах, как выяснилось, мне оказалось достаточным дефолтных значений структуры, и создавать лишний объект в стеке (или в хипе) только лишь ради корректного приведения указателей мне показалось лишним, я хотел соптимизировать этот момент, перебрал несколько идей - в том чиле и этот пост, так как повторюсь, в Кейле для 51 процессоров, с которыми я работал до этого процессора, это прокатывало. Приведение указателя "конст" к "не конст" с помощью круглых скобок при вызове функции мне не показалось лучшим решением. Но на данный момент я оставил это место как есть и иду дальше, так как сроки проекта короткие, и если вдаваться в глубокие рассуждения на тему "кто круче, а кто дурак" - то так я точно в сроки не уложусь. Пусть лучше считают дураком, но при этом делается мое дело. А обсуждать что-либо на форуме больше не хочу. Перехожу обратно в разряд читателей.