2019-03-27 06:02 AM
I'm involved in the developmentof a project where I will use STM MCU that has the capability of multiprocessor communication ("Multiprocessor communication").
This type of communication allows multiple USARTs to be connected on the same network and only the recipient actively receives the contents of the message, for this to occur it is necessary to store the address of this MCU in a register.
So far so good, if only one word of address is used.
But I have to use more than one word of address, in this case, so whoever receives a valid address does the exchange of the address
next expected address, ie I make a new store in the registered MCU.
Now the problem.
When I use the MCU STM32F407 with serial at 115200 bps and the MCU clock at 48MHz, I send a sequence with 4 words and everything works fine,
now I do the same test with the MCU STM32F303, the MCU can only identify the first word and the other 3 not, if you send each word
of the sequence with a delay of 43uS the entire sequence is fully recognized.
I send the following sequence with 9-bit words:
0x101 0x102 0x103 0x104
2019-03-27 06:14 AM
> Could you confirm if this delay is required for the STM32F303?
I think not.
Your description is not quite clear, posting more information about the use case, setup, hardware and firmware involved would be helpful.
But serial communication is asynchronous in nature, I strongly suspect a software issue on the receiver side. Do you use Cube, and interrupt callbacks ?
2019-03-27 06:30 AM
I'm involved in the developmentof a project where I will use STM MCU that has the capability of multiprocessor communication ("Multiprocessor communication").
This type of communication allows multiple USARTs to be connected on the same network and only the recipient actively receives the contents of the message, for this to occur it is necessary to store the address of this MCU in a register.
So far so good, if only one word of address is used.
But I have to use more than one word of address, in this case, so whoever receives a valid address does the exchange of the address
next expected address, ie I make a new store in the registered MCU.
Now the problem.
When I use the MCU STM32F407 with serial at 115200 bps and the MCU clock at 48MHz, I send a sequence with 4 words and everything works fine,
now I do the same test with the MCU STM32F303, the MCU can only identify the first word and the other 3 not, if you send each word
of the sequence with a delay of 43uS the entire sequence is fully recognized.
I send the following sequence with 9-bit words:
0x101 0x102 0x103 0x104
(STM32F407)
RECORDER BIT FIELD VALUE
USART_CR1 WAKE 1
USART_CR2 ADD[3:0] 0001
USART_CR1 RWU 1
(STM32F303)
RECORDER BIT FIELD VALUE
USART_CR1 UE 0
USART_CR2 MME 1
USART_CR2 ADDM7 0
USART_CR1 WAKE 1
USART_CR2 ADD[3:0] 0001
USART_CR1 UE 1
USART_RQR MMRQ 1
Yes I use Cube, and interrupt callbacks.
2019-03-27 07:12 AM
I'm involved in the developmentof a project where I will use STM MCU that has the capability of multiprocessor communication ("Multiprocessor communication").
This type of communication allows multiple USARTs to be connected on the same network and only the recipient actively receives the contents of the message, for this to occur it is necessary to store the address of this MCU in a register.
So far so good, if only one word of address is used.
But I have to use more than one word of address, in this case, so whoever receives a valid address does the exchange of the address
next expected address, ie I make a new store in the registered MCU.
Now the problem.
When I use the MCU STM32F407 with serial at 115200 bps and the MCU clock at 48MHz, I send a sequence with 4 words and everything works fine,
now I do the same test with the MCU STM32F303, the MCU can only identify the first word and the other 3 not, if you send each word
of the sequence with a delay of 43uS the entire sequence is fully recognized.
I send the following sequence with 9-bit words:
0x101 0x102 0x103 0x104
(STM32F407)
RECORDER BIT FIELD VALUE
USART_CR1 WAKE 1
USART_CR2 ADD[3:0] 0001
USART_CR1 RWU 1
(STM32F303)
RECORDER BIT FIELD VALUE
USART_CR1 UE 0
USART_CR2 MME 1
USART_CR2 ADDM7 0
USART_CR1 WAKE 1
USART_CR2 ADD[3:0] 0001
USART_CR1 UE 1
USART_RQR MMRQ 1
Yes I use Cube, and interrupt callbacks.
#define SERIAL4_OFF() CLEAR_BIT (UART4->CR1, (USART_CR1_UE))
#define SERIAL4_ON() SET_BIT (UART4->CR1, (USART_CR1_UE))
#define SERIAL4_M_OFF() CLEAR_BIT (UART4->CR1, (USART_CR1_RE))
#define SERIAL4_M_ON() SET_BIT (UART4->CR1, (USART_CR1_RE))
#define SETUP_MULT_PROC() SET_BIT (UART4->CR1, (USART_CR1_MME));\
CLEAR_BIT (UART4->CR2, (USART_CR2_ADDM7));\
SET_BIT (UART4->CR1, (USART_CR1_WAKE));\
#define MUTE_MODE() SET_BIT (UART4->RQR, (USART_RQR_MMRQ))
#define STOP_COUNTER() CLEAR_BIT (TIM8->CR1, (TIM_CR1_CEN))
#define RUN_COUNTER() SET_BIT (TIM8->CR1, (TIM_CR1_CEN))
#define TIMEOUT_COUNTER(VAL) __HAL_TIM_SET_COUNTER(&htim8,VAL)
#define USART4_RECEIVE_ADDRESS() (uint16_t)(READ_REG(UART4->RDR) & 0x0100)
void startMultUart4(void) //Multi-processador.
{
//Create queue to usart 4
xQueueUsart4 = xQueueCreate(lenQueue4,sizeof( uint8_t ));
//Receive byte usart 4 by int.
HAL_UART_Receive_IT(&huart4,&receiveByte4,1);
//DESLIGA A SERIAL.
SERIAL4_OFF();
SETUP_MULT_PROC();
//STM32F407 -> SÓ 4 BITS DE ENDEREÇO.
flagAddress = 0;
WRITE_NIBBLE(flagAddress);
//LIGA A SERIAL.
SERIAL4_ON();
conv(counterState = 0);
//ENTRA EM MODO MUDO.
MUTE_MODE();
}
void HAL_UART_RxCpltCallbackUart4(UART_HandleTypeDef *huart)
{
BaseType_t xHigherPriorityTaskWoken;
UNUSED(huart);
conv(counterState = 0);
if(USART4_RECEIVE_ADDRESS())
{ conv(counterState = 1);
//PARA CONTADOR.
STOP_COUNTER();
//SETA CONTADOR.
TIMEOUT_COUNTER(30000);
if(flagAddress < 3)
{ conv(counterState = 2);
flagAddress++;
//DESLIGA A SERIAL.
SERIAL4_OFF();
WRITE_NIBBLE(flagAddress);
//LIGA A SERIAL.
SERIAL4_ON();
//DISPARA CONTADOR.
RUN_COUNTER();
//ENTRA EM MODO MUDO.
MUTE_MODE();
}
else
{ conv(counterState = 3);
flagAddress = 0;
//DESLIGA A SERIAL.
SERIAL4_OFF();
WRITE_NIBBLE(flagAddress);
//LIGA A SERIAL.
SERIAL4_ON();
}
}
else
{ conv(counterState = 4);
xHigherPriorityTaskWoken = pdFALSE;
//Send byte receive by usart 4 to queue.
xQueueSendFromISR( xQueueUsart4, &receiveByte4, &xHigherPriorityTaskWoken );
flagReceiveUsart4 = 1;
}
//Receive byte usart 4 by int.
HAL_UART_Receive_IT(huart,&receiveByte4,1);
}
2019-03-27 08:37 AM
Do you use the Hardware Flow Control signals (RTS/CTS)?
How much time is used in the UART Interrupt Handler routine?
(The fact that using a delay between the words works, indicates that the processor might be using too much time in the interrupt handler and that data is overrun.)
Which processor is the Slave?
How many slaves your system uses (max)?
What is the processor CPU clock currently used?
Do you have a logic analyzer (or at least an oscilloscope) to capture the serial port signals and transactions?
2019-03-27 08:52 AM
I was told that to use multiprocessor with USART, the LIN interface is more suitable.
Otherwise, SPI in daisy chain mode will support multi-processor at much higher speed although few tricks need to be applied for proper operation.
2019-03-27 09:31 AM
Do you use the Hardware Flow Control signals (RTS/CTS)? (No)
How much time is used in the UART Interrupt Handler routine? (Abouve 4uS)
Which processor is the Slave? (STM32F303)
2019-03-27 09:35 AM
How many slaves your system uses (max)? (Max 4)
What is the processor CPU clock currently used? (48MHz)
Do you have a logic analyzer (or at least an oscilloscope) to capture the serial port signals and transactions? (I do)
2019-03-27 09:45 AM
I use a USART with:
115200bps
9 bits
1 stop bit
2019-03-27 10:10 AM
I would recommend to enable the RTS/CTS signals for flow control, and to capture on the oscilloscope the 4 signals (TX, RX, RTS, CTS) during a transaction that fails. Please add the screen capture to this thread.
Also, please add a GPIO pin to monitor the UART Interrupt Handler (Set to HIGH when entering the Interrupt, and Set to LOW when leaving).