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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Проблемы с записью/считыванием во/из Flash, Коряво пишутся или считываются данные
Redaer
сообщение Nov 1 2006, 15:14
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 19
Регистрация: 12-07-06
Пользователь №: 18 762



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

Так вот записываю я одни данные, а считываются другие, вернее, происходит какая-то странная подмена одних байтов другими. К примеру(все в шестнадцатиричном виде):



| Записываю | Считываю |

| 0F | F0 |

| EA | 57 |

| FE | 7F |

и т.п.



Вот функции, которыми пользуюсь для записи, считывани во и из flash

Код
  

__ramfunc void EFC_Init(void)
{
  while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY));
  AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(100 << 16)) | AT91C_MC_FWS_1FWS;
  while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY));
}




Код


__ramfunc unsigned int EFC_WritePage(unsigned int adr, unsigned int *pbuf)
{
  unsigned int *pflash;
  unsigned int page;
  unsigned int region;
  unsigned int i;

  pflash = (unsigned int *)adr;
  page = (adr & 0x3FFFF) / EFC_PAGE_SIZE;
  region = (page/EFC_PagesInTheLockRegion);

  EFC_Init();

  if (AT91C_BASE_MC->MC_FSR & (region << 16)) {
// lock set, clear it
    AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(50 << 16)) |
                          AT91C_MC_FWS_2FWS;
    AT91C_BASE_MC->MC_FCR = (0x5A << 24) | (region << 8 ) |
                          AT91C_MC_FCMD_UNLOCK;
  }

  while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY));
  for (i = 0; i < EFC_PAGE_SIZE_UINT; i++)
    if (pbuf[i] != 0) {
      *(pflash + i) = *(pbuf + i);
    }

  AT91C_BASE_MC->MC_FCR = (0x5A << 24) |
                          (page << 8 ) |
                          AT91C_MC_FCMD_START_PROG;
  while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY));

  return 1;
}




Код
  

__ramfunc void TestEFC(unsigned int adr) {

  AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_US1);
  AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_PIOA);



  while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY));
  EFC_WritePage(0x100000 | adr, (unsigned int*)tryInt);



  AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US1);
  AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_PIOA);




Код
__ramfunc ReadFromAddress(unsigned int address) {
  AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_US1);
  AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_PIOA);



    while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY));
    EFC_ReadPage(address, buff_tx);

    while(!(AT91F_US_TxReady(AT91C_BASE_US1)));
    AT91F_US_Put(buff_tx, EFC_PAGE_SIZE);


  AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US1);
  AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_PIOA);

  COM1->US_TPR = (unsigned char)&buff_tx[0];
  COM1->US_TCR = 0;

}




Прогаю sam7s256 в iar.
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Nov 1 2006, 15:43
Сообщение #2


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Цитата(Redaer @ Nov 1 2006, 18:14) *
...

Бит-реверсия получается, однако...
А вы уверены что это ошибка во флеш, а не в УАРТе? Иначе говоря, УАРТ проверен, в нем есть уверенность?


--------------------
شامل
Go to the top of the page
 
+Quote Post
Redaer
сообщение Nov 1 2006, 20:09
Сообщение #3


Участник
*

Группа: Новичок
Сообщений: 19
Регистрация: 12-07-06
Пользователь №: 18 762



Ха! Действительно, как не заметил...

Если посылаю с компа на комп по КОМ-порту, то все корректно приходит, без реверсии... То же самое наблюдается и в ИАРе, когда пошагово выполняю, т.е. в RX-массиве оказываются верные 4-хбайтовые числа...

Получается, что меняются старшие и младшие биты местами... Вернее считывание числа из массива происходит наоборот... А как-нть этого можно избежать?


Edmundo, cпасибо за подсказку, буд дальше мучать smile.gif

Сообщение отредактировал Redaer - Nov 1 2006, 20:11
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Nov 1 2006, 20:27
Сообщение #4


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Цитата(Redaer @ Nov 1 2006, 23:09) *
Получается, что меняются старшие и младшие биты местами... Вернее считывание числа из массива происходит наоборот... А как-нть этого можно избежать?

Edmundo, cпасибо за подсказку, буд дальше мучать smile.gif

