Exemplo n.º 1
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 system timer.
 *
 * This function is automatically called by Nut/OS
 * during system initialization.
 *
 * Nut/OS uses on-chip timer 0 for its timer services.
 * Applications should not modify any registers of this
 * timer, but make use of the Nut/OS timer API. Timer 1
 * and timer 2 are available to applications.
 */
void NutTimerInit(void)
{
#ifdef NUT_CPU_FREQ
    /* 16 bit timer ch. 0 high priority */
    INTC.IPRA.BIT._ITU0 = 1;
    /* auto clear TCNT, clock is phi/4 */
    ITU0.TCR.BYTE = 0x22;
    /* no output on GRA */
    ITU0.TIOR.BYTE = 0x00;
    /* generate interrupt every 10ms */
    /*    ITU0.GRA = 0xd7ff; */
    /* generate interrupt every 1ms */
    ITU0.GRA = 0x159a;
    /* clear counter register */
    ITU0.TCNT = 0x0000;
    /* enable IMIA0 interrupt */
    ITU.TISRA.BIT.IMIEA0 = 1;

    NutRegisterIrqHandler(&sig_IMIA0, NutTimer0Intr, 0);

    /* start timer 0 */
    ITU.TSTR.BIT.STR0 = 1;

#else                           /* #ifdef NUT_CPU_FREQ */
/*        TODO !!! */
#error "NUT_CPU_FREQ must be defined"
#endif                          /* #ifdef NUT_CPU_FREQ */
}
Exemplo n.º 3
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);
}
/*!
 * \brief Initialize TWI interface.
 *
 * The specified slave address is used only, if the local system
 * is running as a slave. Anyway, care must be taken that it doesn't
 * conflict with another connected device.
 *
 * \note This function is only available on ATmega128 systems.
 *
 * \param sla Slave address, must be specified as a 7-bit address,
 *            always lower than 128.
 */
int TwInit(u_char sla)
{
#ifndef __AVR_ENHANCED__
    return -1;
#else
    u_long speed = 2400;

    if (NutRegisterIrqHandler(&sig_2WIRE_SERIAL, TwInterrupt, 0)) {
        return -1;
    }

    /*
     * Set address register, enable general call address, set transfer
     * speed and enable interface.
     */
    outb(TWAR, (sla << 1) | 1);
    TwIOCtl(TWI_SETSPEED, &speed);
    outb(TWCR, _BV(TWINT));
    outb(TWCR, _BV(TWEN) | _BV(TWIE));

    /*
     * Initialize mutex semaphores.
     */
    NutEventPost(&tw_mm_mutex);

    return 0;
#endif /* __AVR_ENHANCED__ */
}
Exemplo n.º 5
0
/*!
 * \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);
}
Exemplo n.º 6
0
/*!
 * \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);
}
Exemplo n.º 7
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;
}
static void SysControlMainBeat(u_char OnOff)
{
	int nError = 0;
	if (OnOff==ON)
	{
		nError = NutRegisterIrqHandler(&OVERFLOW_SIGNAL, SysMainBeatInterrupt, NULL);
		if (nError == 0)
		{
			init_8_bit_timer();
		}
	}
	else
	{
		// disable overflow interrupt
		disable_8_bit_timer_ovfl_int();
	}
}
Exemplo n.º 9
0
/*!
 * \brief Initialize system timer.
 *
 * This function is automatically called by Nut/OS
 * during system initialization.
 *
 * Nut/OS uses on-chip timer 0 for its timer services.
 * Applications should not modify any registers of this
 * timer, but make use of the Nut/OS timer API. Timer 1
 * and timer 2 are available to applications.
 */
