Возникла проблема при работе с интерфейсом SSP на ARM LPC1769.
Для начала я инициализировал интерфейс:
1) В регистре PCONP - Power Control
2) PCLKSEL - Clock (поставил cclk/4)
3) PINSEL - выставил требуемые значения для CLK,SSEL,MISO,MOSI
4) SSP0CR0 - выставил 0x000F, что соответствует 16 битной передаче, CPOL=0 и CPHA=0
SSP0CR1 - выставил 0x0000, что соответствует режиму MASTER, затем выставил бит SSE=1 в этом регистре, что соответствует:
The SSP controller will interact with other devices on the serial bus. Software should write the appropriate control information to the other SSP registers and interrupt controller registers, before setting this bit.
5) SSP0CPSR - выставил второй бит.
Таким образом инициализация интерфейса SSP выглядит так:
Код
void SSP0Init( void )
{
uint8_t i;
uint16_t Dummy=Dummy; //Changed to uint16_t
/* Enable AHB clock to the SSP0. */
LPC_SC->PCONP |= (0x1<<21);
/* Further divider is needed on SSP0 clock. Using default divided by 4 */
LPC_SC->PCLKSEL1 &= ~(0x3<<10);
/* P0.15~0.18 as SSP0 */
LPC_PINCON->PINSEL0 &= ~(0x3UL<<30);
LPC_PINCON->PINSEL0 |= (0x3UL<<30);
LPC_PINCON->PINSEL1 &= ~((0x3<<0)|(0x3<<2)|(0x3<<4));
LPC_PINCON->PINSEL1 |= ((0x2<<0)|(0x2<<2)|(0x2<<4));
/* Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 15 */
LPC_SSP0->CR0 = 0x000F;
LPC_SSP0->CR1 = 0x0000; //ADD by ME
/* SSPCPSR clock prescale register, master mode, minimum divisor is 0x02 */
LPC_SSP0->CPSR = 0x2;
for ( i = 0; i < FIFOSIZE; i++ )
{
Dummy = LPC_SSP0->DR; /* clear the RxFIFO */
}
// /* Master mode */
LPC_SSP0->CR1 = SSPCR1_SSE;
/* Set SSPINMS registers to enable interrupts */
/* enable all error related interrupts */
LPC_SSP0->IMSC = SSPIMSC_RORIM | SSPIMSC_RTIM;
return;
}
{
uint8_t i;
uint16_t Dummy=Dummy; //Changed to uint16_t
/* Enable AHB clock to the SSP0. */
LPC_SC->PCONP |= (0x1<<21);
/* Further divider is needed on SSP0 clock. Using default divided by 4 */
LPC_SC->PCLKSEL1 &= ~(0x3<<10);
/* P0.15~0.18 as SSP0 */
LPC_PINCON->PINSEL0 &= ~(0x3UL<<30);
LPC_PINCON->PINSEL0 |= (0x3UL<<30);
LPC_PINCON->PINSEL1 &= ~((0x3<<0)|(0x3<<2)|(0x3<<4));
LPC_PINCON->PINSEL1 |= ((0x2<<0)|(0x2<<2)|(0x2<<4));
/* Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 15 */
LPC_SSP0->CR0 = 0x000F;
LPC_SSP0->CR1 = 0x0000; //ADD by ME
/* SSPCPSR clock prescale register, master mode, minimum divisor is 0x02 */
LPC_SSP0->CPSR = 0x2;
for ( i = 0; i < FIFOSIZE; i++ )
{
Dummy = LPC_SSP0->DR; /* clear the RxFIFO */
}
// /* Master mode */
LPC_SSP0->CR1 = SSPCR1_SSE;
/* Set SSPINMS registers to enable interrupts */
/* enable all error related interrupts */
LPC_SSP0->IMSC = SSPIMSC_RORIM | SSPIMSC_RTIM;
return;
}
При отладке видно, что все пины инициализированы как надо и SSP работает в формате SPI. В main добавил:
Код
for ( i = 0; i < 1000; i++ )
{
uint8_t *k;
k = (uint8_t *) i;
sprintf(text, "0x%04X", k);
GLCD_DisplayString (7, 8, 1, (unsigned char *)text);
SSPSend( 0, (uint16_t *) text, 16);
os_dly_wait (100);
}
{
uint8_t *k;
k = (uint8_t *) i;
sprintf(text, "0x%04X", k);
GLCD_DisplayString (7, 8, 1, (unsigned char *)text);
SSPSend( 0, (uint16_t *) text, 16);
os_dly_wait (100);
}
Однако SPI не работает, осциллограф показывает следующее Нажмите для просмотра прикрепленного файла
(синий -MOSI, красный - CLK)
Функция передачи данных:
Код
void SSPSend( uint32_t portnum, uint16_t *buffer, uint32_t Length )
{
uint32_t i;
uint16_t Dummy = Dummy;
for ( i = 0; i < Length; i++ )
{
/* Move on only if NOT busy and TX FIFO not full. */
while ( (LPC_SSP0->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF );
LPC_SSP0->DR = *buffer;
buffer++;
/* Wait until the Busy bit is cleared. */
while ( LPC_SSP0->SR & SSPSR_BSY );
}
return;
}
{
uint32_t i;
uint16_t Dummy = Dummy;
for ( i = 0; i < Length; i++ )
{
/* Move on only if NOT busy and TX FIFO not full. */
while ( (LPC_SSP0->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF );
LPC_SSP0->DR = *buffer;
buffer++;
/* Wait until the Busy bit is cleared. */
while ( LPC_SSP0->SR & SSPSR_BSY );
}
return;
}
Почему на осциллографе не видно сигналов CLK и MOSI по сути ни каких данных не выставляет, а только выдает импульсы напряжения?