Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Программирование сегмента данных F5xxx
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
varvar
Не подскажете, в чем разница программирования сегментов данных 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
}


Где опять собака могла порыться?
V_N
Вставте проверку готовности после стирания и
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
}
varvar
Что-то у меня все-таки с установками намудрено - не нравится что-то процессору
Код такой:
Код
#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
}

Вроде все как в Вашем сообщении - вот только не работает. Какое было содержимое до попытки программирования, то и осталось.
rezident
Вот фрагмент функции программирования 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;
varvar
Что-то потихоньку задышало - но истоки непонятны
Когда объявляешь данные
Код
#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 никогда не разблокируются, хотя примеры явно к инфо сегментам относятся.
rezident
Цитата(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 перед записью.
varvar
Цитата(rezident @ Mar 25 2013, 00:09) *
Бит LOCKA имеет особенность. Это toggle-bit. Он изменяет (на противоположное) свое состояние при записи в него 1. А при записи 0 не изменяет. См. описание в User's Manual.

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

Это я в курсе - и в своей программе я этот сегмент не трогаю (в тексасовских примерах тоже используются C и D)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.