|
Вопрос по АРМ LPC |
|
|
|
Jan 20 2006, 12:16
|

Частый гость
 
Группа: Свой
Сообщений: 144
Регистрация: 5-08-05
Пользователь №: 7 382

|
Цитата(vesago @ Jan 20 2006, 14:13)  Хочу сделать первый проект на арм. Выбрал в частности 2214. С инструментарием определился - кейл. Хочу спросить - программный мастер 1 варе хорошо будет работать на этом камне или лучьше взять мелкий сопроцессор типа 2313 и по уарту слать? Нормально lpc будет работать с max232? Знаю, что lpc толерантен к 5В, но спрошу на всякий случай. И вообще, действительно ли можно оперировать свободно с 5в цепями? Програаммный мастер - как напишите, есть огранияения на скорость махания ногами. лучше взять мах3232 , помнить что утилита писания флэша может сама вставать в режим ISP исли заведёте RTS и DTR иначе придётся делать перемычки. Схема сброса вязть нормальную микруху с внешним сбросом или на худой конец R-C + тактовая кнопка. Толерантен к выходам - входам 5V но зачем, сейчас 3.3 логики - как грязи. Да и мелкую логику - ну нах , Xelinx 9500XL ставте и будет счастье... Помнить что некотрые линии без пуллапа SDL SDA , TxD Если серьёзно думаете работать с ARM7TDMI возьмите МТ-ЛИнк , но есть инфа что проект закрыт. можно и виглер, но это гамадризм... Номинал кварц брать из даташита .. вроде всё
--------------------
Свет мой зеркальце, скажи, да всю правду расскажи я ль на свете всех тупее, бесполезней и пьянее? Ты - придурок. Спору нет! Но живет на белом свете вот ТАКИХ еще две трети!
|
|
|
|
|
Jan 20 2006, 14:00
|
Участник

Группа: Свой
Сообщений: 72
Регистрация: 8-11-04
Из: Томск
Пользователь №: 1 070

|
Цитата(Ken@t @ Jan 20 2006, 15:16)  Если серьёзно думаете работать с ARM7TDMI возьмите МТ-ЛИнк , но есть инфа что проект закрыт. Откуда такая информация и по какой причине?
|
|
|
|
|
Jan 22 2006, 10:00
|

Частый гость
 
Группа: Свой
Сообщений: 144
Регистрация: 5-08-05
Пользователь №: 7 382

