Цитата(shreck @ Mar 23 2012, 05:56)

Оп-па.
Из errat'ы.
The DBGMCU_IDCODE and DBGMCU_CR debug registers are accessible only in debug
Такое верно для 101/102/103. В 100 идентификатор читается нормально, 105/107 вроде бы тоже (на практике не пробовал).
Цитата(shreck @ Mar 23 2012, 05:56)

Вопрос остается в силе. Как можно узнать размер страницы памяти, кроме как записать/стереть/посмотреть, что получилось.
Есть еще ячейка служебной флеши по адресу 0x1FFFF7E0 (документирована даже - 30-ый раздел "Reference Manual"-а) - там размер флеша указан (если производитель при прошивке своей служебки ненакосячил).
Ну а полностью узнать какой процессор можно так:
CODE
static DWORD hal_stm32_id(void)
{
DWORD fsize, clken, lock;
lock = hal_lock_interrupt();
{
DWORD save;
//
// Выполняем распознавание 101/102/103 по тактируемым блокам
// Кратковременно разрешаем тактирование USB и CAN,
//
save = RCC_APB1EN;
RCC_APB1EN = save
| bRCC_CAN2EN
| bRCC_CAN1EN
| bRCC_USBEN;
clken = RCC_APB1EN;
//
// Восстанавливаем исходное состояние тактирования
//
RCC_APB1EN = save;
}
hal_unlock_interrupt(lock);
if ((clken & bRCC_USBEN) == 0)
{
//
// STM32F101xx - так как нет контроллера USB FS
//
clken = 101;
}
else
{
if ((clken & bRCC_CAN1EN) == 0)
{
//
// STM32F102xx - так как нет контроллера CAN
//
clken = 102;
}
else
{
//
// Это STM32F103 - так как есть и USB FS и CAN
//
clken = 103;
}
}
fsize = SYSMEM_FSIZE & 0x0000FFFF;
switch(DBGMCU_IDCODE & STM32_ID_MASK)
{
//
// Процессоры 101/102/103 - 468BCDE имеют
// недоступными регистр IDCODE в рабочем
// режиме - читаются нули (см errata)
//
case STM32_ID_000:
{
switch(clken)
{
case 101:
{
switch(fsize)
{
case 16: return STM32F101x4_ID;
case 32: return STM32F101x6_ID;
case 64: return STM32F101x8_ID;
case 128: return STM32F101xB_ID;
case 256: return STM32F101xC_ID;
case 384: return STM32F101xD_ID;
case 512: return STM32F101xE_ID;
}
break;
}
case 102:
{
switch(fsize)
{
case 16: return STM32F102x4_ID;
case 32: return STM32F102x6_ID;
case 64: return STM32F102x8_ID;
case 128: return STM32F102xB_ID;
}
break;
}
case 103:
{
switch(fsize)
{
case 16: return STM32F103x4_ID;
case 32: return STM32F103x6_ID;
case 64: return STM32F103x8_ID;
case 128: return STM32F103xB_ID;
case 256: return STM32F103xC_ID;
case 384: return STM32F103xD_ID;
case 512: return STM32F103xE_ID;
}
break;
}
}
break;
}
case STM32_ID_420:
{
//
// STM32F100-468B
//
switch(fsize)
{
case 16: return STM32F100x4_ID;
case 32: return STM32F100x6_ID;
case 64: return STM32F100x8_ID;
case 128: return STM32F100xB_ID;
}
break;
}
case STM32_ID_428:
{
//
// STM32F100-CDE
//
switch(fsize)
{
case 256: return STM32F100xC_ID;
case 384: return STM32F100xD_ID;
case 512: return STM32F100xE_ID;
}
break;
}
case STM32_ID_410:
{
//
// STM32F10x-8B
//
switch(clken)
{
case 101:
{
switch(fsize)
{
case 64: return STM32F101x8_ID;
case 128: return STM32F101xB_ID;
}
break;
}
case 102:
{
switch(fsize)
{
case 64: return STM32F102x8_ID;
case 128: return STM32F102xB_ID;
}
break;
}
case 103:
{
switch(fsize)
{
case 64: return STM32F103x8_ID;
case 128: return STM32F103xB_ID;
}
break;
}
}
break;
}
case STM32_ID_412:
{
//
// STM32F10x-46
//
switch(clken)
{
case 101:
{
switch(fsize)
{
case 16: return STM32F101x4_ID;
case 32: return STM32F101x6_ID;
}
break;
}
case 102:
{
switch(fsize)
{
case 16: return STM32F102x4_ID;
case 32: return STM32F102x6_ID;
}
break;
}
case 103:
{
switch(fsize)
{
case 16: return STM32F103x4_ID;
case 32: return STM32F103x6_ID;
}
break;
}
}
break;
}
case STM32_ID_414:
{
//
// STM32F10x-CDE
//
switch(clken)
{
case 101:
{
switch(fsize)
{
case 256: return STM32F101xC_ID;
case 384: return STM32F101xD_ID;
case 512: return STM32F101xE_ID;
}
break;
}
case 103:
{
switch(fsize)
{
case 256: return STM32F103xC_ID;
case 384: return STM32F103xD_ID;
case 512: return STM32F103xE_ID;
}
break;
}
}
break;
}
case STM32_ID_430:
{
//
// STM32F10x-FG
//
switch(clken)
{
case 101:
{
switch(fsize)
{
case 768: return STM32F101xF_ID;
case 1024: return STM32F101xG_ID;
}
break;
}
case 103:
{
switch(fsize)
{
case 768: return STM32F103xF_ID;
case 1024: return STM32F103xG_ID;
}
break;
}
}
break;
}
case STM32_ID_418:
{
//
// STM32F105/107 отличаем по блоку Ethernet
//
lock = hal_lock_interrupt();
{
DWORD save;
save = RCC_AHBEN;
RCC_AHBEN = save
| bRCC_ETHMACEN;
clken = RCC_AHBEN;
//
// Восстанавливаем исходное состояние тактирования
//
RCC_AHBEN = save;
}
hal_unlock_interrupt(lock);
if (clken & bRCC_ETHMACEN)
{
switch(fsize)
{
case 128: return STM32F107xB_ID;
case 256: return STM32F107xC_ID;
}
}
else
{
switch(fsize)
{
case 64: return STM32F105x8_ID;
case 128: return STM32F105xB_ID;
case 256: return STM32F105xC_ID;
}
}
break;
}
case STM32_ID_411: // F20x/F21x
case STM32_ID_413: // F40x/F41x
{
//
// Эти серии в рамках этой функции не поддерживаются
//
HAL_ASSERT(FALSE, "Not recognized chip ID");
break;
}
}
return 0;
}