2008-01-15 07:07 AM
Can't convince USARTs to receive on STM3210B-EVAL
2011-05-17 03:20 AM
Perhaps someone can enlighten me here. I can't seem to get the USARTs to receive data from my PC. I can get them to transmit, and I'm using USART1 to download the code to the part, so I assume that the hardware is working.
I've attached the shortest possible version of my C code that exhibits the problem. The code performs the following steps to initialize USART2: -enable GPIO Port D peripheral clock (USART2 pins are mapped to the alternate pins PD5 & PD6 on the STM310B-EVAL board) -enable AFIO peripheral clock so that I can remap the pins -remap the pins by setting the USART2_REMAP bit in the AFIO_MAPR register -configuring GPIO Port D, pin PD5 as alternate function output, push-pull, 2MHz -enable the USART2 peripheral clock -enable the USART enable bit in the USART2 control register CR1 -set the baud rate register for 9600 @ 8MHz (default clock rate after reset) -enable the TE and RE transmitter & receiver enable bits At this point the code can transmit to the PC with no problems. It will not, however, ever seem to receive anything. The RXNE bit in the status register SR never gets set. I've traced the signal all the way to the chip. The same thing happens on USART1. I'm using the GNU/CodeSourcery port for Win32. The code is contained in a single source file. I am not using the firmware library. I use the Flash Demonstrator program to download the firmware to the chip via USART1. I couldn't find anything in the datasheets to indicate that anything special needed to be configured for ''alternate function inputs''. What am I doing wrong? I appreciate any help or suggestions. Thanks, Dale Wheat PS: OK, I tried 6 times to attach the code to this post as a separate file, but I can't seem to get it to work, so I apologize in advance but here it comes.... : // usart.c // USART test for STM3210B-EVAL board // written by dale wheat - 10 january 2008 // macro for addressing registers in memory map #define REGISTER(base, offset) (*((volatile unsigned int *) (base + offset))) // peripheral bit banding macros #define PER_BASE 0x40000000 // peripheral memory map base address #define PER_BB_BASE 0x42000000 // peripheral bitband base address #define PBB(base, offset, bit) (*((volatile unsigned int *) (PER_BB_BASE + ((base + offset - PER_BASE) * 32) + (bit * 4)))) // RCC: Reset & Clock Control registers #define RCC_BASE 0x40021000 // base address #define RCC_APB2ENR_OFFSET 0x18 // APB2 peripheral clock enable register offset #define AFIOEN 0 // alternate function I/O #define IOPDEN 5 // GPIO Port D #define RCC_APB2ENR_AFIOEN PBB(RCC_BASE, RCC_APB2ENR_OFFSET, AFIOEN) // AFIO (alternate function IO) clock enable bit #define RCC_APB2ENR_IOPDEN PBB(RCC_BASE, RCC_APB2ENR_OFFSET, IOPDEN) // GPIO Port D clock enable bit #define RCC_APB1ENR_OFFSET 0x1C // APB1 peripheral clock enable register offset #define USART2EN 17 // USART2 peripheral clock enable bit #define RCC_APB1ENR_USART2EN PBB(RCC_BASE, RCC_APB1ENR_OFFSET, USART2EN) // USART2 peripheral clock enable bit // GPIO Port D #define GPIOD_BASE 0x40011400 // GPIO Port D base address #define GPIOD_CRL REGISTER(GPIOD_BASE, 0x00) // GPIO Port D control register low // Alternate function mapping #define AFIO_BASE 0x40010000 // alternate function base address #define AFIO_MAPR_OFFSET 0x04 // remap register offset #define USART2_REMAP 3 // USART2 remap #define AFIO_MAPR_USART2_REMAP PBB(AFIO_BASE, AFIO_MAPR_OFFSET, USART2_REMAP) // AFIO remap USART2 // USART #define USART2_BASE 0x40004400 // USART2 base address #define USART_SR_OFFSET 0x00 // status register #define RXNE 5 // read data register not empty #define TXE 7 // transmit data register empty #define USART_DR_OFFSET 0x04 // data register #define USART_BRR_OFFSET 0x08 // baud rate register #define USART_CR1_OFFSET 0x0C // control register 1 #define RE 2 // receive enable #define TE 3 // transmit enable #define UE 13 // USART enable #define USART2_SR REGISTER(USART2_BASE, USART_SR_OFFSET) // USART2 status register #define USART2_SR_TXE PBB(USART2_BASE, USART_SR_OFFSET, TXE) // USART2 transmit data register empty status bit #define USART2_SR_RXNE PBB(USART2_BASE, USART_SR_OFFSET, RXNE) // USART2 receive data register not empty status bit #define USART2_DR REGISTER(USART2_BASE, USART_DR_OFFSET) // USART2 data register #define USART2_BRR REGISTER(USART2_BASE, USART_BRR_OFFSET) // USART2 baud rate register #define USART2_CR1 REGISTER(USART2_BASE, USART_CR1_OFFSET) // USART2 control register 1 #define USART2_CR2 REGISTER(USART2_BASE, USART_CR2_OFFSET) // USART2 control register 2 // USART functions void usart2_putchar(unsigned char c) { while(USART2_SR_TXE == 0); // wait for transmit register to be empty USART2_DR = c; // transmit character } void usart2_puts(unsigned char *s) { while(*s) { usart2_putchar(*s); s++; } } unsigned char usart2_getchar(void) { while(USART2_SR_RXNE == 0); // wait for character to be received return (unsigned char) USART2_DR; // return received character } // main() - main program loop void main(void) { // initialize GPIO RCC_APB2ENR_IOPDEN = 1; // enable GPIO Port D peripheral clock RCC_APB2ENR_AFIOEN = 1; // enable AFIO peripheral clock AFIO_MAPR_USART2_REMAP = 1; // remap UASRT2 to alternate pins (TX=PD5, RX=PD6) on STM3210B-EVAL GPIOD_CRL = 0x00A00000; // PD5 output, alternate function (USART2 TX, remapped), push-pull, 2MHz // initialize USART2 RCC_APB1ENR_USART2EN = 1; // enable USART2 peripheral clock USART2_CR1 = 1< USART2_BRR = 52< USART2_CR1 = 1< // transmit signon message usart2_puts((unsigned char *)''USART2 test\n\r''); // echo incoming characters forever while(1) { usart2_putchar(usart2_getchar()); // echo } } // NMI (non-maskable interrupt) handler void nmi(void) { while(1); // just hang out here for a while } // hard fault handler void hard_fault(void) { while(1); // just hang out here for a while } // cortex vector table unsigned int * vectors[4] __attribute__ ((section(''vector''))) = { (unsigned int *) 0x20005000, // stack pointer (unsigned int *) main, // reset vector (unsigned int *) nmi, // NMI handler (unsigned int *) hard_fault // hard fault handler }; // [end-of-file] [ This message was edited by: dale on 11-01-2008 05:31 ] [ This message was edited by: dale on 11-01-2008 05:33 ]2011-05-17 03:20 AM
It seem with your config that PD6 is analog input. Even if there is no ADC input on PD6, I think you must configure this pin in Input floating or Input pull-up.
[ This message was edited by: eric.vanolden on 11-01-2008 18:26 ]2011-05-17 03:20 AM
Eric,
Thank you for responding to my note. You have a good eye! That was the problem! Thanks, Dale Wheat2011-05-17 03:20 AM