|
Цитата(vesago @ Jan 22 2006, 12:22)  Спасибо, Kenat. Хотел еще спросить - существенно ли медленнее исполняется код из флеша? Стоит ли максимально грузить в рам или в большинстве случаев можно из флеши? И еще - можно как нибудь дистанционно запустить загрузку во флешь используя штатный загрузчик. Допустим прибор где нибудь в отдалении по 485 связан и надобно поменять прошивку? Я так понял 14 лапу сожают на землю только для того, чтоб после ресета камень перешел в область загрузчика. скорость выполнения программ зависит от ваших требований. Только учтите, что скорость махание лапками ограничено аппаратной реализацией . Для загрузки своего кода можно применить технологию IAP + преназначение области встроенной RAM на вектора прерыванией MEMMAP .. код IAP прилагаю с примером. iap.h Код #ifndef _IAP_H #define _IAP_H
// Results from flashInit() #define LPC256K 2 #define LPC128K 1 #define LPCUNKN -1
// (Philips) Status Codes #define CMD_SUCCESS 0 #define INVALID_CMD 1 #define SRC_ADDR_ERROR 2 #define DST_ADDR_ERROR 3 #define SRC_ADDR_NOT_MAPPED 4 #define DST_ADDR_NOT_MAPPED 5 #define COUNT_ERROR 6 #define INVALID_SECTOR 7 #define SECTOR_NOT_BLANK 8 #define SECTOR_NOT_PREPARED 9 #define COMPARE_ERROR 10 #define BUSY 11 #define PARAM_ERROR 12 #define ADDR_ERROR 13 #define ADDR_NOT_MAPPED 14 #define CMD_LOCKED 15 #define INVALID_CODE 16 #define INVALID_BAUD_RATE 17 #define INVALID_STOP_BIT 18 #define CODE_READ_PROT_ENABLED 19
int flashBlank(int startSector, int endSector); int flashErase(int startSector, int endSector); int flashInit(void); int flashWrite(void *dst, void *src, unsigned byteCount);
#endif iap.c Код #include <intrinsic.h> #include "string.h" #include "iap.h"
#define IAP_LOCATION 0x7ffffff1 typedef void (*IAP)(unsigned long *,unsigned long *); IAP iap_entry =(IAP) IAP_LOCATION;
static unsigned long flashParams[5], flashResult[2]; static int lastSector;
#ifndef MIN #define MIN(n,m) (((n) < (m)) ? (n) : (m)) #endif
int GetProcessorClockFreq(void); int GetPeripheralClockFreq(void);
int flashBlank(int startSector, int endSector) { flashParams[0] = 53; // blank check flashParams[1] = startSector; // start sector flashParams[2] = endSector; // end sector iap_entry(flashParams,flashResult); return (int)flashResult[0]; }
int flashErase(int startSector, int endSector) { // unsigned long cpsr; // unsigned char memmap;
__disable_interrupt(); // memmap = MEMMAP; // get current memory map // MEMMAP = MEMMAP_FLASH; // map User Flash into low 64 bytes
flashParams[0] = 50; // prepare sector(s) flashParams[1] = startSector; // start sector flashParams[2] = endSector; // end sector
iap_entry(flashParams,flashResult);
if (flashResult[0] == CMD_SUCCESS) { flashParams[0] = 52; // erase sector(s) flashParams[1] = startSector; // start sector flashParams[2] = endSector; // end sector flashParams[3] = GetProcessorClockFreq()/1000; // cpu clock freq in KHz iap_entry(flashParams,flashResult); }
//MEMMAP = memmap & 0x03; // restore the memory map __enable_interrupt(); return (int)flashResult[0]; }
int flashInit(void) { lastSector = 0; // clear last usable sector #
switch (flashBlank(16, 16)) // check last sector of 256K parts { case CMD_SUCCESS: case SECTOR_NOT_BLANK: lastSector = 16; // store last usable sector # return LPC256K;
case INVALID_SECTOR: break;
default: return LPCUNKN; }
switch (flashBlank(14, 14)) // check last sector of 128K parts { case CMD_SUCCESS: case SECTOR_NOT_BLANK: lastSector = 14; // store last usable sector # return LPC128K;
default: break; }
return LPCUNKN; }
int flashWrite(void *dst, void *src, unsigned byteCount) { // unsigned char memmap; unsigned long count; // cpsr,; unsigned long buffer[512/sizeof (long)];
if ((lastSector == 0) && ( flashInit() == LPCUNKN)) return BUSY;
while (byteCount) { // cpsr = disableINTs(); // disable all interrupts __disable_interrupt();
// memmap = MEMMAP; // get current memory map // MEMMAP = MEMMAP_FLASH; // map User Flash into low 64 bytes
// prepare all sectors for programing flashParams[0] = 50; // prepare sectors flashParams[1] = 0; // start sector flashParams[2] = lastSector; // last sector iap_entry(flashParams,flashResult);
if (flashResult[0] != CMD_SUCCESS) { // MEMMAP = memmap & 0x03; // restore the memory map // restoreINTs(cpsr); // restore all interrupts __enable_interrupt(); return flashResult[0]; }
// check if dst is on 512 byte boundary if ((unsigned long)dst & 0x1FF) { // no, copy 512 bytes from flash into buffer memcpy(buffer, (void *)((unsigned long)dst & ~0x1FF), 512);
// copy src into buffer count = MIN(byteCount, (512 - ((unsigned long)dst & 0x1FF))); memcpy((char *)buffer + ((unsigned long)dst & 0x1FF), src, count);
flashParams[0] = 51; // copy RAM to Flash flashParams[1] = (unsigned long)dst & ~0x1FF; // destination flashParams[2] = (unsigned long)buffer; // source flashParams[3] = 512; // byte count flashParams[4] = GetProcessorClockFreq()/1000; // CCLK in KHz iap_entry(flashParams,flashResult);
// MEMMAP = memmap & 0x03; // restore the memory map // restoreINTs(cpsr); // restore all interrupts __enable_interrupt();
if (flashResult[0] != CMD_SUCCESS) return (int)flashResult[0];
dst = (char *)dst + count; src = (char *)src + count; byteCount -= count; continue; // restart the loop to prepare sectors again }
// dst is now aligned on a 512 byte boundary // find the biggest chunk we can program at a time if (byteCount >= 8192) count = 8192; else if (byteCount >= 4096) count = 4096; else if (byteCount >= 1024) count = 1024; else if (byteCount >= 512) count = 512; else count = byteCount;
if (count < 512) { memcpy(buffer, dst, 512); // copy current flash contents into buffer memcpy(buffer, src, count); // update buffer with the new contents flashParams[2] = (unsigned long)buffer; // source flashParams[3] = 512; // byte count } else { flashParams[2] = (unsigned long)src; flashParams[3] = count; // byte count }
flashParams[0] = 51; // copy RAM to Flash flashParams[1] = (unsigned long)dst; // destination flashParams[4] = GetProcessorClockFreq()/1000; // CCLK in KHz
iap_entry(flashParams,flashResult);
// MEMMAP = memmap & 0x03; // restore the memory map // restoreINTs(cpsr); // restore all interrupts __enable_interrupt();
if (flashResult[0] != CMD_SUCCESS) return (int)flashResult[0];
dst = (char *)dst + count; src = (char *)src + count; byteCount -= count; }
return CMD_SUCCESS; } пример Код // 1 Erase 16 block printf ("Erase calibration\r\n"); rslt = flashErase(16, 16); printf ("Result = 0x%04X\r\n",rslt); printf ("Write calibration\r\n"); rslt = flashWrite((int *)pCalibration, &ZerroREDOX, sizeof(int)); printf ("Result = 0x%04X\r\n",rslt);
--------------------
Свет мой зеркальце, скажи, да всю правду расскажи я ль на свете всех тупее, бесполезней и пьянее? Ты - придурок. Спору нет! Но живет на белом свете вот ТАКИХ еще две трети!
|
|
|
|
|
Jun 6 2006, 05:54
|
Частый гость
 
Группа: Свой
Сообщений: 105
Регистрация: 14-01-05
Из: Москва Зеленоград
Пользователь №: 1 962

|
Да, мудрено вот тольок я не увидел код описания и инициализации переменных во флешь памяти никак не пойму как сделать это правильно. сейчас так: "globals.h" Код typedef union { int i; unsigned char b[4]; float r; } RealByte; "IAP.cpp" Код #include <inarm.h> #include <iolpc2214.h> #include "globals.h" #include "iap.h" #include "string.h"
const RealByte ParamInEEPROM[6] @ "EEPROM" = { 500, 2000, 10, 120, 0.1, 1.3 // Mic1 sensor };
RealByte const * pParamInEEPROM = ParamInEEPROM; EEPROM - один сектор flash, 16ый, адреса 0x0003 C000 - DFFF) в проце LPC2214 Код -DEEPROMSTART=0x0003C000 -DEEPROMEND=0003DFFF
-Z(DATA)EEPROM=EEPROMSTART-EEPROMEND pParamInEEPROM - используется в других модулях Если делать extern сам массив , то линкер выдает ошибку , типа undefine external symbol Сейчас просто Warning "Warning[w29]: Parts of segment EEPROM are initialized (as in module IAP), even though it is of type DATA (and thus not promable)" и что с ним делать? совсем не понятно да , кстати при инициализации 0.1 , 1.3 преобразовываются в int а мне это не нужно, может есть какие мысли по поводу как это исправить? --------------------------------- по второму вопросу разобрался надо делать так Код const RealByte ParamInEEPROM[6] @ "EEPROM" = { 500, 2000, 10, 120, {.r = 0.1}, {.r = 1.3} // Mic1 sensor };
|
|
|
|
|
Jun 6 2006, 07:41
|

Участник

Группа: Свой
Сообщений: 47
Регистрация: 28-07-05
Пользователь №: 7 162

|
Цитата(vesago @ Jan 22 2006, 14:18)  Большое спасибо! Буду переваривать. А какую максимальную частоту SPI можно выжать из LPC? Судя по юзер мануалу - не более 8 МГц. Или я не правильно понял? Реально удалось пропустить 1.6 МБита на такте 2.5 МГц (тактовая процессора-60 МГц). Там получаются большие дырки между байтами. Слишком простой SPI.
|
|
|
|
|
Jun 6 2006, 08:58
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(vesago @ Jan 22 2006, 13:18)  Большое спасибо! Буду переваривать. А какую максимальную частоту SPI можно выжать из LPC? Судя по юзер мануалу - не более 8 МГц. Или я не правильно понял? 7,5 - 1/8 тактовой. Для 213x/4x SSP мастером - на 1/2 тактовой, есть FIFO и SSEL аппаратный работает. Полную 30MHz скорость, естественно, не развить, ибо FIFO разгружается быстрее, чем его можно реально загружать.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|