/** * @brief Low level serial driver configuration and (re)start. * * @param[in] sdp pointer to a @p SerialDriver object * @param[in] config the architecture-dependent serial driver configuration. * If this parameter is set to @p NULL then a default * configuration is used. * * @notapi */ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) { UNUSED(sdp); if (config == NULL) config = &default_config; IRQ_DISABLE1 = BIT(29); AUX_ENABLES = 1; AUX_MU_IER_REG = 0x00; AUX_MU_CNTL_REG = 0x00; AUX_MU_LCR_REG = 0x03; // Bit 1 must be set AUX_MU_MCR_REG = 0x00; AUX_MU_IER_REG = 0x05; AUX_MU_IIR_REG = 0xC6; AUX_MU_BAUD_REG = BAUD_RATE_COUNT(config->baud_rate); bcm2835_gpio_fnsel(14, GPFN_ALT5); bcm2835_gpio_fnsel(15, GPFN_ALT5); GPPUD = 0; bcm2835_delay(150); GPPUDCLK0 = (1<<14)|(1<<15); bcm2835_delay(150); GPPUDCLK0 = 0; AUX_MU_CNTL_REG = 0x03; IRQ_ENABLE1 = BIT(29); }
/** * @brief Low level serial driver stop. * @details De-initializes the USART, stops the associated clock, resets the * interrupt vector. * * @param[in] sdp pointer to a @p SerialDriver object * * @notapi */ void sd_lld_stop(SerialDriver *sdp) { UNUSED(sdp); IRQ_DISABLE1 |= BIT(29); bcm2835_gpio_fnsel(14, GPFN_IN); bcm2835_gpio_fnsel(15, GPFN_IN); }
/** * @brief Deactivates the I2C peripheral. * * @param[in] i2cp pointer to the @p I2CDriver object * * @notapi */ void i2c_lld_stop(I2CDriver *i2cp) { /* Set GPIO pin function to default */ bcm2835_gpio_fnsel(GPIO0_PAD, GPFN_IN); bcm2835_gpio_fnsel(GPIO1_PAD, GPFN_IN); i2cp->device->control &= ~BSC_I2CEN; }
/** * @brief Configures and activates the I2C peripheral. * * @param[in] i2cp pointer to the @p I2CDriver object * * @notapi */ void i2c_lld_start(I2CDriver *i2cp) { /* Set up GPIO pins for I2C */ bcm2835_gpio_fnsel(GPIO0_PAD, GPFN_ALT0); bcm2835_gpio_fnsel(GPIO1_PAD, GPFN_ALT0); uint32_t speed = i2cp->config->ic_speed; if (speed != 0 && speed != 100000) i2cp->device->clockDivider = BSC_CLOCK_FREQ / i2cp->config->ic_speed; i2cp->device->control |= BSC_I2CEN; }
void _pal_lld_setgroupmode(ioportid_t port, ioportmask_t mask, uint32_t mode) { int i; switch (mode) { case PAL_MODE_INPUT: set_gpio_in(port, mask); set_gpio_pud(port, mask, GPIO_PUD_OFF); break; case PAL_MODE_INPUT_PULLUP: set_gpio_in(port, mask); set_gpio_pud(port, mask, GPIO_PUD_PULLUP); break; case PAL_MODE_INPUT_PULLDOWN: set_gpio_in(port, mask); set_gpio_pud(port, mask, GPIO_PUD_PULLDOWN); break; case PAL_MODE_OUTPUT: case PAL_MODE_OUTPUT_PUSHPULL: case PAL_MODE_OUTPUT_OPENDRAIN: for (i = 0; i < 32; i++) { unsigned int bit = mask & 1; if (bit) bcm2835_gpio_fnsel(i + port->pin_base, GPFN_OUT); mask >>= 1; } break; } }
/** * @brief Configures and activates the PWM peripheral. * * @param[in] pwmp pointer to the @p PWMDriver object * * @notapi */ void pwm_lld_start(PWMDriver *pwmp) { /* Set PWM pin function.*/ bcm2835_gpio_fnsel(18, GPFN_ALT5); /* Stop PWM.*/ PWM_CTL = 0 ; /* Disable clock generator (reset bit 4).*/ GPIO0_CLK_CTL = GPIO_CLK_PWD | 0x01 ; delayMicroseconds (110) ; /* Wait for clock to be !BUSY.*/ while ((GPIO0_CLK_CTL & 0x80) != 0); /* set pwm div to 32 (19.2/32 = 600KHz).*/ GPIO0_CLK_DIV = GPIO_CLK_PWD | (32 << 12); /* enable clock generator.*/ GPIO0_CLK_CTL = GPIO_CLK_PWD | 0x11; /* N/M -- N = DATA, M = RANGE.*/ /* M/S -- M = DATA, S = RANGE.*/ PWM0_DATA = 0; PWM0_RANGE = pwmp->period; }
static void set_gpio_in(ioportid_t port, ioportmask_t mask) { int i; for (i = 0; i < 32; i++) { unsigned int bit = mask & 1; if (bit) bcm2835_gpio_fnsel(i + port->pin_base, GPFN_IN); mask >>= 1; } }