К отладочной плате olymex была варварски припаяна (так как свободно-торчащих пинов на плате нет) самодельная светодиодная матрица 2х2 (схему матрицы могу приложить, если нужно).
Какое-то время мой код для работы с этой матрицей работал без нареканий, а потом в один прекрасный момент я решил поднять частоту процессора (заюзав PLL) до 100 МГц. Светодиоды гореть перестали.
Это явление было не очень стабильным, на разных частотах код вел себя по-разному и не всегда одинаково.
На четвертый день разборок бажный код редуцировался до вот такого фрагмента, который должен выключать все светодиоды. В таком виде код работает.:
Код
LPC_GPIO1->FIOPIN |= (1<<14 | 1<<15);
LPC_GPIO1->FIOPIN &= ~(1<<16 | 1<<17);
LPC_GPIO1->FIOPIN &= ~(1<<16 | 1<<17);
А вот в таком - нет. PLL в обоих случаях отключен, проц тактируется от внутренней цепочки на 4Мгц.
Код
uint32_t tempPin;
uint32_t mask;
uint32_t temp;
tempPin = LPC_GPIO1->FIOPIN;
mask = (1<<14 | 1<<15);
tempPin |= mask;
LPC_GPIO1->FIOPIN = tempPin;
tempPin = LPC_GPIO1->FIOPIN;
mask = (1<<16 | 1<<17);
tempPin &= ~mask;
uint32_t mask;
uint32_t temp;
tempPin = LPC_GPIO1->FIOPIN;
mask = (1<<14 | 1<<15);
tempPin |= mask;
LPC_GPIO1->FIOPIN = tempPin;
tempPin = LPC_GPIO1->FIOPIN;
mask = (1<<16 | 1<<17);
tempPin &= ~mask;
При пошаговой отладке работают оба варианта. Если вот этот момент
Код
LPC_GPIO1->FIOPIN = tempPin;
tempPin = LPC_GPIO1->FIOPIN;
tempPin = LPC_GPIO1->FIOPIN;
не делать (или вставить задержку в пару тактов между этими строчками), то все работает. Т.е., насколько я понимаю, значение в регистре толи меняется, толи считывается недостаточно быстро.
Вопрос: прав ли я или проблема может быть в чем-то другом? Если я прав, где в даташите это описано или как это вообще гуглить, что делать? <_>