void NutRegisterTimer(void (*handler) (void *))
{
    os_handler = handler;


    /* Disable master interrupt. */
    outw(REG_IME, 0);

    /* Set global interrupt vector. */
    NutRegisterIrqHandler(&sig_TMR3, Timer3Entry, 0);

    /* Enable timer and timer interrupts. */
    outdw(REG_TMR3CNT, TMR_IRQ_ENA | TMR_ENA | 48756);

    /* Enable timer 3 interrupts. */
    outw(REG_IE, inw(REG_IE) | INT_TMR3);

    /* Enable master interrupt. */
    outw(REG_IME, 1);
}
Exemplo n.º 10
0
int NutTraceInit(int size, char mode)
{
    if (!trace_isinit) {
        // start timer1 at CPU frequency/8 and register interrupt service routine
        outb(TCCR1B, 2);
        NutRegisterIrqHandler(&sig_OVERFLOW1, NutTraceTimer1IRQ, 0);
        sbi(TIMSK, TOIE1);
        trace_isinit = 1;
    }
    if (size==0) {
        size = TRACE_SIZE_DEFAULT;
    }
    if (size != trace_size) {
        // current buffer is not of size that is wanted
        if (trace_items != 0) {
            // but memory is already allocated -> free old buffer
            NutHeapFree(trace_items);
        }
        // allocate buffer
        trace_items = (t_traceitem *)NutHeapAlloc(size * sizeof(t_traceitem));
        if (trace_items == 0) {
            // failed
            return trace_size = 0;
        }
        else {
            trace_size = size;
        }
    }

//  if (mode == TRACE_MODE_OFF) {
//      // if terminal-cmd "trace size <val>" is called trace is started in
//      // default mode
//      mode = TRACE_MODE_DEFAULT;
//  }
    trace_mode   = mode;
    NutTraceClear();
    return trace_size;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
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;
}
/*!
 * \brief Initialize system timer.
 *
 * This function is automatically called by Nut/OS
 * during system initialization.
 *
 * Nut/OS uses on-chip timer 0 for its timer services.
 * Applications should not modify any registers of this
 * timer, but make use of the Nut/OS timer API. Timer 1
 * and timer 2 are available to applications.
 */
void NutRegisterTimer(void (*handler) (void *))
{
    os_handler = handler;

#if defined(MCU_AT91R40008)

    /* Disable the Clock Counter */
    outr(TC0_CCR, TC_CLKDIS);
    /* Disable all interrupts */
    outr(TC0_IDR, 0xFFFFFFFF);
    /* Clear the status register. */
    dummy = inr(TC0_SR);
    /* Select divider and compare trigger */
    outr(TC0_CMR, TC_CLKS_MCK32 | TC_CPCTRG);
    /* Enable the Clock counter */
    outr(TC0_CCR, TC_CLKEN);
    /* Validate the RC compare interrupt */
    outr(TC0_IER, TC_CPCS);

    /* Disable timer 0 interrupts. */
    outr(AIC_IDCR, _BV(TC0_ID));
    /* Set the TC0 IRQ handler address */
    outr(AIC_SVR(4), (unsigned int)Timer0Entry);
    /* Set the trigg and priority for timer 0 interrupt */
    /* Level 7 is highest, level 0 lowest. */
    outr(AIC_SMR(4), (AIC_SRCTYPE_INT_LEVEL_SENSITIVE | 0x4));
    /* Clear timer 0 interrupt */
    outr(AIC_ICCR, _BV(TC0_ID));
    /* Enable timer 0 interrupts */
    outr(AIC_IECR, _BV(TC0_ID));

    /* Set compare value for 1 ms. */
    outr(TC0_RC, 0x80F);
    /* Software trigger starts the clock. */
    outr(TC0_CCR, TC_SWTRG);

#elif defined(MCU_S3C4510B)

    INT_DISABLE(IRQ_TIMER);
    CSR_WRITE(TCNT0, 0);
    CSR_WRITE(TDATA0, CLOCK_TICK_RATE);
    CSR_WRITE(TMOD, TMOD_TIMER0_VAL);

    CLEAR_PEND_INT(IRQ_TIMER);

    NutRegisterIrqHandler(
        &InterruptHandlers[IRQ_TIMER], handler, 0);

    INT_ENABLE(IRQ_TIMER);

#elif defined(MCU_GBA)

    /* Disable master interrupt. */
    outw(REG_IME, 0);

    /* Set global interrupt vector. */
    NutRegisterIrqHandler(&sig_TMR3, Timer3Entry, 0);

    /* Enable timer and timer interrupts. */
    outdw(REG_TMR3CNT, TMR_IRQ_ENA | TMR_ENA | 48756);

    /* Enable timer 3 interrupts. */
    outw(REG_IE, inw(REG_IE) | INT_TMR3);

    /* Enable master interrupt. */
    outw(REG_IME, 1);

#else
#warning "MCU not defined"
#endif
}
Exemplo n.º 14
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;
}