реклама на сайте
подробности

 
 
> IAP. Лыжи не едут или как...
EXeGLuMATOR
сообщение Apr 2 2008, 08:51
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 182
Регистрация: 30-01-05
Из: Volgograd
Пользователь №: 2 305



В общем надо записывать флэш.
Определения:
Код
#define IAP_LOCATION 0x7FFFFFF1
typedef void (*IAP)(unsigned int [], unsigned int []);
#define iap_entry ((IAP) IAP_LOCATION)

unsigned int    command[5];
unsigned int    result[2];


Собственно функция стирания секторов:
Код
unsigned int erase (unsigned int start, unsigned int end)
{

  command[0]= IAP_PREPARE_SECTOR;              // IAP Command: Prepare Sectors for Write (50)
  command[1] = 3;//Get_sector(start);              // Start Sector
  command[2] = 3; //Get_sector(end-1);     // End Sector
  iap_entry(command, result);               // Call IAP Function
  if (result[0]==0)
  {
       u0putstr("Preparing sector`s ok. Erasing...\r\n");
    command[0] = IAP_ERASE_SECTOR;           // IAP Command: Erase Flash (52)
      command[1] = Get_sector (start);         // Start Sector
      command[2] = Get_sector (end-1);            // End Sector
      command[3] = PCLK/1000;                  // CPU Clock
      iap_entry(command,result);           // Call IAP Function
  }
}

При вызове IAP_PREPARE_SECTOR возвращает ошибку 7: INVALID_SECTOR. Я уже по всякому и объявлять пытался и т.п. - ни в какую. И номера секторов ручками пишу и по всякому. Результат один.
массив команд заполнен вроде как верно. Примеры смотрел, документацию читал. Все вроде как там. И не работает.
Камень LPC2106, LPC2103. PLL и т.п. отключены. Кварц 14.7456
Может гитьки какие есть? Если когда-то была установлена защита - она стирается при полнеом стирании флэша? И влияет ли она на эти процедуры?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 14)
YAM
сообщение Apr 2 2008, 09:44
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 256
Регистрация: 7-07-04
Из: Ukraine
Пользователь №: 291



У меня вот так все работает, правда для LPC2136:

// Вызов команды IAP
static u32 IapCommand(u32 cmd, u32 p0, u32 p1, u32 p2, u32 p3, u32 *r0)
{
u32 command[5] = { cmd, p0, p1, p2, p3 };
u32 result[2];
// Запускаю команду IAP
((void(*)(u32 [],u32 []))0x7FFFFFF1)(command, result);
// Возвращаю результат
if (r0)
{
*r0 = result[1];
}
return result[0];
}

static u32 IAP_ERASE(u32 curr_sec, u32 FcclkKHZ)
{
u32 state;
// Готовлю сектор к стиранию
iap_prepare_erase:
state = IapCommand( IAP_CMD_PREPARE, curr_sec, curr_sec, 0, 0, 0);
switch(state)
{
case IAP_CMD_SUCCESS:
break;
case IAP_BUSY:
goto iap_prepare_erase;
default:
return state;
}
// Стираю сектор
iap_erase:
state = IapCommand(IAP_CMD_ERASE, curr_sec, curr_sec, FcclkKHZ, 0, 0);
switch(state)
{
case IAP_CMD_SUCCESS:
break;
case IAP_BUSY:
goto iap_erase;
default:
return state;
}
return IAP_CMD_SUCCESS;
}


--------------------
Go to the top of the page
 
+Quote Post
EXeGLuMATOR
сообщение Apr 2 2008, 10:53
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 182
Регистрация: 30-01-05
Из: Volgograd
Пользователь №: 2 305



Эффект тот-же. Абсолютно.
И еще, если command, result объявлять глобально - то возвращает код ошибки. Если локально в теле функции - то просто виснет на вызове.

В симуляторе все работает без вопросов. Стирает, пишет, готовит.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 2 2008, 12:28
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(EXeGLuMATOR @ Apr 2 2008, 11:51) *
command[0]= IAP_PREPARE_SECTOR; // IAP Command: Prepare Sectors for Write (50)
а чему равно IAP_PREPARE_SECTOR? Бывает указывают 0x50... Прерывания не забываете запрещать? В конце ОЗУ не забыли зарезервировать область 32 байта для IAP чтобы в нее случайно стек не залез?

Код
// (Philips) Status Codes
enum iap_status_t
{
    CMD_SUCCESS, INVALID_CMD,
    SRC_ADDR_ERROR, DST_ADDR_ERROR, SRC_ADDR_NOT_MAPPED, DST_ADDR_NOT_MAPPED,
    COUNT_ERROR, INVALID_SECTOR, SECTOR_NOT_BLANK, SECTOR_NOT_PREPARED,
    COMPARE_ERROR, BUSY, PARAM_ERROR, ADDR_ERROR, ADDR_NOT_MAPPED,
    CMD_LOCKED, INVALID_CODE, INVALID_BAUD_RATE, INVALID_STOP_BIT, CODE_READ_PROT_ENABLED, OUT_OF_MEMORY, MAX_ERROR
};

