W7500P UART1 does not receive

Anyone else having this problem?

When attempting to receive on UART1 RxD (Pin 24, PA10) you can transmit but not receive.
UART0 and UART2 (different driver for UART2) both work OK.

This happens on the Wizwiki board and on our PCB.


What is using firmware code??

W7500 code is together working to GPIO and PAD(alternative) setting.

So i think, not working initial to UART1.

Thank you

Edward, are you saying that you think that the problem is in the initialisation code for UART1?
If so, why does it work correctly when modified to work with UART0 and UART2, and why does transmit work on UART1?

We have confirmed that the pin works when initialised as GPIO.

I’m happy to send you the initialisation code. What is the procedure for this?

My code is encapsulated in C++ classes, I’ve cut & pasted the relevant init code here:

UART *UART::_handlerMap = { 0 }; // Init the static member.


// Set UART clock to internal 8MHz oscillator.

// Set up a dummy “/dev/null” serial port.
: _def(0)
, _uart(0)
, _portnum(-1)
, _interruptNum(0)
, _sendData(0)
, _sendDataSize(0)
, _recvDataSize(0)
, _recvDataLastTick(0)

// Set up a port based on the given parameters.
UART::UART(const UART_DEF &init, unsigned portnum)
: _def(&init)
, _portnum(portnum)
, _sendData(0)
, _sendDataSize(0)
, _recvDataSize(0)
, _recvDataLastTick(0)
// Set up a pointer to our interrupt handler.
_handlerMap[_def->nIrq - UART0_IRQn] = this;

// Route GPIO to UART.
// Only route the receive pin. The transmit pin is shared with an IR sender.
GPIO_Configuration(_def->gpio, _def->gpioPinRX, GPIO_Mode_AF, _def->padType);

// Pointer to the UART peripheral.
_uart = init.uart;

// Disable the UART while setting up.

// Enable both receive and transmit.
_uart->CR = UART_Mode_Rx | UART_Mode_Tx;

// Set up the port with default parameters.
UartParams initParams;


// Set to trigger an interrupt on receive.

// Enable our interrupt.

_recvData[0] = _uart->DR; // See if this kicks off the receive interrupt.


Sorry, please ignore that last post. The code is spread across a bunch of files, I have to cut out the relevant bits and collate it together. Here it is:

void uartInit(unsigned baud)
// Set UART clock to internal 8MHz oscillator.

// Route GPIO to UART.
GPIO_Configuration(GPIOA, GPIO_Pin_10, GPIO_Mode_AF, PAD_AF2);
GPIO_Configuration(GPIOA, GPIO_Pin_9, GPIO_Mode_AF, PAD_AF2);

// Enable both receive and transmit.
UART1->CR = UART_Mode_Rx | UART_Mode_Tx;

// Disable the UART while making changes.

// Set baud rate.
float baud_divisor = ((float)UART_FOSC / (16 * baud));
uint32_t integer_baud    = (uint32_t)baud_divisor;
uint32_t fractional_baud = (uint32_t)((baud_divisor - integer_baud) * 64 + 0.5);
UART1->IBRD = integer_baud;
UART1->FBRD = fractional_baud;

// Set up parity, start and stop bits. The FIFO can also be set here.
UART1->LCR_H = UART_WordLength_8b | UART_StopBits_1 | UART_Parity_No;


// Set to trigger an interrupt on receive.

// Enable our interrupt.



First, refer to below link

wizwiki.net/wiki/doku.php?id=pro … herals:afc

It is W7500 alternative function table.

for example, if you chooce UART1 to PA_07 ~ PA10 pin, It is 3rd alternative function.

So, You must setting PAD_AF3. not setting PAD_AF2.

ex) GPIO_Configuration(GPIOA, GPIO_Pin_10, GPIO_Mode_AF, PAD_AF3);

I again say, W7500 code is together working to GPIO and PAD(alternative) setting.

Thank you

Well I tried changing the AF to PAD_AF3 and as expected, we now have no transmit or receive. AF2 is the correct setting. AF3 is for PWM function.

Perhaps you are confusing the function number with the pad selection value. This is how it works:

Normal function: PAD_AF0

2nd function: PAD_AF1

3rd function: PAD_AF2

4th function: PAD_AF3

While the AF3 pad thing is not the right solution, thinking about pads and pin routing has given me an idea.

All the pads default to AF0 on boot, so that means that U_RXD1 will be mapped to PC03 (pin 56) by default. I’m mapping it to PA10 (pin 38) by setting PAD2 but it will still be mapped to PC03 as well, which will create a contention.

So I added these lines to un-map it from its default pads:

GPIO_Configuration(GPIOC, GPIO_Pin_2, GPIO_Mode_AF, PAD_AF1);
GPIO_Configuration(GPIOC, GPIO_Pin_3, GPIO_Mode_AF, PAD_AF1);

And now I am receiving!

It’s not displaying the received bytes - but I think that’s a bug in my buffering code. Using the debugger, I can see the receive interrupt occur and the data byte arrive.


I checking this problem.

And later I will answer.

Thank you.

Thank you very much for this solution to the problem!