2019-01-07 08:56 PM
Hi,
I am using STM32F405 micro-controller and interfacing enc28j60. The enc28j60 communicates on SPI, so I utilized SPI1 peripheral for that purpose using following pins:-
PA4 - CS
PA5 - SCK
PA6 - MISO
PA7 - MOSI
Now SPI1 works perfectly well with micro-controller however the problem arises when I configure PB10 as an alternate function for USART3.
After configuration when I read the registers of enc28j60, it does not return the values which is set by default in datasheet. As opposed to if I comment the USART3 configuration it work perfect fine.
Is there any relation of USART3(PB10) and SPI1 in STM32F405?
Could someone help in this regard.
Regards,
Muhammad Moiz khan
2019-01-07 11:34 PM
> Is there any relation of USART3(PB10) and SPI1 in STM32F405?
No, if there is no pin resource conflict.
I suspect a software related issue. Either you inadvertendly modify a SPI/GPIO peripheral setting when configuring UART3, or the UART interferes at runtime (interrupts). Showing some initialization code would help.
And an EMI interference between PCB tracks seems remotely possible.
2019-01-08 01:48 AM
Dear AvaTar,
I verified the PCB tracks it is fine, The thing that i noticed is that when I configure the PB10 back to GPIO from USART3_TX it works fine. Let me share my configurations.
void USART3_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// Enable GPIO clock
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10 , GPIO_AF_USART3);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11 , GPIO_AF_USART3);
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Enable the USART3 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); // Enable USART1 Receive Interrupt
USART_Init(USART3, &USART_InitStructure);
USART_Cmd(USART3, ENABLE);
}
void ENC28J60_SPI1_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;
/* Enable the SPI periph */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
/* SPI configuration -------------------------------------------------------*/
SPI_I2S_DeInit(SPI1);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
}
void ENC28J60_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable SCK, MOSI and MISO GPIO clocks */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* Enable CS GPIO clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
/* SPI SCK pin configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* SPI MOSI pin configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* SPI MISO pin configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure GPIO PIN for Chip select */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Deselect : Chip Select high */
GPIO_ResetBits(GPIOA, GPIO_Pin_4);
}
2019-01-08 02:27 AM
> I verified the PCB tracks it is fine, ...
I didn't expect anything else - both interfaces are relatively low power, and usually not EMI generators.
> void ENC28J60_GPIO_Configuration(void)
> {
>...
>
> /* Enable SCK, MOSI and MISO GPIO clocks */
> RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
>
> /* Enable CS GPIO clock */
> RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
...
Just one call would suffice, albeit calling it twice doesn't do harm.
I think the easiest way would be stepping through the UART initialization code in the debugger, and watch the SPI and GPIOA peripheral register settings. They should not change.
> USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); // Enable USART1 Receive Interrupt
I still not exclude an interrupt issue. Guessing SPI works with interrupts as well, the UART interrupt can block the SPI interrupt long enough to cause overflows when both have (the default) equal priorities.