enum iap_cmd_t
{
    PREPARE = 50, COPY, ERASE, BLANK_CHECK, GET_PART_ID, GET_BOOT_VER, COMPARE,
    SIZE_ALIGN = 0xFFFFFFFF // make iap_cmd_t 4-bytes width
};

struct iap_command_t
{
    iap_cmd_t    Command;
    uint32_t        Param[4];
};
struct iap_result_t
{
    iap_status_t    Status;
    uint32_t        Result[4];
};

extern "C" __thumb void IAP(iap_command_t *params, iap_result_t *result); // IAP объявлено в скрипте линкера, компилится более эффективный вызов, чем по указателю.

iap_status_t Erase (uint_fast8_t start_sector, uint_fast8_t end_sector)
{
    iap_command_t Cmd;
    iap_result_t Res;

    Cmd.Command = PREPARE;
    Cmd.Param[0] = start_sector;
    Cmd.Param[1] = end_sector;

    critical_t cs;
    IAP(&Cmd, &Res);
    
    if (Res.Status == CMD_SUCCESS)
    {
        Cmd.Command = ERASE;
        Cmd.Param[0] = start_sector;
        Cmd.Param[1] = end_sector;
        Cmd.Param[2] = CCLK / 1000;

        IAP(&Cmd, &Res);
    }
    return Res.Status;
}


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
EXeGLuMATOR
сообщение Apr 2 2008, 13:15
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 182
Регистрация: 30-01-05
Из: Volgograd
Пользователь №: 2 305



Так... А как резервировать область? Подозреваю что в этом проблема. Поскольку в зависимости от объявления параметров меняется и результат.
Кстати Парт ИД читается без проблем. Но как только начинаются остальные параметры - лезет какая-то фигня...
Команды указаны верно, прерывания запрещаются.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 2 2008, 13:22
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(EXeGLuMATOR @ Apr 2 2008, 16:15) *
Так... А как резервировать область?
Зависит от компилятора (точнее линкера). Для IAR 4.xx указываю в скрипте
Код
-DRAMEND=(40003fff-.32)       // reserve RAM for IAP
....
-Z(DATA)CSTACK+_CSTACK_SIZE#RAMSTART-RAMEND
-Z(DATA)SVC_STACK+_SVC_STACK_SIZE#RAMSTART-RAMEND
-Z(DATA)IRQ_STACK+_IRQ_STACK_SIZE#RAMSTART-RAMEND
.....
для GCC наверное писал бы что-нибудь вроде
Код
MEMORY
{
  ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00008000
  RAM (rwx) : ORIGIN = 0x40000000, LENGTH = 0x00004000 - 0x20  // reserve RAM for IAP
  REMAPED (rwx) : ORIGIN = 0x00000000, LENGTH = 0x40
}


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
EXeGLuMATOR
сообщение Apr 2 2008, 13:54
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 182
Регистрация: 30-01-05
Из: Volgograd
Пользователь №: 2 305



Попробовал определения как описал - результат тот-же.
Компилятор Keil, RealView.
зарезервировать наверное можно просто указав в настройках проекта длину за вычетом этих байтов?
Go to the top of the page
 
+Quote Post
lebiga
сообщение Apr 2 2008, 14:12
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 22-06-06
Из: Киев
Пользователь №: 18 292



Цитата(EXeGLuMATOR @ Apr 2 2008, 16:54) *
Попробовал определения как описал - результат тот-же.
Компилятор Keil, RealView.
зарезервировать наверное можно просто указав в настройках проекта длину за вычетом этих байтов?


Может сначала попробовать стереть всю флеш вместе с битами защиты через FLASH MAGIC? Если заработает - потом играться дальше
Go to the top of the page
 
+Quote Post
EXeGLuMATOR
сообщение Apr 2 2008, 17:33
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 182
Регистрация: 30-01-05
Из: Volgograd
Пользователь №: 2 305



Да там и не стояло их отродясь. Причем и на новых процах, только с завода - один фиг. Та-же проблема. Походу где-то есть что-то что не дает работать с флэшем. Либо не так передаются параметры. Хотя у всех работает - у меня нет. Ну не может быть. Походу что-то не так в проекте всетаки. Вот только что...
Go to the top of the page
 
+Quote Post
SeregaB
сообщение Apr 3 2008, 06:26
Сообщение #10


Участник
*

