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

 
 
 
Reply to this topicStart new topic
> Программирование сегмента данных F5xxx
varvar
сообщение Mar 24 2013, 08:22
Сообщение #1


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

Группа: Участник
Сообщений: 93
Регистрация: 5-01-05
Из: Оулу
Пользователь №: 1 811



Не подскажете, в чем разница программирования сегментов данных F5xx и F1xx? В F1xx, как помнится, было ограничение по тактовой частоте и минимальному напряжению.
В F5xx таких ограничений не увидел, тем не менее код, по сути дела скопированный из примеров, ничего во флеш не записывает.
Частота 8 мгц (уменьшение до 1 не помогло), питание 3.3V.

Код
void BurnEeprom(void)
{
  char *Flash_ptrC;
  Flash_ptrC = (char *) 0x1880;             // Initialize info segment C ptr  
  __disable_interrupt();                    // 5xx Workaround: Disable global

  FCTL3 = FWKEY;                           // unlock info  
  FCTL1 = FWKEY+ERASE;                     // Set Erase bit  
  *Flash_ptrC = 0;                         // Dummy write to erase info seg С
  
// на всякий случай - 32ms
  for (volatile int i=0; i<10000; i++)
  {
    __no_operation();
    __no_operation();    
    __no_operation();        
  }
  
  FCTL1 = FWKEY+WRT;                       // Byte write
  for (int i=0; i<27; i++) *Flash_ptrC++ = EEPROM.RegMap[i];  
  FCTL1 = FWKEY;                            // Clear WRT bit
  FCTL3 = FWKEY+LOCK;                     //  lock info  

  __enable_interrupt();                    // 5xx Workaround
}


Где опять собака могла порыться?
Go to the top of the page
 
+Quote Post
V_N
сообщение Mar 24 2013, 09:04
Сообщение #2


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

Группа: Свой
Сообщений: 162
Регистрация: 12-01-09
Из: Харьков
Пользователь №: 43 270



Вставте проверку готовности после стирания и
while (FCTL3 & BUSY); // test busy

пеример из IAR

void write_block_int(void)
{
unsigned int i;
unsigned long * Flash_ptr;
Flash_ptr = (unsigned long *)0x10000; // Initialize write address
__disable_interrupt(); // 5xx Workaround: Disable global
// interrupt while erasing. Re-Enable
// GIE if needed
// Erase Flash
while(BUSY & FCTL3); // Check if Flash being used
FCTL3 = FWKEY; // Clear Lock bit
FCTL1 = FWKEY+ERASE; // Set Erase bit
*Flash_ptr = 0; // Dummy write to erase Flash seg
while(BUSY & FCTL3); // Check if Erase is done

// Write Flash
FCTL1 = FWKEY+BLKWRT+WRT; // Enable block write

for(i = 0; i < 64; i++)
{
*Flash_ptr++ = value++; // Write long int to Flash

while(!(WAIT & FCTL3)); // Test wait until ready for next byte
}

FCTL1 = FWKEY; // Clear WRT, BLKWRT
while(BUSY & FCTL3); // Check for write completion
FCTL3 = FWKEY+LOCK; // Set LOCK
}
Go to the top of the page
 
+Quote Post
varvar
сообщение Mar 24 2013, 11:53
Сообщение #3


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

Группа: Участник
Сообщений: 93
Регистрация: 5-01-05
Из: Оулу
Пользователь №: 1 811



Что-то у меня все-таки с установками намудрено - не нравится что-то процессору
Код такой:
Код
#pragma dataseg = INFOC                         // Info Flash Memory Block c
static const uint8 FlashArray[27]=
{
0x28, 0x96, 0xC8, 0x96, 0x68, 0x97,
0x88, 0x13, 0xC4, 0x09, 0x82, 0x06, 0xE2, 0x04,
0xE8, 0x03, 0x41, 0x03, 0xCA, 0x02, 0x71, 0x02,
0x03,
0x01,
10,
0x01,
0x01
};  
#pragma dataseg = default

struct sSetup
{
  uint16 Frequency[3];
  uint16 Tone[8];
  uint8 NumCH;
  uint8 PackGap;
  uint8 ToneTime;
  uint8 Delay;
  uint8 State;  
};  

