/** * \brief Init function for the left button. * * Parameters are ignored. They have been included because the prototype is * dictated by the core sensor api. The return value is also not required by * the API but otherwise ignored. * * \param type ignored * \param value ignored * \return ignored */ static int config_ac_zero_detector(int type, int value) { // config(BUTTON_LEFT_PORT_BASE, BUTTON_LEFT_PIN_MASK); /* Software controlled */ GPIO_SOFTWARE_CONTROL(AC_ZERO_DETECTOR_PORT_BASE, AC_ZERO_DETECTOR_PIN_MASK); /* Se2t pin to input */ GPIO_SET_INPUT(AC_ZERO_DETECTOR_PORT_BASE, AC_ZERO_DETECTOR_PIN_MASK); /* Enable edge detection */ GPIO_DETECT_EDGE(AC_ZERO_DETECTOR_PORT_BASE, AC_ZERO_DETECTOR_PIN_MASK); /* Single edge */ GPIO_TRIGGER_SINGLE_EDGE(AC_ZERO_DETECTOR_PORT_BASE, AC_ZERO_DETECTOR_PIN_MASK); /* Trigger interrupt on Falling edge */ GPIO_DETECT_FALLING(AC_ZERO_DETECTOR_PORT_BASE, AC_ZERO_DETECTOR_PIN_MASK); //We can't use RISING detect, becuse while symithtor is open detector will always return 1=like we have //zero crossing, so we can use FALLING edge only. // GPIO_DETECT_RISING(AC_ZERO_DETECTOR_PORT_BASE, AC_ZERO_DETECTOR_PIN_MASK); GPIO_ENABLE_INTERRUPT(AC_ZERO_DETECTOR_PORT_BASE, AC_ZERO_DETECTOR_PIN_MASK); ioc_set_over(AC_ZERO_DETECTOR_PORT, AC_ZERO_DETECTOR_PIN, IOC_OVERRIDE_PUE); nvic_interrupt_enable(AC_ZERO_DETECTOR_VECTOR); gpio_register_callback(zero_cross_callback, AC_ZERO_DETECTOR_PORT, AC_ZERO_DETECTOR_PIN); return 1; }
/*---------------------------------------------------------------------------*/ static int configure(int type, int value) { if(type != MOTION_ACTIVE) { PRINTF("Motion: invalid configuration option\n"); return MOTION_ERROR; } if(!value) { presence_int_callback = NULL; GPIO_DISABLE_INTERRUPT(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); return MOTION_SUCCESS; } /* Configure interruption */ GPIO_SOFTWARE_CONTROL(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); GPIO_SET_INPUT(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); GPIO_DETECT_RISING(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); GPIO_TRIGGER_SINGLE_EDGE(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); ioc_set_over(MOTION_SENSOR_PORT, MOTION_SENSOR_PIN, IOC_OVERRIDE_DIS); gpio_register_callback(motion_interrupt_handler, MOTION_SENSOR_PORT, MOTION_SENSOR_PIN); process_start(&motion_int_process, NULL); GPIO_ENABLE_INTERRUPT(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); nvic_interrupt_enable(MOTION_SENSOR_VECTOR); return MOTION_SUCCESS; }
/*---------------------------------------------------------------------------*/ static int config_GPIO2(int type, int value) { config(BUTTON_GPIO2_PORT_BASE, BUTTON_GPIO2_PIN_MASK); ioc_set_over(BUTTON_GPIO2_PORT, BUTTON_GPIO2_PIN, IOC_OVERRIDE_PUE); nvic_interrupt_enable(BUTTON_GPIO2_VECTOR); gpio_register_callback(btn_callback, BUTTON_GPIO2_PORT, BUTTON_GPIO2_PIN); return 1; }
/*---------------------------------------------------------------------------*/ static void ssi_reconfigure(int init_tx_buffer) { int i; /* Disable SSI0 interrupt in NVIC */ nvic_interrupt_disable(NVIC_INT_SSI0); /* Reset SSI peripheral */ REG(SYS_CTRL_SRSSI) = 1; for(i = 0; i < 24; i++) { asm("nop"); } REG(SYS_CTRL_SRSSI) = 0; /* Enable the clock for the SSI peripheral */ REG(SYS_CTRL_RCGCSSI) |= 1; /* Start by disabling the peripheral before configuring it */ REG(SSI0_BASE + SSI_CR1) = 0; /* Set slave mode */ REG(SSI0_BASE + SSI_CR1) = SSI_CR1_MS;// | SSI_CR1_SOD; /* Set the IO clock as the SSI clock */ REG(SSI0_BASE + SSI_CC) = 1; /* Configure the clock */ REG(SSI0_BASE + SSI_CPSR) = 2;//64; /* Configure the default SPI options. * mode: Motorola frame format * clock: High when idle * data: Valid on rising edges of the clock * bits: 8 byte data */ REG(SSI0_BASE + SSI_CR0) = SSI_CR0_SPH | SSI_CR0_SPO | (0x07); if(init_tx_buffer) { /* initialize SPI TX FIFO (empty read answer) */ REG(SSI0_BASE + SSI_DR) = 0x50; REG(SSI0_BASE + SSI_DR) = 0xff; REG(SSI0_BASE + SSI_DR) = 0xff; REG(SSI0_BASE + SSI_DR) = 0xff; REG(SSI0_BASE + SSI_DR) = 0xff; REG(SSI0_BASE + SSI_DR) = 0xff; REG(SSI0_BASE + SSI_DR) = 0xff; REG(SSI0_BASE + SSI_DR) = 0xff; } /* Unmask interrupts (RX FIFO half full or more, and RX timeout) */ REG(SSI0_BASE + SSI_IM) = SSI_IM_RXIM | SSI_IM_RTIM; /* Enable the SSI */ REG(SSI0_BASE + SSI_CR1) |= SSI_CR1_SSE; /* Enable SSI0 interrupt in NVIC */ nvic_interrupt_enable(NVIC_INT_SSI0); }
/** * \brief Init function for the select button. * * Parameters are ignored. They have been included because the prototype is * dictated by the core sensor api. The return value is also not required by * the API but otherwise ignored. * * \param type ignored * \param value ignored * \return ignored */ static int config_relay_button(int type, int value) { config(RELAY_BUTTON_PORT_BASE, RELAY_BUTTON_PIN_MASK); ioc_set_over(RELAY_BUTTON_PORT, RELAY_BUTTON_PIN, IOC_OVERRIDE_PUE); nvic_interrupt_enable(RELAY_BUTTON_VECTOR); gpio_register_callback(btn_callback, RELAY_BUTTON_PORT, RELAY_BUTTON_PIN); return 1; }
/*---------------------------------------------------------------------------*/ void felicia_spi_init(void) { /* Initialize ring buffers for RX and TX data */ ringbuf_init(&spi_rx_buf, rxbuf_data, sizeof(rxbuf_data)); ringbuf_init(&spi_tx_buf, txbuf_data, sizeof(txbuf_data)); /* Configre SSI interface and init TX FIFO */ ssi_reconfigure(1); /* Set the mux correctly to connect the SSI pins to the correct GPIO pins */ /* set input pin with ioc */ REG(IOC_CLK_SSIIN_SSI0) = ioc_input_sel(SPI_CLK_PORT, SPI_CLK_PIN); REG(IOC_SSIFSSIN_SSI0) = ioc_input_sel(SPI_SEL_PORT, SPI_SEL_PIN); REG(IOC_SSIRXD_SSI0) = ioc_input_sel(SPI_MOSI_PORT, SPI_MOSI_PIN); /* set output pin */ ioc_set_sel(SPI_MISO_PORT, SPI_MISO_PIN, IOC_PXX_SEL_SSI0_TXD); /* Set pins as input and MISo as output */ GPIO_SET_INPUT(SPI_CLK_PORT_BASE, SPI_CLK_PIN_MASK); GPIO_SET_INPUT(SPI_MOSI_PORT_BASE, SPI_MOSI_PIN_MASK); GPIO_SET_INPUT(SPI_SEL_PORT_BASE, SPI_SEL_PIN_MASK); /* it seems that setting SEL as input is not necessary */ GPIO_SET_OUTPUT(SPI_MISO_PORT_BASE, SPI_MISO_PIN_MASK); /* Put all the SSI gpios into peripheral mode */ GPIO_PERIPHERAL_CONTROL(SPI_CLK_PORT_BASE, SPI_CLK_PIN_MASK); GPIO_PERIPHERAL_CONTROL(SPI_MOSI_PORT_BASE, SPI_MOSI_PIN_MASK); GPIO_PERIPHERAL_CONTROL(SPI_MISO_PORT_BASE, SPI_MISO_PIN_MASK); GPIO_PERIPHERAL_CONTROL(SPI_SEL_PORT_BASE, SPI_SEL_PIN_MASK); /* it seems that setting SEL: as peripheral controlled is not necessary */ /* Disable any pull ups or the like */ ioc_set_over(SPI_CLK_PORT, SPI_CLK_PIN, IOC_OVERRIDE_DIS); ioc_set_over(SPI_MOSI_PORT, SPI_MOSI_PIN, IOC_OVERRIDE_DIS); ioc_set_over(SPI_MISO_PORT, SPI_MISO_PIN, IOC_OVERRIDE_DIS); ioc_set_over(SPI_SEL_PORT, SPI_SEL_PIN, IOC_OVERRIDE_PDE); /* it seems that configuring pull-ups/downs on SEL is not necessary */ /* Configure output INT pin (from Felicia to Host */ GPIO_SET_OUTPUT(SPI_INT_PORT_BASE, SPI_INT_PIN_MASK); GPIO_CLR_PIN(SPI_INT_PORT_BASE, SPI_INT_PIN_MASK); /* Configure CS pin and detection for both edges on that pin */ GPIO_SOFTWARE_CONTROL(SPI_CS_PORT_BASE, SPI_CS_PIN_MASK); GPIO_SET_INPUT(SPI_CS_PORT_BASE, SPI_CS_PIN_MASK); GPIO_DETECT_EDGE(SPI_CS_PORT_BASE, SPI_CS_PIN_MASK); GPIO_TRIGGER_BOTH_EDGES(SPI_CS_PORT_BASE, SPI_CS_PIN_MASK); GPIO_ENABLE_INTERRUPT(SPI_CS_PORT_BASE, SPI_CS_PIN_MASK); ioc_set_over(SPI_CS_PORT, SPI_CS_PIN, IOC_OVERRIDE_PUE); /* Enable interrupt form CS pin */ nvic_interrupt_enable(NVIC_INT_GPIO_PORT_B); gpio_register_callback(cs_isr, SPI_CS_PORT, SPI_CS_PIN); }
/** * \brief Initialize configuration for the user button. * * \param type ignored * \param value ignored * \return ignored */ static int config_user_button(int type, int value) { config(USER_BUTTON_PORT_BASE, USER_BUTTON_PIN_MASK); ioc_set_over(USER_BUTTON_PORT, USER_BUTTON_PIN, IOC_OVERRIDE_PUE); timer_set(&debouncetimer, 0); nvic_interrupt_enable(USER_BUTTON_VECTOR); gpio_register_callback(user_button_irq_handler, USER_BUTTON_PORT, USER_BUTTON_PIN); return 1; }
/*---------------------------------------------------------------------------*/ static void set_poll_mode(uint8_t enable) { poll_mode = enable; if(enable) { mac_timer_init(); REG(RFCORE_XREG_RFIRQM0) &= ~RFCORE_XREG_RFIRQM0_FIFOP; /* mask out FIFOP interrupt source */ REG(RFCORE_SFR_RFIRQF0) &= ~RFCORE_SFR_RFIRQF0_FIFOP; /* clear pending FIFOP interrupt */ nvic_interrupt_disable(NVIC_INT_RF_RXTX); /* disable RF interrupts */ } else { REG(RFCORE_XREG_RFIRQM0) |= RFCORE_XREG_RFIRQM0_FIFOP; /* enable FIFOP interrupt source */ nvic_interrupt_enable(NVIC_INT_RF_RXTX); /* enable RF interrupts */ } }
//Use C0 to receive interrupt void configGPIOInterrupt(){ GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(0)); GPIO_SET_INPUT(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(0)); GPIO_DETECT_EDGE(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(0)); GPIO_DETECT_RISING(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(0)); GPIO_ENABLE_INTERRUPT(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(0)); GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(2)); GPIO_SET_INPUT(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(2)); GPIO_DETECT_EDGE(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(2)); GPIO_DETECT_FALLING(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(2)); GPIO_ENABLE_INTERRUPT(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(2)); ioc_set_over(GPIO_C_NUM,0, IOC_OVERRIDE_PUE); ioc_set_over(GPIO_C_NUM,2, IOC_OVERRIDE_PUE); nvic_interrupt_enable(NVIC_INT_GPIO_PORT_C); gpio_register_callback(cb,GPIO_C_NUM,0); gpio_register_callback(cb,GPIO_C_NUM,2); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(gpiot_process, ev, data) { PROCESS_BEGIN(); etimer_set(&periodic_timer_gpio, CLOCK_SECOND/10); GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(0)); GPIO_SET_INPUT(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(0));//input: pin: C0 GPIO_DETECT_EDGE(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(0)); GPIO_TRIGGER_SINGLE_EDGE(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(0)); GPIO_DETECT_RISING(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(0)); GPIO_ENABLE_INTERRUPT(GPIO_PORT_TO_BASE(GPIO_C_NUM), GPIO_PIN_MASK(0)); ioc_set_over(GPIO_C_NUM, 0, IOC_OVERRIDE_PUE); nvic_interrupt_enable(NVIC_INT_GPIO_PORT_C); gpio_register_callback(gp_int,GPIO_C_NUM, 0); while(1) { PROCESS_YIELD(); leds_toggle(LEDS_RED); etimer_restart(&periodic_timer_gpio); } PROCESS_END(); }
/** * \brief Initialize the nRF51822. */ void nrf51822_init() { // Setup interrupt from nRF51822 GPIO_SOFTWARE_CONTROL(NRF51822_INT_BASE, NRF51822_INT_MASK); GPIO_SET_INPUT(NRF51822_INT_BASE, NRF51822_INT_MASK); GPIO_DETECT_EDGE(NRF51822_INT_BASE, NRF51822_INT_MASK); GPIO_TRIGGER_SINGLE_EDGE(NRF51822_INT_BASE, NRF51822_INT_MASK); GPIO_DETECT_RISING(NRF51822_INT_BASE, NRF51822_INT_MASK); GPIO_ENABLE_INTERRUPT(NRF51822_INT_BASE, NRF51822_INT_MASK); ioc_set_over(NRF51822_INT_PORT_NUM, 0, IOC_OVERRIDE_DIS); nvic_interrupt_enable(NVIC_INT_GPIO_PORT_B); gpio_register_callback(nrf51822_interrupt, NRF51822_INT_PORT_NUM, NRF51822_INT_PIN); spi_cs_init(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); SPI_CS_SET(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); }
/** * \brief Init function for the User button. * \param type SENSORS_ACTIVE: Activate / Deactivate the sensor (value == 1 * or 0 respectively) * * \param value Depends on the value of the type argument * \return Depends on the value of the type argument */ static int config_user(int type, int value) { switch(type) { case SENSORS_HW_INIT: button_press_duration_exceeded = process_alloc_event(); /* Software controlled */ GPIO_SOFTWARE_CONTROL(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); /* Set pin to input */ GPIO_SET_INPUT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); /* Enable edge detection */ GPIO_DETECT_EDGE(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); /* Both Edges */ GPIO_TRIGGER_BOTH_EDGES(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); ioc_set_over(BUTTON_USER_PORT, BUTTON_USER_PIN, IOC_OVERRIDE_PUE); gpio_register_callback(btn_callback, BUTTON_USER_PORT, BUTTON_USER_PIN); break; case SENSORS_ACTIVE: if(value) { GPIO_ENABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); nvic_interrupt_enable(BUTTON_USER_VECTOR); } else { GPIO_DISABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); nvic_interrupt_disable(BUTTON_USER_VECTOR); } return value; case BUTTON_SENSOR_CONFIG_TYPE_INTERVAL: press_duration = (clock_time_t)value; break; default: break; } return 1; }
/*---------------------------------------------------------------------------*/ void uart_init(uint8_t uart) { const uart_regs_t *regs; if(uart >= UART_INSTANCE_COUNT) { return; } regs = &uart_regs[uart]; if(regs->rx.port < 0 || regs->tx.port < 0) { return; } lpm_register_peripheral(permit_pm1); /* Enable clock for the UART while Running, in Sleep and Deep Sleep */ REG(SYS_CTRL_RCGCUART) |= regs->sys_ctrl_rcgcuart_uart; REG(SYS_CTRL_SCGCUART) |= regs->sys_ctrl_scgcuart_uart; REG(SYS_CTRL_DCGCUART) |= regs->sys_ctrl_dcgcuart_uart; /* Run on SYS_DIV */ REG(regs->base | UART_CC) = 0; /* * Select the UARTx RX pin by writing to the IOC_UARTRXD_UARTn register * * The value to be written will be on of the IOC_INPUT_SEL_Pxn defines from * ioc.h. The value can also be calculated as: * * (port << 3) + pin */ REG(regs->ioc_uartrxd_uart) = (regs->rx.port << 3) + regs->rx.pin; /* * Pad Control for the TX pin: * - Set function to UARTn TX * - Output Enable */ ioc_set_sel(regs->tx.port, regs->tx.pin, regs->ioc_pxx_sel_uart_txd); ioc_set_over(regs->tx.port, regs->tx.pin, IOC_OVERRIDE_OE); /* Set RX and TX pins to peripheral mode */ GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->tx.port), GPIO_PIN_MASK(regs->tx.pin)); GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->rx.port), GPIO_PIN_MASK(regs->rx.pin)); /* * UART Interrupt Masks: * Acknowledge RX and RX Timeout * Acknowledge Framing, Overrun and Break Errors */ REG(regs->base | UART_IM) = UART_IM_RXIM | UART_IM_RTIM; REG(regs->base | UART_IM) |= UART_IM_OEIM | UART_IM_BEIM | UART_IM_FEIM; REG(regs->base | UART_IFLS) = UART_IFLS_RXIFLSEL_1_8 | UART_IFLS_TXIFLSEL_1_2; /* Make sure the UART is disabled before trying to configure it */ REG(regs->base | UART_CTL) = UART_CTL_VALUE; /* Baud Rate Generation */ REG(regs->base | UART_IBRD) = regs->ibrd; REG(regs->base | UART_FBRD) = regs->fbrd; /* UART Control: 8N1 with FIFOs */ REG(regs->base | UART_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN; /* * Enable hardware flow control (RTS/CTS) if requested. * Note that hardware flow control is available only on UART1. */ if(regs->cts.port >= 0) { REG(IOC_UARTCTS_UART1) = ioc_input_sel(regs->cts.port, regs->cts.pin); GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->cts.port), GPIO_PIN_MASK(regs->cts.pin)); ioc_set_over(regs->cts.port, regs->cts.pin, IOC_OVERRIDE_DIS); REG(UART_1_BASE | UART_CTL) |= UART_CTL_CTSEN; } if(regs->rts.port >= 0) { ioc_set_sel(regs->rts.port, regs->rts.pin, IOC_PXX_SEL_UART1_RTS); GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->rts.port), GPIO_PIN_MASK(regs->rts.pin)); ioc_set_over(regs->rts.port, regs->rts.pin, IOC_OVERRIDE_OE); REG(UART_1_BASE | UART_CTL) |= UART_CTL_RTSEN; } /* UART Enable */ REG(regs->base | UART_CTL) |= UART_CTL_UARTEN; /* Enable UART0 Interrupts */ nvic_interrupt_enable(regs->nvic_int); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(mainProcess, ev, data) { PROCESS_BEGIN(); GPIO_SET_OUTPUT(GPIO_A_BASE, 0xf8); GPIO_SET_OUTPUT(GPIO_B_BASE, 0x0f); GPIO_SET_OUTPUT(GPIO_C_BASE, 0x02); GPIO_CLR_PIN(GPIO_A_BASE, 0xf8); GPIO_CLR_PIN(GPIO_B_BASE, 0x07); GPIO_SET_PIN(EDISON_WAKEUP_BASE, EDISON_WAKEUP_PIN_MASK); // edison WAKEUP GPIO_SET_INPUT(RESET_PORT_BASE, RESET_PIN_MASK); // reset ioc_set_over(RESET_PORT, RESET_PIN, IOC_OVERRIDE_PUE); leds_off(LEDS_RED); leds_off(LEDS_GREEN); leds_off(LEDS_BLUE); // RESET interrupt, active low GPIO_DETECT_EDGE(RESET_PORT_BASE, RESET_PIN_MASK); GPIO_DETECT_FALLING(RESET_PORT_BASE, RESET_PIN_MASK); GPIO_TRIGGER_SINGLE_EDGE(RESET_PORT_BASE, RESET_PIN_MASK); gpio_register_callback(resetcallBack, RESET_PORT, RESET_PIN); GPIO_ENABLE_INTERRUPT(RESET_PORT_BASE, RESET_PIN_MASK); nvic_interrupt_enable(RESET_NVIC_PORT); GPIO_CLR_PIN(TRIUMVI_DATA_READY_PORT_BASE, TRIUMVI_DATA_READY_MASK); // SPI CS interrupt GPIO_DETECT_EDGE(SPI0_CS_PORT_BASE, SPI0_CS_PIN_MASK); GPIO_DETECT_RISING(SPI0_CS_PORT_BASE, SPI0_CS_PIN_MASK); GPIO_TRIGGER_SINGLE_EDGE(SPI0_CS_PORT_BASE, SPI0_CS_PIN_MASK); gpio_register_callback(spiCScallBack, SPI0_CS_PORT, SPI0_CS_PIN); GPIO_ENABLE_INTERRUPT(SPI0_CS_PORT_BASE, SPI0_CS_PIN_MASK); // SPI interface spix_slave_init(SPIDEV); spix_txdma_enable(SPIDEV); spi_register_callback(spiFIFOcallBack); spix_interrupt_enable(SPIDEV, SSI_IM_RXIM_M); // RX FIFO half full nvic_interrupt_enable(NVIC_INT_SSI0); // uDMA SPI0 TX udma_channel_disable(CC2538_SPI0_TX_DMA_CHAN); udma_channel_prio_set_default(CC2538_SPI0_TX_DMA_CHAN); udma_channel_use_primary(CC2538_SPI0_TX_DMA_CHAN); udma_channel_use_single(CC2538_SPI0_TX_DMA_CHAN); udma_channel_mask_clr(CC2538_SPI0_TX_DMA_CHAN); udma_set_channel_dst(CC2538_SPI0_TX_DMA_CHAN, SPI0DR); udma_set_channel_assignment(CC2538_SPI0_TX_DMA_CHAN, UDMA_CH11_SSI0TX); simple_network_set_callback(&rf_rx_handler); //NETSTACK_RADIO.off(); process_start(&decryptProcess, NULL); process_start(&spiProcess, NULL); while (1){ PROCESS_YIELD(); // buffer is not empty, spi is not in use //if ((spiInUse==0) && (spix_busy(SPIDEV)==0) && ((triumviAvailIDX!=triumviFullIDX) || (triumviRXBufFull==1))){ if ((spiInUse==0) && ((triumviAvailIDX!=triumviFullIDX) || (triumviRXBufFull==1))){ GPIO_SET_PIN(TRIUMVI_DATA_READY_PORT_BASE, TRIUMVI_DATA_READY_MASK); if (triumviRXBufFull==1){ resetCnt += 1; if (resetCnt==RESET_THRESHOLD){ watchdog_reboot(); } } #ifdef LED_DEBUG leds_off(LEDS_RED); leds_off(LEDS_GREEN); leds_off(LEDS_BLUE); #endif } // Fail safe, CC2538 missing some SPI commands, reset spi state else if (triumviRXBufFull==1){ spiState = SPI_RESET; process_poll(&spiProcess); #ifdef LED_DEBUG leds_off(LEDS_RED); leds_off(LEDS_GREEN); leds_on(LEDS_BLUE); #endif } } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ void uart_init(void) { lpm_register_peripheral(permit_pm1); /* Enable clock for the UART while Running, in Sleep and Deep Sleep */ REG(SYS_CTRL_RCGCUART) |= SYS_CTRL_RCGCUART_UART; REG(SYS_CTRL_SCGCUART) |= SYS_CTRL_SCGCUART_UART; REG(SYS_CTRL_DCGCUART) |= SYS_CTRL_DCGCUART_UART; /* Run on SYS_DIV */ REG(UART_BASE | UART_CC) = 0; /* * Select the UARTx RX pin by writing to the IOC_UARTRXD_UARTn register * * The value to be written will be on of the IOC_INPUT_SEL_Pxn defines from * ioc.h. The value can also be calculated as: * * (port << 3) + pin */ REG(IOC_UARTRXD_UART) = (UART_RX_PORT << 3) + UART_RX_PIN; /* * Pad Control for the TX pin: * - Set function to UART0 TX * - Output Enable */ ioc_set_sel(UART_TX_PORT, UART_TX_PIN, IOC_PXX_SEL_UART_TXD); ioc_set_over(UART_TX_PORT, UART_TX_PIN, IOC_OVERRIDE_OE); /* Set RX and TX pins to peripheral mode */ GPIO_PERIPHERAL_CONTROL(UART_TX_PORT_BASE, UART_TX_PIN_MASK); GPIO_PERIPHERAL_CONTROL(UART_RX_PORT_BASE, UART_RX_PIN_MASK); /* * UART Interrupt Masks: * Acknowledge RX and RX Timeout * Acknowledge Framing, Overrun and Break Errors */ REG(UART_BASE | UART_IM) = UART_IM_RXIM | UART_IM_RTIM; REG(UART_BASE | UART_IM) |= UART_IM_OEIM | UART_IM_BEIM | UART_IM_FEIM; REG(UART_BASE | UART_IFLS) = UART_IFLS_RXIFLSEL_1_8 | UART_IFLS_TXIFLSEL_1_2; /* Make sure the UART is disabled before trying to configure it */ REG(UART_BASE | UART_CTL) = UART_CTL_TXE | UART_CTL_RXE; /* Baud Rate Generation */ REG(UART_BASE | UART_IBRD) = UART_CONF_IBRD; REG(UART_BASE | UART_FBRD) = UART_CONF_FBRD; /* UART Control: 8N1 with FIFOs */ REG(UART_BASE | UART_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN; /* UART Enable */ REG(UART_BASE | UART_CTL) |= UART_CTL_UARTEN; /* Enable UART0 Interrupts */ nvic_interrupt_enable(NVIC_INT_UART); }
/*---------------------------------------------------------------------------*/ static int configure(int type, int value) { if((type != WEATHER_METER_ACTIVE) && (type != WEATHER_METER_ANEMOMETER_INT_OVER) && (type != WEATHER_METER_RAIN_GAUGE_INT_OVER) && (type != WEATHER_METER_ANEMOMETER_INT_DIS) && (type != WEATHER_METER_RAIN_GAUGE_INT_DIS)) { PRINTF("Weather: invalid configuration option\n"); return WEATHER_METER_ERROR; } if(type == WEATHER_METER_ACTIVE) { anemometer.value_avg = 0; anemometer.ticks_avg = 0; weather_sensors.anemometer.int_en = 0; weather_sensors.rain_gauge.int_en = 0; weather_sensors.anemometer.ticks = 0; weather_sensors.rain_gauge.ticks = 0; weather_sensors.anemometer.value = 0; weather_sensors.rain_gauge.value = 0; if(!value) { anemometer_int_callback = NULL; rain_gauge_int_callback = NULL; GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); GPIO_DISABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); process_exit(&weather_meter_int_process); enabled = 0; PRINTF("Weather: disabled\n"); return WEATHER_METER_SUCCESS; } /* Configure the wind vane */ adc_zoul.configure(SENSORS_HW_INIT, WIND_VANE_ADC); /* Configure anemometer interruption */ GPIO_SOFTWARE_CONTROL(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); GPIO_SET_INPUT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); GPIO_DETECT_RISING(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); GPIO_TRIGGER_SINGLE_EDGE(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); ioc_set_over(ANEMOMETER_SENSOR_PORT, ANEMOMETER_SENSOR_PIN, IOC_OVERRIDE_DIS); gpio_register_callback(weather_meter_interrupt_handler, ANEMOMETER_SENSOR_PORT, ANEMOMETER_SENSOR_PIN); /* Configure rain gauge interruption */ GPIO_SOFTWARE_CONTROL(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); GPIO_SET_INPUT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); GPIO_DETECT_RISING(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); GPIO_TRIGGER_SINGLE_EDGE(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); ioc_set_over(RAIN_GAUGE_SENSOR_PORT, RAIN_GAUGE_SENSOR_PIN, IOC_OVERRIDE_DIS); gpio_register_callback(weather_meter_interrupt_handler, RAIN_GAUGE_SENSOR_PORT, RAIN_GAUGE_SENSOR_PIN); process_start(&weather_meter_int_process, NULL); /* Initialize here prior the first second tick */ wind_vane.value_prev = weather_meter_get_wind_dir(); ctimer_set(&ct, CLOCK_SECOND, ct_callback, NULL); GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); GPIO_ENABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); nvic_interrupt_enable(ANEMOMETER_SENSOR_VECTOR); nvic_interrupt_enable(RAIN_GAUGE_SENSOR_VECTOR); enabled = 1; PRINTF("Weather: started\n"); return WEATHER_METER_SUCCESS; } switch(type) { case WEATHER_METER_ANEMOMETER_INT_OVER: weather_sensors.anemometer.int_en = 1; weather_sensors.anemometer.int_thres = value; PRINTF("Weather: anemometer threshold %u\n", value); break; case WEATHER_METER_RAIN_GAUGE_INT_OVER: weather_sensors.rain_gauge.int_en = 1; weather_sensors.rain_gauge.int_thres = value; PRINTF("Weather: rain gauge threshold %u\n", value); break; case WEATHER_METER_ANEMOMETER_INT_DIS: PRINTF("Weather: anemometer int disabled\n"); weather_sensors.anemometer.int_en = 0; break; case WEATHER_METER_RAIN_GAUGE_INT_DIS: PRINTF("Weather: rain gauge int disabled\n"); weather_sensors.rain_gauge.int_en = 0; break; default: return WEATHER_METER_ERROR; } return WEATHER_METER_SUCCESS; }
/*---------------------------------------------------------------------------*/ static int init(void) { PRINTF("RF: Init\n"); if(rf_flags & RF_ON) { return 0; } /* Enable clock for the RF Core while Running, in Sleep and Deep Sleep */ REG(SYS_CTRL_RCGCRFC) = 1; REG(SYS_CTRL_SCGCRFC) = 1; REG(SYS_CTRL_DCGCRFC) = 1; REG(RFCORE_XREG_CCACTRL0) = CC2538_RF_CCA_THRES_USER_GUIDE; /* * Changes from default values * See User Guide, section "Register Settings Update" */ REG(RFCORE_XREG_TXFILTCFG) = 0x09; /** TX anti-aliasing filter bandwidth */ REG(RFCORE_XREG_AGCCTRL1) = 0x15; /** AGC target value */ REG(ANA_REGS_IVCTRL) = 0x0B; /** Bias currents */ /* * Defaults: * Auto CRC; Append RSSI, CRC-OK and Corr. Val.; CRC calculation; * RX and TX modes with FIFOs */ REG(RFCORE_XREG_FRMCTRL0) = RFCORE_XREG_FRMCTRL0_AUTOCRC; #if CC2538_RF_AUTOACK REG(RFCORE_XREG_FRMCTRL0) |= RFCORE_XREG_FRMCTRL0_AUTOACK; #endif /* If we are a sniffer, turn off frame filtering */ #if CC2538_RF_CONF_SNIFFER REG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN; #endif /* Disable source address matching and autopend */ REG(RFCORE_XREG_SRCMATCH) = 0; /* MAX FIFOP threshold */ REG(RFCORE_XREG_FIFOPCTRL) = CC2538_RF_MAX_PACKET_LEN; /* Set TX Power */ REG(RFCORE_XREG_TXPOWER) = CC2538_RF_TX_POWER; set_channel(rf_channel); /* Acknowledge RF interrupts, FIFOP only */ REG(RFCORE_XREG_RFIRQM0) |= RFCORE_XREG_RFIRQM0_FIFOP; nvic_interrupt_enable(NVIC_INT_RF_RXTX); /* Acknowledge all RF Error interrupts */ REG(RFCORE_XREG_RFERRM) = RFCORE_XREG_RFERRM_RFERRM; nvic_interrupt_enable(NVIC_INT_RF_ERR); if(CC2538_RF_CONF_TX_USE_DMA) { /* Disable peripheral triggers for the channel */ udma_channel_mask_set(CC2538_RF_CONF_TX_DMA_CHAN); /* * Set the channel's DST. SRC can not be set yet since it will change for * each transfer */ udma_set_channel_dst(CC2538_RF_CONF_TX_DMA_CHAN, RFCORE_SFR_RFDATA); } if(CC2538_RF_CONF_RX_USE_DMA) { /* Disable peripheral triggers for the channel */ udma_channel_mask_set(CC2538_RF_CONF_RX_DMA_CHAN); /* * Set the channel's SRC. DST can not be set yet since it will change for * each transfer */ udma_set_channel_src(CC2538_RF_CONF_RX_DMA_CHAN, RFCORE_SFR_RFDATA); } process_start(&cc2538_rf_process, NULL); rf_flags |= RF_ON; ENERGEST_ON(ENERGEST_TYPE_LISTEN); return 1; }
/*---------------------------------------------------------------------------*/ uint8_t aes_auth_crypt_start(uint32_t ctrl, uint8_t key_area, const void *iv, const void *adata, uint16_t adata_len, const void *data_in, void *data_out, uint16_t data_len, struct process *process) { if(REG(AES_CTRL_ALG_SEL) != 0x00000000) { return CRYPTO_RESOURCE_IN_USE; } /* Workaround for AES registers not retained after PM2 */ REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE | AES_CTRL_INT_EN_RESULT_AV; REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_AES; REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | AES_CTRL_INT_CLR_RESULT_AV; REG(AES_KEY_STORE_READ_AREA) = key_area; /* Wait until key is loaded to the AES module */ while(REG(AES_KEY_STORE_READ_AREA) & AES_KEY_STORE_READ_AREA_BUSY); /* Check for Key Store read error */ if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) { /* Clear the Keystore Read error bit */ REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_RD_ERR; /* Disable the master control / DMA clock */ REG(AES_CTRL_ALG_SEL) = 0x00000000; return AES_KEYSTORE_READ_ERROR; } if(iv != NULL) { /* Write initialization vector */ REG(AES_AES_IV_0) = ((const uint32_t *)iv)[0]; REG(AES_AES_IV_1) = ((const uint32_t *)iv)[1]; REG(AES_AES_IV_2) = ((const uint32_t *)iv)[2]; REG(AES_AES_IV_3) = ((const uint32_t *)iv)[3]; } /* Program AES authentication/crypto operation */ REG(AES_AES_CTRL) = ctrl; /* Write the length of the payload block (lo) */ REG(AES_AES_C_LENGTH_0) = data_len; /* Write the length of the payload block (hi) */ REG(AES_AES_C_LENGTH_1) = 0; /* For combined modes only (CCM or GCM) */ if(ctrl & (AES_AES_CTRL_CCM | AES_AES_CTRL_GCM)) { /* Write the length of the AAD data block (may be non-block size-aligned) */ REG(AES_AES_AUTH_LENGTH) = adata_len; if(adata_len != 0) { /* Configure DMAC to fetch the AAD data * Enable DMA channel 0 */ REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; /* Base address of the AAD data buffer */ REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)adata; /* AAD data length in bytes */ REG(AES_DMAC_CH0_DMALENGTH) = adata_len; /* Wait for completion of the AAD data transfer, DMA_IN_DONE */ while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_IN_DONE)); /* Check for the absence of error */ if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) { /* Clear the DMA error */ REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR; /* Disable the master control / DMA clock */ REG(AES_CTRL_ALG_SEL) = 0x00000000; return CRYPTO_DMA_BUS_ERROR; } /* Clear interrupt status */ REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE; } } /* Enable result available bit in interrupt enable */ REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_RESULT_AV; if(process != NULL) { crypto_register_process_notification(process); nvic_interrupt_unpend(NVIC_INT_AES); nvic_interrupt_enable(NVIC_INT_AES); } if(data_len != 0) { /* Configure DMAC * Enable DMA channel 0 */ REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; /* Base address of the input payload data buffer */ REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)data_in; /* Input payload data length in bytes */ REG(AES_DMAC_CH0_DMALENGTH) = data_len; if(data_out != NULL) { /* Enable DMA channel 1 */ REG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH_CTRL_EN; /* Base address of the output payload data buffer */ REG(AES_DMAC_CH1_EXTADDR) = (uint32_t)data_out; /* Output payload data length in bytes */ REG(AES_DMAC_CH1_DMALENGTH) = data_len; } } return CRYPTO_SUCCESS; }