I'm using a STM32F103RB on an Olimexino STM32 board from Olimex and try to get USART TX working with no success so far. Some more details about my setup:
- I use the Maple bootloader, so I changed the linkerscripts and VTOR accordingly and use the dfu-util to flash my software
- I use the USB CDC example in my test program which works like a charm
- I attached another USB <-> USART (FTDI FT232RL based) to the processors USART2 RX/TX pins.
- On my computer I have two terminals open: One to communicate with the FTDI chip (which forwards to the STM32's USART2) and one to access the STM32's own USB CDC serial device.
In my program I forward characters received from USART2 to the SerialOverUSB connection. This works like a charm. However if I try to transmit something on USART2 nothing is happening at the TX pin PA2 (verified using an oscilloscope).
For the USART usage I copied the demo program and modified it accordingly to my board. Every time something is received or transmitted, the yellow LED on the board is flashed. This works correctly even though I don't see anything on the TX pin, so the callback functions are called correctly.
What could be the problem here? Could it be related to some initialization the Maple bootloader does? Unfortunately I don't have any debugger hardware.
I also tried using USART1 - it is the same there.
My code with respect to the USART2 is as follows:
Code: Select all
/*
* UART Callback functions
*/
static VirtualTimer vt1, vt2;
static void restart(void *p) {
(void)p;
chSysLockFromIsr();
uartStartSendI(&UARTD2, 14, "Hello World!\r\n");
chSysUnlockFromIsr();
}
static void ledoff(void *p) {
(void)p;
palClearPad(GPIOA, GPIOA_YELLOW_LED);
}
/*
* This callback is invoked when a transmission buffer has been completely
* read by the driver.
*/
static void txend1(UARTDriver *uartp) {
(void)uartp;
palSetPad(GPIOA, GPIOA_YELLOW_LED);
}
/*
* This callback is invoked when a transmission has physically completed.
*/
static void txend2(UARTDriver *uartp) {
(void)uartp;
palClearPad(GPIOA, GPIOA_YELLOW_LED);
chSysLockFromIsr();
if (chVTIsArmedI(&vt1))
chVTResetI(&vt1);
// Call restart() after given time
chVTSetI(&vt1, MS2ST(50), restart, NULL);
chSysUnlockFromIsr();
}
/*
* This callback is invoked when a character is received but the application
* was not ready to receive it, the character is passed as parameter.
*/
static void rxchar(UARTDriver *uartp, uint16_t c) {
(void)uartp;
// Forward character on to SDU1
chprintf((BaseSequentialStream *)(&SDU1), "RECVD: %c\r\n", c);
/* Flashing the LED each time a character is received.*/
palSetPad(GPIOA, GPIOA_YELLOW_LED);
chSysLockFromIsr();
if (chVTIsArmedI(&vt2))
chVTResetI(&vt2);
chVTSetI(&vt2, MS2ST(200), ledoff, NULL);
chSysUnlockFromIsr();
}
/*
* UART driver configuration structure.
*/
static UARTConfig uart_cfg_2 = {
txend1,
txend2,
NULL,
rxchar,
NULL,
9600,
0,
0, //USART_CR2_LINEN,
0
};
/*
* Application entry point.
*/
int main(void) {
/*
* Early pad initialization
*/
palSetPadMode(GPIOA, 2, PAL_MODE_STM32_ALTERNATE_PUSHPULL); // USART2-TX
palSetPadMode(GPIOA, 3, PAL_MODE_INPUT); // USART2-RX
/*
* System initializations.
* - HAL initialization, this also initializes the configured device drivers
* and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
*/
halInit();
chSysInit();
/*
* Activates the uart driver 2 using the given configuration.
*/
uartStart( &UARTD2, &uart_cfg_2 );
/*
* Start transmission on UART2
*/
uartStartSend(&UARTD2, 13, "Starting...\r\n");
/*
* Normal main() thread activity, in this demo it does nothing except
* sleeping in a loop.
*/
while (TRUE) {
chThdSleepMilliseconds(1000);
}
}
P.S.: ChibiOS is a really great software. The examples and demos really helped me to get started quickly!