Группа: Свой
Сообщений: 55
Регистрация: 6-04-06
Из: Москва, Зеленоград
Пользователь №: 15 863



Цитата(EXeGLuMATOR @ Apr 2 2008, 20:33) *
Да там и не стояло их отродясь. Причем и на новых процах, только с завода - один фиг. Та-же проблема. Походу где-то есть что-то что не дает работать с флэшем. Либо не так передаются параметры. Хотя у всех работает - у меня нет. Ну не может быть. Походу что-то не так в проекте всетаки. Вот только что...


Пока не поставил command[3] = 512; процик тоже гнал всякую пургу. Почему-то не все описанные в ДШ размеры поддерживаются. Камень - LPC2119, одной из первых партий, у которых еще сброс не с первого раза.
Код
        command[0] = IAP_CMD_WRITE;
        command[1] = (U32)(Buf_Dst);
        command[2] = (U32)(Buf_Src);
        command[3] = 512;//0x2000;
        command[4] = 14745;
Go to the top of the page
 
+Quote Post
EXeGLuMATOR
сообщение Apr 3 2008, 07:04
Сообщение #11


Частый гость
**

Группа: Свой
Сообщений: 182
Регистрация: 30-01-05
Из: Volgograd
Пользователь №: 2 305



Да у меня 512 и стоит.
В общем закомментил все, кроме того что работает с ИАП и ЮАРТом - заработало. Код не менял. Сегодня буду подключать потихоньку все остальное и смотреть, что получится. Где-то засела бяка.
Go to the top of the page
 
+Quote Post
EXeGLuMATOR
сообщение Apr 3 2008, 15:35
Сообщение #12


Частый гость
**

Группа: Свой
Сообщений: 182
Регистрация: 30-01-05
Из: Volgograd
Пользователь №: 2 305



Подключил. Все заработало. Причем все в том виде в каком и было. И что это? Типа фича компилера?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 3 2008, 19:34
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(EXeGLuMATOR @ Apr 3 2008, 18:35) *
Типа фича компилера?
Вот если вы покажете конкретный участок листинга, который компилятор сделал по вашему мнению неправильно - можно будет говорить что-то о причастности компилятора.

У меня с этим кодом была почти мистическая ситуация - программирование то работало, то не работало. Один день могло работать, второй - нет. Я уже начал вслух повторять "чудес не бывает" и думать насчет показаться психологу smile.gif
Смотрю передающуюся структуру в отладчике - все правильно. Command = 50, Param[0] = 1, Param[1] = 2 а оно мне возвращает ошибку INVALID_CMD. Долго медитировал, несколько подходов делал. А в другой день отладчик показывает то же самое содердимое структуры, и все работает. Потом однажды посмотрел содержимое памяти на стеке в том месте, где лежит структура. А компилятор честно отвел под enum команды один байт и заполнял только его. В остальных трех был мусор, который иногда случайно был равен нулям и все работало. И отладчик тоже честно показывал мне содержимое только одного байта. После этого добавил в enum фиктивное значение SIZE_ALIGN = 0xFFFFFFFF и с тех пор все работает.

Если кто-то захочет возразить, что enum занимает минимум int - у меня сознательно включена опция использовать короткие enumы и это активно используется в других частях программы.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
EXeGLuMATOR
сообщение Apr 3 2008, 22:03
Сообщение #14


Частый гость
**

Группа: Свой
Сообщений: 182
Регистрация: 30-01-05
Из: Volgograd
Пользователь №: 2 305



Да вот почти также все. Привел типы все и вроде ок. Причем если команде присваивать явно 4 (прям циферкой), например, при том что она определена как лонг - не работает. А вот при передаче через параметр функции, в которой сидит вызов ИАП - все нормально.
Также почему-то и при вызове процедур I2C. Если в функции сидит - нормально. Если на уровень глубже (напрмер перенес вызов из этой функции в функцию записи с проверкой) - не работает и все. Как победить - пока не знаю. Не так давно я плотно занялся всеми этими делами. Я так понимаю надо стек увеличивать?
Go to the top of the page
 
+Quote Post
lebiga
сообщение Jan 22 2009, 12:30
Сообщение #15


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 22-06-06
Из: Киев
Пользователь №: 18 292



Цитата(Сергей Борщ @ Apr 2 2008, 15:28) *
Код
extern "C" __thumb void IAP(iap_command_t *params, iap_result_t *result); // IAP объявлено в скрипте линкера, компилится более эффективный вызов, чем по указателю.
}

А как в скрипте линкера (.icf - IAR520) объявить IAP?
Это не работает:
define symbol IAP = 0x7FFFFFF1;
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 09:36
Рейтинг@Mail.ru


Страница сгенерированна за 0.01555 секунд с 7
ELECTRONIX ©2004-2016