Example #1
0
/*!
 * \brief Initialize the RTC in LPC 17xx controller
 *
 * \return 0 on success or -1 in case of an error.
 *
 */
static int Lpc17xxRtcInit(NUTRTC *rtc)
{
    rtc->dcb = NutHeapAllocClear(sizeof(lpc17xx_rtc_dcb));
    if (rtc->dcb == NULL) {
        return -1;
    }

    if (NutRegisterIrqHandler(&sig_RTC, Lpc17xxRtcInterrupt, rtc) != 0) {
        NutHeapFree(rtc->dcb);
        return -1;
    }

    /* Set up clock and power for RTC module */
    SysCtlPeripheralClkEnable(CLKPWR_PCONP_PCRTC);

    /* Clear all register to be default */
    LPC_RTC->ILR  = 0x03;
    LPC_RTC->CCR  = 0x00;
    LPC_RTC->CIIR = 0x00;
    LPC_RTC->AMR  = 0xFF;
    LPC_RTC->CALIBRATION = 0x00;

    /* enable RTC (run) */
    LPC_RTC->CCR |= RTC_CCR_CLKEN;

    ((lpc17xx_rtc_dcb *)rtc->dcb)->flags = 0x00000000;
    rtc->alarm = NULL;

    NutIrqEnable(&sig_RTC);

    return(0);
}
Example #2
0
void ADCInit(void)
{
    int channel;

    /* Only init once */
    if (ADC_Buffer) return;

    /* Enable clock int PMC and reset ADC */
    outr(PMC_PCER, _BV(ADC_ID));              // Enable ADC clock in PMC
    outr(ADC_CR, ADC_SWRST);                  // Reset bus
    outr(ADC_CR, 0x00);

    /* Basic configuration: Disable all channels and set mode and prescaler */
    outr(ADC_CHDR, ADC_CH0 | ADC_CH1 | ADC_CH2 | ADC_CH3 | ADC_CH4 | ADC_CH5 | ADC_CH6 | ADC_CH7);
    ADCSetMode(AT91_ADC_INITIAL_MODE);
    ADCSetPrescale(AT91_ADC_INITIAL_PRESCALE);

    /* Init adc buffers. One for every channel as we can sample all by automatic sequence */
    ADC_Buffer = NutHeapAlloc(sizeof(uint16_t *) * ADC_MAX_CHANNEL);
    for (channel = 0; channel < ADC_MAX_CHANNEL; channel ++) {
        ADC_Buffer[channel] = NutHeapAlloc(sizeof(uint16_t) * AT91_ADC_BUF_SIZE + 2);
        ADC_Buffer[channel][_adc_buf_head] = 0;
        ADC_Buffer[channel][_adc_buf_tail] = 0;
    }

    if (NutRegisterIrqHandler(&sig_ADC, ADCInterrupt, NULL)) {
        // We do not free buffer as this would cost ROM and is not likely
        return;
    }
    NutIrqEnable(&sig_ADC);
}
/*!
 * \brief Initialize the second serial peripheral interface on the AT91 MCU.
 */
int At91Spi1Init(void)
{
    /* Enable SPI peripherals. */
    At91Spi1Enable();
    /* Enable SPI clock. */
    outr(PMC_PCER, _BV(SPI1_ID));

    /* Register and enable SPI1 interrupt handler. */
    NutRegisterIrqHandler(&sig_SPI1, At91Spi1Interrupt, 0);
    NutIrqEnable(&sig_SPI1);

    return At91SpiReset(SPI1_BASE);
}
/*!
 * \brief Initialize the first serial peripheral interface on the AVR32 MCU.
 */
int Avr32Spi0Init(void)
{
    volatile avr32_spi_t *spi = AVR32_SPI0;
    /* Enable SPI peripherals. */
    Avr32Spi0Enable();
    /* Enable SPI clock. */
    spi->outr(PMC_PCER, _BV(SPI0_ID));

    /* Register and enable SPI0 interrupt handler. */
    NutRegisterIrqHandler(&sig_SPI0, Avr32Spi0Interrupt, 0);
    NutIrqEnable(&sig_SPI0);

    return Avr32SpiReset(SPI0_BASE);
}
Example #5
0
/*!
 * \brief Initialize the I2C bus controller (STM32 implementation).
 *
 * This function is called by the platform independent code via the
 * NUTI2C_BUS::bus_init function pointer when the first slave is
 * attached to this bus. Note, that NUTI2C_BUS::bus_rate must be zero
 * initially. Otherwise no call to this function will take place.
 *
 * This function must do all required initializations so that the
 * driver will be ready to process transfers via NUTI2C_BUS::bus_tran.
 *
 * This function must return 0 on success or -1 otherwise.
 */
