Port-arm archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Raspberry Pi ACT LED



Set the value of a GPIO pin. Something like this (not compile tested):

void
bcm2835gpio_function_write(u_int pin, u_int val)
{
	const bus_space_tag_t iot = &bcm2835_bs_tag;
	const bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(BCM2835_GPIO_BASE);
	const u_int mask = (1 << BCM2835_GPIO_GPFSEL_BITS_PER_PIN) - 1;
	const u_int regid = (pin / BCM2835_GPIO_GPFSEL_PINS_PER_REGISTER);
	const u_int shift = (pin % BCM2835_GPIO_GPFSEL_PINS_PER_REGISTER) *
	    BCM2835_GPIO_GPFSEL_BITS_PER_PIN;
	uint32_t v;

	v = bus_space_read_4(iot, ioh, BCM2835_GPIO_GPFSEL(regid));
	v &= ~(mask << shift);
	v |= (val << shift);
	bus_space_write_4(iot, ioh, BCM2835_GPIO_GPFSEL(regid), v);
}


On Thu, 23 Apr 2015, Stephan wrote:

One thing is unclear to me: What is bcm2835gpio_function_write supposed to do?

2015-04-21 23:24 GMT+02:00 Jared McNeill <jmcneill%invisible.ca@localhost>:
I would do this:

 - Add bcm2835gpio_function_write to bcm2835_gpio_subr.[ch]
 - Pass the gpio pin from rpi_device_register to the mmc driver as a
   device property.
 - In the MMC driver, if the pin property is set, use it to toggle the LED
   state. You've selected the right place to do it.

Since this is all MD code (and we don't have a MI KPI for gpio access,
unfortunately) this approach should be fine.


On Tue, 21 Apr 2015, Stephan wrote:

Okay, LED_ON() and LED_OFF() is pseudo-code and should have indicated
the place to put the control functions in. The next question would be
how to control the LED - for example by utilizing the GPIO framework
or driver, which might be too much overhead. Another way could be
writing directly to the corresponding register. I guess the given code
snipped runs in process context and waits on a CV which gets signalled
from the interrupt context?!


Either way, it might be good to know how it is impleneted in Linux but
I couldn?t find the appropriate place yet. The ultra-fragmented nature
of Linux isn?t very helpful with finding things.


2015-04-21 14:24 GMT+02:00 Greg Troxel <gdt%ir.bbn.com@localhost>:


Stephan <stephanwib%googlemail.com@localhost> writes:

bcm_dmac_transfer(sc->sc_dmac);
LED_ON();
   while (sc->sc_state == EMMC_DMA_STATE_BUSY) {
   error = cv_timedwait(&sc->sc_cv, &sc->sc_lock, hz * 10);
   if (error == EWOULDBLOCK) {
   device_printf(sc->sc.sc_dev, "transfer timeout!\n");
   bcm_dmac_halt(sc->sc_dmac);
   sc->sc_state = EMMC_DMA_STATE_IDLE;
   error = ETIMEDOUT;
   break;
   }
}
LED_OFF();
mutex_exit(&sc->sc_lock);

This also needs to be put in an #ifdef to be only included in a Pi
build.

Comments / hints / better ideas?


I wonder if it makes sense to generalize this, to have a bunch of naemd
(#define?) notification types, and macros to on/off, so that they get
defined to empty on systems where it doesn't make sense, and to
something sensible on various systems that have indicators.   Surely the
RPI B isn't the only device where this makes sense, and there's probably
a lot different.

There was a comment about calling these "during the transfer" which was
too vague to be really helpful, but you might want to check the
locking/sleeping rules - generally one cannot call things that might
sleep from interrupts, etc.   But given that the code is already calling
cv_timedwait, sleeping isn't really an issue (and I don't know what's
behind LED_ON()).

(A tangent: More generally, one of the harder things to figure out in
NetBSD (or anything) is what the locking/etc. rules are, and I think it
would help to have more explicit comments in each procedure about
assumptions.)







Home | Main Index | Thread Index | Old Index