Интуитивно мне кажется, что при работе с флеш бит-реверсии получиться не может (справедливости ради скажу, что в SAM'ах флешку не щупал). А вот при работе с последовательными интерфейсами -- запросто smile.gif, сами понимаете.


--------------------
شامل
Go to the top of the page
 
+Quote Post
Timofey
сообщение Nov 2 2006, 12:12
Сообщение #5


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

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Я впринципе пишу также, у меня все нормально, не видно как тут идет прием из ком-порта ..... Я вобщем делаю так: у меня есть некий буфер на 200 байтов, по приходу разного количества байт я записываю их в этот буфер, а буфер потом во флэш. При включении контроллера я эти байты считываю из флэш в буфер .... И все вроде бы пока нормально, ошибок таких, как был записан или считан не верный байт, не было ..... Даже если приходит на ком-порт всего один байт.
Go to the top of the page
 
+Quote Post
Redaer
сообщение Nov 2 2006, 14:00
Сообщение #6


Участник
*

Группа: Новичок
Сообщений: 19
Регистрация: 12-07-06
Пользователь №: 18 762



Цитата(Edmundo @ Nov 1 2006, 23:27) *
Цитата(Redaer @ Nov 1 2006, 23:09) *
Получается, что меняются старшие и младшие биты местами... Вернее считывание числа из массива происходит наоборот... А как-нть этого можно избежать?

Edmundo, cпасибо за подсказку, буд дальше мучать smile.gif

Интуитивно мне кажется, что при работе с флеш бит-реверсии получиться не может (справедливости ради скажу, что в SAM'ах флешку не щупал). А вот при работе с последовательными интерфейсами -- запросто smile.gif , сами понимаете.




Ага, только если на КОМ посылается больше 1 байта, то он передает их в обратном порядке, т.е.: если посылать по кому 0x1234, то он отправит их как 0x3412, а никак не 0x589 -- проверял на арме



прием данных происходит так(не пинать smile.gif , но дружеский подзатыльник можно biggrin.gif )

Код


        unsigned int testAdr = 0x100000;

        while(1) {
          while(!(AT91F_US_RxReady(AT91C_BASE_US1))); //жду, когда что-либо будет на RX
          TestEFC(testAdr);  // Пишу во флешь данные из RX-буфера(массив типа unsigned int buff_rx[64])
          testAdr += 0x100; //изменение адреса записи
        }




инициализация буфера на прием

Код


    AT91C_BASE_US1->US_RPR = (unsigned int)&buff_rx;
    AT91C_BASE_US1->US_RCR = 64;




Вот думаю, может в каком-нть месте произвести реверсию, к примеру, при отправке с компа на уарт арма?.. Есть смысл?
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Nov 2 2006, 14:10
Сообщение #7


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Цитата(Redaer @ Nov 2 2006, 17:00) *
если посылать по кому 0x1234, то он отправит их как 0x3412

Ну это наверное уже little endian имеет место быть.


--------------------
شامل
Go to the top of the page
 
+Quote Post
Redaer
сообщение Nov 2 2006, 18:43
Сообщение #8


Участник
*

Группа: Новичок
Сообщений: 19
Регистрация: 12-07-06
Пользователь №: 18 762



Может быть...
В общем, просто реверс в проге, которая скидывает инфу с компа сделал. Вроде работает...
Но все равно интересно, че за глюк такой...
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Nov 2 2006, 21:07
Сообщение #9


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Цитата(Redaer @ Nov 2 2006, 21:43) *
Может быть...
В общем, просто реверс в проге, которая скидывает инфу с компа сделал. Вроде работает...
Но все равно интересно, че за глюк такой...

Реверс байтов или битов?

Здесь необходимо разобраться в проблеме. Если реверс байтов, то посмотрите: не получается ли у вас где-то так, что вы оперируете массивом int'ов (или short'ов) в одном месте, а в другом -- массивом байтов. В этом случае надо четко представлять порядок байтов при расположении в памяти с учетом endian'а.

Если битов, то вероятно это неправильное направление передачи по последовательному интерфейсу (есть два варианта: MSB first и LSB first). Я в свое время делал бит-реверсию по алгоритму из книги Уорена мл. для передачи по SPI, так как там возможно лишь MSB first (в отличие от SSC, где порядок можно настроить). Как в УАРТе -- не знаю, не увлекался smile.gif


--------------------
شامل
Go to the top of the page
 
+Quote Post
Alex03
сообщение Nov 3 2006, 03:56
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(Edmundo @ Nov 3 2006, 02:07) *
Я в свое время делал бит-реверсию по алгоритму из книги Уорена


А что за алгоритм?
Случайно не так:
Код
   BYTE b;
   b = ((b<<4) & 0xF0) | ((b>>4) & 0x0F);
   b = ((b<<2) & 0xCC) | ((b>>2) & 0x33);
   b = ((b<<1) & 0xAA) | ((b>>1) & 0x55);


Если нет то расскажите. smile.gif
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Nov 3 2006, 05:08
Сообщение #11


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Цитата(Alex03 @ Nov 3 2006, 06:56) *
А что за алгоритм?
Случайно не так:
Код
   BYTE b;
   b = ((b<<4) & 0xF0) | ((b>>4) & 0x0F);
   b = ((b<<2) & 0xCC) | ((b>>2) & 0x33);
   b = ((b<<1) & 0xAA) | ((b>>1) & 0x55);


Если нет то расскажите. smile.gif

Алгоритм такой (он эффективен для однотактового умножения):

Код
static inline unsigned char BitReverse(unsigned char cByte)
{
    int nU = (cByte*0x00020202),
        nM = 0x01044010,
        nS = nU & nM,
        nT = (nU << 2) & (nM << 1);
    return ((nS+nT)*0x01001001) >> 24;
}

Там можно код чуть соптимизировать, уменьшить число операций за счет констант, но меня по производительности устраивало, поэтому оставил форму как из книги smile.gif


--------------------
شامل
Go to the top of the page
 
+Quote Post
Redaer
сообщение Nov 3 2006, 07:19
Сообщение #12


Участник
*

Группа: Новичок
Сообщений: 19
Регистрация: 12-07-06
Пользователь №: 18 762



Я реверсию битов сделал

Вот ещё вопрос, когда, во флешь что-то пишешь, её нужно предварительно очистить(как я понял, забить 0xFF). Но во флеше, насколько я знаю, хранится таблица векторов прерываний, она не сотрется? И вообще, какой у нее адрес?
З.Ы. Начинаю писать с такого адреса 0x100000
Go to the top of the page
 
+Quote Post
vmp
сообщение Nov 3 2006, 07:28
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 20-01-05
Из: Зеленоград
Пользователь №: 2 070



Посмотри внимательно, ты случайно не ставишь бит MSBF (16 бит) в регистре US_MR?
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Nov 4 2006, 15:58
Сообщение #14


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Цитата(Redaer @ Nov 3 2006, 10:19) *
Вот ещё вопрос, когда, во флешь что-то пишешь, её нужно предварительно очистить(как я понял, забить 0xFF). Но во флеше, насколько я знаю, хранится таблица векторов прерываний, она не сотрется? И вообще, какой у нее адрес?
З.Ы. Начинаю писать с такого адреса 0x100000

Ну это уже вопросы к doc6175. А после внимательного прочтения сюда, если что не ясно.


--------------------
شامل
Go to the top of the page
 
+Quote Post
Redaer
сообщение Nov 14 2006, 12:48
Сообщение #15


Участник
*

Группа: Новичок
Сообщений: 19
Регистрация: 12-07-06
Пользователь №: 18 762



2vmp, MSBF в нуле...



2Edmundo, как я понял, регистр векторов прерываний находится вот здесь, то есть затереть я его никак не могу своими действиями:

Цитата
AIC_IVR is mapped at the absolute address 0xFFFFF100 and thus accessible from the ARM interrupt vector at address 0x00000018


[/size]

Можно тогда ещё вопрос по получению информации по уарту и записи её во flash?

Я посылаю 256 байт зараз по уарту и принимаю их в буфер, который потом записываю во flash, так вот... Если просто запускаю программу(слушающую и записывающую), то во flash ничего не пишется(когда читаю из неё, то получаю F0 00 00 00 FF FF FF и т.д.)

Ежели по шагам выполняю программу со свеверменной подачей порций информации, то все отлично записывается, что я не так делаю?



Код вот такой:

Код
         while(1) {
          while(!(AT91F_US_RxReady(AT91C_BASE_US1)));
            AT91F_Flash_Write(testAdr, 256, buff_rx);
            COM1->US_RPR = (unsigned int)&buff_rx[0];
            COM1->US_RCR = 256;
          testAdr += 0x100;
        }
[size="2"][/size]




[size="2"]AT91F_Flash_Write - процедура записи во flash:


- дизактивация прерываний

- запись во flash

- активация прерываний

Go to the top of the page
 
+Quote Post

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

 


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


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