static int I2cBusInit(NUTI2C_BUS *bus)
{
    I2C_TypeDef *i2c;
    STM32_I2CCB *icb;

    icb = (STM32_I2CCB *) bus->bus_icb;

    if (checkpin_and_config(icb))
        return -1;
    /* Try to configure the bus*/
    if (I2cBusConf(bus)) {
        return -1;
    }
    i2c = (I2C_TypeDef*) icb->icb_base;
    i2c->CR1 |= I2C_CR1_PE;
    if (NutRegisterIrqHandler(icb->icb_sig_ev, I2cEventBusIrqHandler, icb))
        return -1;
    if (NutRegisterIrqHandler(icb->icb_sig_er, I2cErrorBusIrqHandler, icb))
        return -1;
    NutIrqEnable(icb->icb_sig_ev);
    NutIrqDisable(icb->icb_sig_er);

    return 0;
}
Example #6
0
/*!
 * \brief Register a GPIO pin interrupt handler.
 *
 * Generating interrupts on GPIO pin changes is not supported on all
 * platforms. In this case dedicated external interrupt pins may
 * be used with NutRegisterIrqHandler().
 *
 * Interrupts are triggered on rising and falling edges. Level triggering
 * or triggering on specific edges is not supported.
 *
 * After registering, interrupts are disabled. Calling GpioIrqEnable()
 * is required to activate the interrupt.
 *
 * The following code fragment registers an interrupt handler which is
 * called on each change of bit 4 of the first GPIO port:
 * \code
 * #include <dev/gpio.h>
 *
 * static void PinChange(void *arg)
 * {
 *     ...
 * }
 *
 * {
 *     ...
 *     GpioPinConfigSet(0, 4, GPIO_CFG_PULLUP);
 *     GpioRegisterIrqHandler(&sig_GPIO, 4, PinChange, NULL);
 *     GpioIrqEnable(&sig_GPIO, 4);
 *     ...
 * }
 * \endcode
 *
 * \param sig     Bank/port interrupt to be associated with this handler.
 * \param bit     Bit number of the specified bank/port.
 * \param handler This routine will be called by Nut/OS, when the specified
 *                pin changes its state.
 * \param arg     Argument to be passed to the interrupt handler routine.
 *
 * \return 0 on success, -1 otherwise.
 */
int GpioRegisterIrqHandler(GPIO_SIGNAL * sig, int bit, void (*handler) (void *), void *arg)
{
    int rc = 0;

    if (sig->ios_vector == 0) {
        /* This is the first call. Allocate the vector table. */
        sig->ios_vector = malloc(sizeof(GPIO_VECTOR) * 32);
        if (sig->ios_vector) {
            memset(sig->ios_vector, 0, sizeof(GPIO_VECTOR) * 32);
            /* Register our internal PIO interrupt service. */
            rc = NutRegisterIrqHandler(sig->ios_sig, sig->ios_handler, sig->ios_vector);
            if (rc == 0) {
                rc = NutIrqEnable(sig->ios_sig);
            }
        }
        else {
            rc = -1;
        }
    }
    sig->ios_vector[bit].iov_handler = handler;
    sig->ios_vector[bit].iov_arg = arg;

    return rc;
}
Example #7
0
/*! 
 * \brief Initialize an SPI bus node. 
 *
 * This routine is called for each SPI node, which is registered via 
 * NutRegisterSpiDevice().
 *
 * \param node Specifies the SPI bus node.
 *
 * \return 0 on success or -1 if there is no valid chip select.
 */
int At91SpiBusNodeInit(NUTSPINODE * node)
{
    int rc;
    NUTSPIBUS *bus;

    /* Sanity check. */
    NUTASSERT(node != NULL);
    NUTASSERT(node->node_bus != NULL);
    bus = node->node_bus;

    /* Try to deactivate the node's chip select. */
#if defined(SPI1_BASE)
    if (bus->bus_base == SPI1_BASE) {
        rc = At91Spi1ChipSelect(node->node_cs, (node->node_mode & SPI_MODE_CSHIGH) == 0);
    } else
#endif
    rc = At91Spi0ChipSelect(node->node_cs, (node->node_mode & SPI_MODE_CSHIGH) == 0);

    /* It should not hurt us being called more than once. Thus, we
       ** check wether any initialization had been taken place already. */
    if (rc == 0 && node->node_stat == NULL) {
        /* Allocate and set our shadow registers. */
        AT91SPIREG *spireg = malloc(sizeof(AT91SPIREG));
        if (spireg) {
            /* Set interface defaults. */
            spireg->at91spi_mr = SPI_MODFDIS | SPI_MSTR;
            switch (node->node_cs) {
            case 0:
                spireg->at91spi_mr |= SPI_PCS_0;
                break;
            case 1:
                spireg->at91spi_mr |= SPI_PCS_1;
                break;
            case 2:
                spireg->at91spi_mr |= SPI_PCS_2;
                break;
            case 3:
                spireg->at91spi_mr |= SPI_PCS_3;
                break;
            }
            spireg->at91spi_csr = 0;
            /* Update with node's defaults. */
            node->node_stat = (void *)spireg;
            At91SpiSetup(node);

            /* 
             * Register and enable SPI interrupt handler. 
             */
#if !defined(SPIBUS1_POLLING_MODE) && defined(SPI1_BASE)
            if (bus->bus_base == SPI1_BASE) {
#if defined(SPIBUS1_DOUBLE_BUFFER)
                NutRegisterIrqHandler(bus->bus_sig, At91SpiInterrupt, &bus->bus_ready);
#else
                NutRegisterIrqHandler(bus->bus_sig, At91SpiBus1Interrupt, &bus->bus_ready);
#endif
                outr(bus->bus_base + SPI_IDR_OFF, (unsigned int) - 1);
                NutIrqEnable(bus->bus_sig);
            } else
#endif /* !SPIBUS1_POLLING_MODE */

            {
#if !defined(SPIBUS0_POLLING_MODE)
#if defined(SPIBUS0_DOUBLE_BUFFER)
                NutRegisterIrqHandler(bus->bus_sig, At91SpiInterrupt, &bus->bus_ready);
#else
                NutRegisterIrqHandler(bus->bus_sig, At91SpiBus0Interrupt, &bus->bus_ready);
#endif
                outr(bus->bus_base + SPI_IDR_OFF, (unsigned int) - 1);
                NutIrqEnable(bus->bus_sig);
#endif /* !SPIBUS0_POLLING_MODE */
            }
        } else {
            /* Out of memory? */
            rc = -1;
        }
    }
    return rc;
}
Example #8
0
/*!
 * \brief Initialize TWI interface.
 *
 * The specified slave address is not used here as we don't support twi-slave
 * on this architecture for now.
 *
 * \param sla Slave address, must be specified as a 7-bit address,
 *            always lower than 128.
 */