union
{
  sSetup Setup;
  uint8 RegMap[27];
} EEPROM;  

void BurnEeprom(void)
{
  char *Flash_ptrC;
  Flash_ptrC = (char *) 0x1880;             // Initialize info segment C ptr  
  __disable_interrupt();                    // 5xx Workaround: Disable global

  while(BUSY & FCTL3);                     // Check if Flash being used
  FCTL3 = FWKEY;                           // unlock info  
  FCTL1 = FWKEY+ERASE;                     // Set Erase bit  
  *Flash_ptrC = 0;                         // Dummy write to erase info seg A
  while(BUSY & FCTL3);                     // Check if Erase is done
  FCTL1 = FWKEY+WRT;                       // Byte write
  for (int i=0; i<27; i++)
  {
    *Flash_ptrC++ = EEPROM.RegMap[i];  
    while(!(WAIT & FCTL3));                // Test wait until ready for next byte
  }  
  FCTL1 = FWKEY;                           // Clear WRT bit
  while(BUSY & FCTL3);                     // Check for write completion
  FCTL3 = FWKEY+LOCK;                      //  lock info  

  __enable_interrupt();                    // 5xx Workaround
}

Вроде все как в Вашем сообщении - вот только не работает. Какое было содержимое до попытки программирования, то и осталось.
Go to the top of the page
 
+Quote Post
rezident
сообщение Mar 24 2013, 13:02
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Вот фрагмент функции программирования Flash-памяти MSP430F5438A, выполняющейся из Flash. Естественно, что сегмент предварительно стирается. В функции реализована попытка ускорения записи. Вначале идет запись байтами, потом словами и завершается вновь байтовой записью потому, что запись может быть с любого адреса во Flash (в т.ч. с нечетного). Пробовал еще ускорять записью 4-байтовыми блоками, но где-то ошибся с выравниванием на границу 32бита, в виду малого лимита времени плюнул и ограничился пословной записью.
Код
  pDst = (unsigned char *)addrDst; pSrc = (unsigned char *)addrSrc;
  WDreg = WDTCTL;
  WDTCTL = WDTPW | (WDreg & 0x00FF) | WDTHOLD; //останов WDT
  SRreg = __get_interrupt_state();
  __disable_interrupt(); //запрет прерываний
  if (type == IFLSH_SECT_INFO)
  { if ((addrD >= MSP430_FLASH_INFO_A_ADDR_START)&&
        (addrD <= MSP430_FLASH_INFO_A_ADDR_END)
       )
    { if ((FCTL3 & LOCKA) != 0) FCTL3 = FWPW | LOCKA; //clear LOCKA
    }
    FCTL3 = FWPW; //clear LOCK
    FCTL4 = FWPW; //clear LOCKINFO
  }
  else
  { FCTL3 = FWPW; //clear LOCK
    FCTL4 = FWPW | LOCKINFO; //set LOCKINFO
  }
  idxD = 0; idxS = 0; cntr = size;
  //вначале выровняем запись на четный адрес
  pDst = (unsigned char *)addrDst;
  pDstW = (unsigned short *)(addrDst & (~1UL));
  FCTL1 = FWPW | WRT; //запись батовая или словом
  if ((addrDst & (~1UL)) != addrDst) //нечетный адрес?
  { pDst[idxS] = pSrc[idxS];
    idxS += 1; idxD += 1; cntr -= 1;
  }
  //теперь можно писать по 16и битному слову за раз
  while (cntr > 2)
  { type = (unsigned short)(pSrc[idxS]);
    idxS +=1;
    type |= ((unsigned short)(pSrc[idxS]))<<8;
    idxS +=1;
    pDstW[idxD] = type; //запись слова
    idxD += 1; cntr -= 2;
  }
  //завершаем запись побайтно
