2020-06-18 12:47 AM
I'm developing an IoT device for a customer and I have an external Bluetooth SoC connected to the ST's MCU via UART. The BT SoC shares its UART Tx pin with reset functionality so I need to develop a driver to momentarily turn the UART to GPIO mode to reset the device followed by return to UART mode to carry on with the communication.
As a first step I'm doing a Proof of Concept -like solution where I use a normal tty driver (usart3) to communicate and a second custom driver to highjack the GPIO peripheral.
The issue is that I don't seem to be able to read any values out of the GPIO registers except for 0. Here is the code I'm using for testing the GPIO access:
static const uint32_t GPIO_BASE = 0x50003000;
static const uint32_t GPIO_LAST = GPIO_BASE + 0x3fc;
ssize_t show_debug_attr(struct kobject* kobj, struct kobj_attribute* attr,
char* buf) {
ssize_t written = 0;
uint32_t i;
volatile void __iomem* ptr =
ioremap_nocache(GPIO_BASE, GPIO_LAST - GPIO_BASE);
if (!ptr) {
return -EIO;
}
for (i = 0; i <= GPIO_LAST - GPIO_BASE; i += 4) {
writel(0xffffffff, ptr + i);
uint32_t val = readl(ptr + i);
written += snprintf(buf + written, PAGE_SIZE - written, "%i, ", val);
}
iounmap(ptr);
written += snprintf(buf + written, PAGE_SIZE - written, "\n");
return written;
}
The code above only prints zeroes. I've disabled the tty using the same peripheral. Also gpioset/get tools in linux seem to work fine.
2021-07-23 08:43 AM
Hi,
I think my reply is too late :face_with_tears_of_joy:. So, as you wrote in your post, we should use the solution suggested from ST to control gpios via pinctrl/gpiolib + devicetree. You could find a simple example at https://wiki.st.com/stm32mpu/wiki/How_to_control_a_GPIO_in_kernel_space
In other hand, if you still control your gpio pins directly, I think you need refer more in reference manual, at RCC section. I think RCC_MP_AHB4ENSETR is ưhat you want. You must set these bits to enable peripheral clock from MP side before access them.
Hope it useful with you.
2021-07-26 01:02 AM
Hi,
don't know exactly what do you mean by "The BT SoC shares its UART Tx pin with reset functionality" nor what is your HW behind that.
Maybe look at sending a 'Break' on tty (break is forcing UART_TX pin to low, usually by a time in a range of tens or hundreds of ms).
This is somewhat more standard and might avoid to 'hack' the UART AFmux to GPIO (which is probably possible, but maybe not compliant/future proof regarding DT flexibility and Linux behavior)
Regards.