int NutRegisterTwiBus( NUTTWIBUS *bus, uint8_t sla )
{
    int rc = -1;

    uint32_t speed = 80000; /* Errata Doc 14574 Rev. 9 Chapter 2.11: Avoid 88kHz to 100kHz */
//    uint16_t tmpreg = 0;
    I2C_TypeDef* I2Cx = (I2C_TypeDef*)bus->bus_base;
    NUTTWIICB *icb = NULL;

    DBGP1_INIT();
    DBGP2_INIT();

    /* Check if bus was already registered */
    if( bus->bus_icb) {
        return 0;
    }

    /* Allocate ICB for this bus */
    icb = NutHeapAlloc(sizeof(NUTTWIICB));
    if( icb == NULL) {
        return rc;
    }
    memset( icb, 0, sizeof(NUTTWIICB));

    /* Link bus and ICB */
    bus->bus_icb = icb;

    if( NutRegisterIrqHandler( bus->bus_sig_ev, TwEventIrq, bus ) ) {
        free( icb);
        return rc;
    }

    if( NutRegisterIrqHandler( bus->bus_sig_er, TwErrorIrq, bus ) ) {
        free( icb);
        return rc;
    }

    /* Initialize GPIO Hardware */
    if( bus->bus_initbus != NULL) {
        rc = bus->bus_initbus();
    }
    if( rc) {
        return rc;
    }

    /* Disable and reset this bus */
    I2Cx->CR1 &= ~I2C_CR1_PE;
    I2Cx->CR1 |= I2C_CR1_SWRST;
    I2Cx->CR1 &= ~I2C_CR1_SWRST;


#ifdef I2C_DEFAULT_SPEED
    if( bus->bus_base == I2C1_BASE)
        speed = I2CBUS1_DEFAULT_SPEED*1000UL;
#endif
#ifdef I2CBUS2_DEFAULT_SPEED
    if( bus->bus_base == I2C2_BASE)
        speed = I2CBUS2_DEFAULT_SPEED*1000UL;
#endif
    /* Set initial rate. */
    if( (rc = NutTwiSetSpeed( bus, speed))) {
        return rc;
    }

    /* Setup 7-Bit Addressing Mode not acknowledged */
    I2Cx->OAR1 = 0x4000; /* FIXME: OAR1 Bit 14 is reserved */

#if 0
    /* Setup CR1 */
    tmpreg = I2Cx->CR1;
    tmpreg &= ~(I2C_CR1_SMBUS|I2C_CR1_SMBTYPE|I2C_CR1_PEC);
    tmpreg |= I2C_CR1_ACK;
    // TODO: Set SMBTYPE and SMBUS bits
    I2Cx->CR1 = tmpreg;

    /* Setup Interrupts */
    tmpreg = I2Cx->CR2;
    tmpreg |= (I2C_CR2_ITBUFEN|I2C_CR2_ITEVTEN|I2C_CR2_ITERREN);
    I2Cx->CR2 = tmpreg;
#endif
    I2Cx->CR1 = I2C_CR1_PE;

    // TODO: Slave Address Setup

    NutIrqSetPriority(bus->bus_sig_ev, 0);
    rc = NutIrqEnable(bus->bus_sig_ev);
    if( rc) {
        return rc;
    }
    NutIrqSetPriority(bus->bus_sig_er, 1);
    rc = NutIrqEnable(bus->bus_sig_er);
    if( rc) {
        return rc;
    }

    /* Initialize mutex semaphores. */
    NutEventPost(&bus->bus_mutex);

    return rc;
}