//  FCTL1 = FWPW | WRT;
  while (cntr > 0)
  { pDst[idxS] = pSrc[idxS];
    idxS += 1; cntr -= 1;
  }
  FCTL1 = FWPW;
  if ((FCTL3 & LOCKA) != 0) FCTL3 = FWPW | LOCK;
  else                      FCTL3 = FWPW | LOCK | LOCKA;
  FCTL4 = FWPW | LOCKINFO;
  __set_interrupt_state(SRreg);  //востановим разрещение прерываний
  WDTCTL = WDTPW | (WDreg & 0x00FF) | WDTCNTCL; //восстановим работу WDTimer

Инициализация FTG, выполняемая после включения питания.
Код
  FCTL1 = FWPW;
  if ((FCTL3 & LOCKA) != 0)
    FCTL3 = FWPW | LOCK;
  else
    FCTL3 = FWPW | LOCK | LOCKA;
  FCTL4 = FWPW | LOCKINFO;
  SFRIE1 &= ~ACCVIE;
Go to the top of the page
 
+Quote Post
varvar
сообщение Mar 24 2013, 17:16
Сообщение #5


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

Группа: Участник
Сообщений: 93
Регистрация: 5-01-05
Из: Оулу
Пользователь №: 1 811



Что-то потихоньку задышало - но истоки непонятны
Когда объявляешь данные
Код
#pragma dataseg = INFOC                         // Info Flash Memory Block c
const uint8 FlashArray[27]=
{
0x28, 0x96, 0xC8, 0x96, 0x68, 0x97,
0x88, 0x13, 0xC4, 0x09, 0x82, 0x06, 0xE2, 0x04,
0xE8, 0x03, 0x41, 0x03, 0xCA, 0x02, 0x71, 0x02,
0x03,
0x01,
10,
0x01,
0x01
};  
#pragma dataseg = default

в сегменте С ничего нет, все данные в А
А когда так:
Код
const uint8 FlashArray[27]@0x1880=
{
0x28, 0x96, 0xC8, 0x96, 0x68, 0x97,
0x88, 0x13, 0xC4, 0x09, 0x82, 0x06, 0xE2, 0x04,
0xE8, 0x03, 0x41, 0x03, 0xCA, 0x02, 0x71, 0x02,
0x03,
0x01,
10,
0x01,
0x01
};

в С данные появляются, но из А они никуда не деваются.
Похоже, в опциях ИАРа нужно какую-то галку поставить/убрать, остается выяснить какую.

А примеры у тексаса ключница писала - по крайней мере lockinfo никогда не разблокируются, хотя примеры явно к инфо сегментам относятся.
Go to the top of the page
 
+Quote Post
rezident
сообщение Mar 24 2013, 20:09
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(varvar @ Mar 24 2013, 22:16) *
А примеры у тексаса ключница писала - по крайней мере lockinfo никогда не разблокируются, хотя примеры явно к инфо сегментам относятся.

Бит LOCKA имеет особенность. Это toggle-bit. Он изменяет (на противоположное) свое состояние при записи в него 1. А при записи 0 не изменяет. См. описание в User's Manual.
Цитата
LOCKA Bit 6 Segment A lock. Write a 1 to this bit to change its state. Writing 0 has no effect.
0 Segment A of the information memory is unlocked and can be written or erased in segment
erase mode.
1 Segment A of the information memory is locked and can not be written or erased in segment
erase mode.

По этой причине у меня в тексте стоит проверка его (бита LOCKA) состояния для разблокирования сегмента INFO_A перед записью.
Go to the top of the page
 
+Quote Post
varvar
сообщение Mar 25 2013, 08:40
Сообщение #7


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

Группа: Участник
Сообщений: 93
Регистрация: 5-01-05
Из: Оулу
Пользователь №: 1 811



Цитата(rezident @ Mar 25 2013, 00:09) *
Бит LOCKA имеет особенность. Это toggle-bit. Он изменяет (на противоположное) свое состояние при записи в него 1. А при записи 0 не изменяет. См. описание в User's Manual.

По этой причине у меня в тексте стоит проверка его (бита LOCKA) состояния для разблокирования сегмента INFO_A перед записью.

Это я в курсе - и в своей программе я этот сегмент не трогаю (в тексасовских примерах тоже используются C и D)
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 25th August 2025 - 05:35
Рейтинг@Mail.ru


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