Доброго времени суток!
Keil 5.23 + Jet-Link ultra, Pack: Keil.LPC1700_DFP 2.4.0
Для SSP использую CMSIS Keil.
Контроллер LPC1778, используемые девайсы: три таймера, 5 UART, MCI, TRC, DAC, 3 SSP, WDT (при отладке отключен).
Наблюдается проблема при обработки прерывания от SSP1 после сброса reset-ом.
Инициализация SSP1
Код
extern ARM_DRIVER_SPI Driver_SPI1;
static ARM_DRIVER_SPI *SpiDrv;
SpiDrv = &Driver_SPI1;
SpiDrv->Initialize( NULL );
#ifdef PRIORITY_SSP1
NVIC_SetPriority( SSP1_IRQn, PRIORITY_SSP1 );
#endif
SpiDrv->PowerControl( ARM_POWER_FULL );
SpiDrv->Control( ARM_SPI_MODE_MASTER | ARM_SPI_CPOL0_CPHA0 | ARM_SPI_MSB_LSB | ARM_SPI_SS_MASTER_SW | ARM_SPI_DATA_BITS( 16 ), 1000000 );
SpiDrv->Control( ARM_SPI_CONTROL_SS, ARM_SPI_SS_INACTIVE );
Обмен данными через SSP1 рулит прерывание от одного из входов GPIO, инициализация
Код
GPIO_IntCmd( PORT0, IRQ_485_MASK, 1 ); //Falling edge
NVIC_ClearPendingIRQ( GPIO_IRQn );
NVIC_SetPriority( GPIO_IRQn, PRIORITY_GPIO );
NVIC_EnableIRQ( GPIO_IRQn );
Тут вопросов нет, все работает.
Инициализация SSP2
Код
extern ARM_DRIVER_SPI Driver_SPI2;
static ARM_DRIVER_SPI *SpiDrv;
SpiDrv = &Driver_SPI2;
SpiDrv->Initialize( &CallBackSPI2 );
#ifdef PRIORITY_SSP2
NVIC_SetPriority( SSP2_IRQn, PRIORITY_SSP2 );
#endif
SpiDrv->PowerControl( ARM_POWER_FULL );
SpiDrv->Control( ARM_SPI_MODE_SLAVE | ARM_SPI_CPOL0_CPHA0 | ARM_SPI_MSB_LSB | ARM_SPI_SS_SLAVE_HW | ARM_SPI_DATA_BITS( 8 ), SSP2_SPEED );
SpiDrv->Receive( &recv_data, 1 );
Обработка прерывания SSP2:
Код
static void CallBackSPI2( uint32_t event ) {
if ( event & ARM_SPI_EVENT_TRANSFER_COMPLETE ) {
flg_recv = true;
////////////////////////// переключаем пин для контроля работы
if ( GPIO_PinRead( TRC_PORT, EXT_RT ) )
GPIO_PinWrite( TRC_PORT, EXT_RT, 0 );
else GPIO_PinWrite( TRC_PORT, EXT_RT, 1 );
}
}
Из main-while(1)
Код
void SPIFlowCtrl( void ) {
if ( flg_recv == true ) {
flg_recv = false;
SpiDrv->Receive( &recv_data, 1 );
}
}
Приоритеты прерываний:
Код
//CMSIS NXP
#define PRIORITY_TIMER0 1
#define PRIORITY_TIMER1 2
#define PRIORITY_TIMER2 3
//CMSIS Keil
#define PRIORITY_USART0 5
#define PRIORITY_USART1 6
#define PRIORITY_USART2 7
#define PRIORITY_USART3 8
#define PRIORITY_USART4 9
//CMSIS Keil
#define PRIORITY_SSP0 10
#define PRIORITY_SSP1 11
#define PRIORITY_SSP2 12
//CMSIS NXP
#define PRIORITY_GPIO 13
#define PRIORITY_RTC 17
Пока не подключил прием одного байта:
Код
SpiDrv->Receive( &recv_data, 1 );
через SSP2, все работало четко без проблем.
Проблема наблюдается в следующем образом:
При включении питания все запускается и работает.
Если нажать reset (внешняя кнопка) начинаются проблемы с обработкой прерывания от SSP1, канал 1 – прерывание от SSP2 мастер передает 1 байт с интервалом 1 сек, канал2 – прерывание от SSP1

а должно быть так

Если контроллер запустить в режиме отладки F5, потом «Stop», сделать пару шагов и выйти – все продолжает работать нормально.
Перезапуск от WDT тоже приводит к кривой работе.
Как только убираю из кода строку SpiDrv->Receive( &recv_data, 1 ) (SSP2) – все работает.
После включения питания в RSID установлены биты: POR и EXTR, а после reset или выхода из отладки: POR EXTR SYSRESET.
Схема reset стандартная. Поломал уже весь мозг, не могу понять причину, может кто-то сталкивался с подобной проблемой ?