/*! * \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); }
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); }
/*! * \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; }
/*! * \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; }
/*! * \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 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; }