Добрый день!
FreeRTOS завел, даже думал написать краткий мануал, а потом понял, что мануал давно написан и называется FreeRTOS Porting Guide,
zltigo хоть и суров, но прав на 100%

Теперь взялся за ADC.
Последовательность такая: прочитал User Manual, посмотрел исходники для gcc, посмотрел библиотеку NXP (LPC CDL), подключил ее.
Причина использования библиотеки - любовь к функциям типа PINSEL_Set, оставшаяся от писания под SAM7S.
Итого получилось так:
Код
void xSetupADC(void)
{
// Select pin that used as ADC function
PINSEL_Set (PORT_0, 23, FUNC_1);
PINSEL_Set (PORT_0, 24, FUNC_1);
PINSEL_Set (PORT_0, 25, FUNC_1);
PINSEL_Set (PORT_0, 26, FUNC_1);
PINSEL_Set (PORT_1, 30, FUNC_3);
PINSEL_Set (PORT_1, 31, FUNC_3);
PINSEL_SetResistorMode(PORT_0,23,PINMODE_TRISTATE);
PINSEL_SetResistorMode(PORT_0,24,PINMODE_TRISTATE);
PINSEL_SetResistorMode(PORT_0,25,PINMODE_TRISTATE);
PINSEL_SetResistorMode(PORT_0,26,PINMODE_TRISTATE);
PINSEL_SetResistorMode(PORT_1,30,PINMODE_TRISTATE);
PINSEL_SetResistorMode(PORT_1,31,PINMODE_TRISTATE);
/* Init ADC device */
if ((adcdev = ADC_Init()) == 0)
{
while(1);
}
// Install ADC interrupt handler
if ((VIC_InstallIRQ (ADC0_INT, (void *) ADC_ISR, 0x0F)) == _ERROR)
{
while(1);
}
// Set call back function for ADC
//ADC_SetCBS (adcdev, (void *)usr_adc_cbs);
// Configure ADC with 1MHz of freq, 10-bit of resolution
ADC_Config (adcdev, 500000, 10);
// Enable all channels
ADC_EnableCH (adcdev, 0);
ADC_EnableCH (adcdev, 1);
ADC_EnableCH (adcdev, 2);
ADC_EnableCH (adcdev, 3);
ADC_EnableCH (adcdev, 4);
ADC_EnableCH (adcdev, 5);
// Enable interrupt for ADC0 channel 5
ADC_EnableInt (adcdev, 5);
//ADC_EnableGlobalInt(adcdev);
// Enable ADC interrupt source
VIC_EnableInt (ADC0_INT);
// Start ADC conversion
ADC_Start (adcdev, ADC_START_CONTINUOUS, 0);
}
ADC_Config пришлось подправить, ибо частоту я выставляю не через библиотечные функции:
Код
S32 ADC_Config (S32 ADCdev, U32 freq, U32 resolution)
{
ADC_CFG_T *pADCdev = (ADC_CFG_T *) ADCdev;
U32 tmp;
if (pADCdev->init == FALSE)
{
return _ERROR;
}
if ((resolution > 10) || (resolution < 3))
{
return _ERROR;
}
if (freq > 4500000)
{
return _ERROR;
}
tmp = SCB_GetPCLK (PCLK_ADC);
//tmp = (tmp / freq) - 1;
tmp = (30000000 / freq) -1;
pADCdev->regptr->CR &= ~(ADC_CR_CLKDIV(0xFF));
pADCdev->regptr->CR |= ADC_CR_CLKDIV(tmp);
pADCdev->regptr->CR &= ~(ADC_CR_BITS(3));
pADCdev->regptr->CR |= ADC_CR_BITS(resolution);
return _NO_ERROR;
}
Обработчик прерывания:
Код
__irq __arm void ADC_ISR (void)
{
//FIXME For debug
U32 regval;//= adccfg.regptr->STAT;
//FIXME For debug
volatile U32 ulStatus = AD0STAT;
volatile U32 dummy;
U8 i;
regval = ulStatus;
if (regval & 0x0000FF00) /* check OVERRUN error first */
{
regval = ADC_STAT_CH_OVERRUN_FLAG(regval);
//regval = AD0STAT;
// BUGBUG There are 6 channels, not 8
for (i = 0; i < 6; i++)
{
if (regval & 0x01)
{
/* if overrun, just read ADDR to clear */
dummy = adccfg.regptr->DR[i];
}
regval = regval >> 1;
}
}
// Check DONE bit
else if (regval & ADC_STAT_INT_FLAG)
{
regval = ADC_STAT_CH_DONE_FLAG(regval);
// BUGBUG There are 6 channels, not 8
for (i = 0; i < 6; i++)
{
if (regval & 0x01)
{
/* if overrun, just read ADDR to clear */
adccfg.ADCBuff[i] = adccfg.regptr->DR[i];
}
regval = regval >> 1;
}
}
// call callback function if it is already installed
if (adccfg.cbs != NULL)
{
adccfg.cbs();
}
if ((ulStatus & 0x3f) != 0x3f)
ulStatus=0;
// Acknowledge interrupt
VIC_Ack();
}
Чего хотел добиться:
1. Чтобы работали все 6 каналов.
2. Чтобы работало в Free run в Burst-режиме
3. Чтобы возникало одно прерывание при отработке всех 6 каналов.
4. Прерывание поставлено на 5 канал, потому что он должен отработаться последним:
The first conversion after the start corresponds to the least-significant 1 in the SEL field, then
higher numbered 1 bits (pins) if applicable.
В общем, ставлю я два брейка - один на VIC_Ack(), другой - на ulStatus=0, запускаю.
Дальше что-то, что я не понимаю.
Если стоит два брейка, то остановка происходит только на VIC_Ack(), и статусный регистр содержит 0x00013F3F, что более или менее соответствует ожиданиям. Не соответствует Overrun, происхождение которого я не понимаю.
Но стоит снять брейк с VIC_Ack(), начинает срабатывать брейк на ulStatus=0, при этом ulStatus == 0x00013C3C, т.е. каналы 0 и 1 не отработали.
Частоту АЦМ пробовал менять, история повторяется от 4.5МГц до 30кГц.
Вопрос традиционный: что я делаю не так?
Заранее спасибо!