Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 6 Jul 2006 05:46:58 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 100693 for review
Message-ID:  <200607060546.k665kwqW030518@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=100693

Change 100693 by imp@imp_lighthouse on 2006/07/06 05:46:44

	Our board does weird things with serial ports sometimes for reasons
	that are unclear.  We have noticed that RXD1 is held high, and some
	weird things based on which part we're talking to sometimes.  To avoid
	this, we expliticly pull up the TXDx lines (but not for DBGU).  This
	appears to be because the USARTs can supprot RS-485 multi-drop, but
	the DBGU doesn't.  This may solve some weirdness that we're seeing,
	but until more tests are run, it won't be known.
	
	At least this way the state of all the lines is explict and we don't
	reply on the kindess of boatloaders for our good function.

Affected files ...

.. //depot/projects/arm/src/sys/arm/at91/at91_pio.c#14 edit
.. //depot/projects/arm/src/sys/arm/at91/at91_piovar.h#2 edit
.. //depot/projects/arm/src/sys/arm/at91/kb920x_machdep.c#27 edit

Differences ...

==== //depot/projects/arm/src/sys/arm/at91/at91_pio.c#14 (text+ko) ====

@@ -280,21 +280,29 @@
  * them.
  */
 void
-at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask)
+at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, int use_pullup)
 {
 	uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
 
 	PIO[PIO_ASR / 4] = periph_a_mask;
 	PIO[PIO_PDR / 4] = periph_a_mask;
+	if (use_pullup)
+		PIO[PIO_PUER / 4] = periph_a_mask;
+	else
+		PIO[PIO_PUDR / 4] = periph_a_mask;
 }
 
 void
-at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask)
+at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask, int use_pullup)
 {
 	uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
 
 	PIO[PIO_BSR / 4] = periph_b_mask;
 	PIO[PIO_PDR / 4] = periph_b_mask;
+	if (use_pullup)
+		PIO[PIO_PUER / 4] = periph_b_mask;
+	else
+		PIO[PIO_PUDR / 4] = periph_b_mask;
 }
 
 void
@@ -314,11 +322,15 @@
 }
 
 void
-at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask)
+at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask, int use_pullup)
 {
 	uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
 
 	PIO[PIO_OER / 4] = output_enable_mask;
+	if (use_pullup)
+		PIO[PIO_PUER / 4] = output_enable_mask;
+	else
+		PIO[PIO_PUDR / 4] = output_enable_mask;
 }
 
 void

==== //depot/projects/arm/src/sys/arm/at91/at91_piovar.h#2 (text+ko) ====

@@ -27,11 +27,12 @@
 #ifndef ARM_AT91_AT91_PIOVAR_H
 #define ARM_AT91_AT91_PIOVAR_H
 
-void at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask);
-void at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask);
+void at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, int use_pullup);
+void at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask, int use_pullup);
 void at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask);
 void at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask);
-void at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask);
+void at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask,
+	int use_pullup);
 void at91_pio_gpio_set(uint32_t pio, uint32_t data_mask);
 void at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask);
 

==== //depot/projects/arm/src/sys/arm/at91/kb920x_machdep.c#27 (text+ko) ====

@@ -203,21 +203,33 @@
 static long
 board_init(void)
 {
+	/*
+	 * Since the USART supprots RS-485 multidrop mode, it allows the
+	 * TX pins to float.  However, for RS-232 operations, we don't want
+	 * these pins to float.  Instead, they should be pulled up to avoid
+	 * mismatches.  Linux does something similar when it configures the
+	 * TX lines.  This implies that we also allow the RX lines to float
+	 * rather than be in the state they are left in by the boot loader.
+	 * Since they are input pins, I think that this is the right thing
+	 * to do.
+	 */
+
 	/* PIOA's A periph: Turn USART 0 and 2's TX/RX pins */
 	at91_pio_use_periph_a(AT91RM92_PIOA_BASE,
-	    AT91C_PA17_TXD0 | AT91C_PA18_RXD0 |
-	    AT91C_PA23_TXD2 | AT91C_PA22_RXD2);
+	    AT91C_PA18_RXD0 | AT91C_PA22_RXD2, 0);
+	at91_pio_use_periph_a(AT91RM92_PIOA_BASE,
+	    AT91C_PA17_TXD0 | AT91C_PA23_TXD2, 1);
 	/* PIOA's B periph: Turn USART 3's TX/RX pins */
-	at91_pio_use_periph_b(AT91RM92_PIOA_BASE,
-	    AT91C_PA5_TXD3 | AT91C_PA6_RXD3);
+	at91_pio_use_periph_b(AT91RM92_PIOA_BASE, AT91C_PA6_RXD3, 0);
+	at91_pio_use_periph_b(AT91RM92_PIOA_BASE, AT91C_PA5_TXD3, 1);
 	/* PIOB's A periph: Turn USART 1's TX/RX pins */
-	at91_pio_use_periph_a(AT91RM92_PIOB_BASE,
-	    AT91C_PB20_TXD1 | AT91C_PB21_RXD1);
+	at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PB21_RXD1, 0);
+	at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PB20_TXD1, 1);
 
 	/* Pin assignment */
 	/* Assert PA24 low -- talk to rubidium */
 	at91_pio_use_gpio(AT91RM92_PIOA_BASE, AT91C_PIO_PA24);
-	at91_pio_gpio_output(AT91RM92_PIOA_BASE, AT91C_PIO_PA24);
+	at91_pio_gpio_output(AT91RM92_PIOA_BASE, AT91C_PIO_PA24, 0);
 	at91_pio_gpio_clear(AT91RM92_PIOA_BASE, AT91C_PIO_PA24);
 
 	return (ramsize());



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607060546.k665kwqW030518>