/*---------------------------------------------------------------------------*/ 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); }
/*---------------------------------------------------------------------------*/ void i2c_init(uint8_t port_sda, uint8_t pin_sda, uint8_t port_scl, uint8_t pin_scl, uint32_t bus_speed) { /* Enable I2C clock in different modes */ REG(SYS_CTRL_RCGCI2C) |= 1; /* Run mode */ /* Reset I2C peripheral */ REG(SYS_CTRL_SRI2C) |= 1; /* Reset position */ /* Delay for a little bit */ clock_delay_usec(50); REG(SYS_CTRL_SRI2C) &= ~1; /* Normal position */ /* Set pins in input */ GPIO_SET_INPUT(GPIO_PORT_TO_BASE(port_sda), GPIO_PIN_MASK(pin_sda)); GPIO_SET_INPUT(GPIO_PORT_TO_BASE(port_scl), GPIO_PIN_MASK(pin_scl)); /* Set peripheral control for the pins */ GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(port_sda), GPIO_PIN_MASK(pin_sda)); GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(port_scl), GPIO_PIN_MASK(pin_scl)); /* Set the pad to no drive type */ ioc_set_over(port_sda, pin_sda, IOC_OVERRIDE_DIS); ioc_set_over(port_scl, pin_scl, IOC_OVERRIDE_DIS); /* Set pins as peripheral inputs */ REG(IOC_I2CMSSDA) = ioc_input_sel(port_sda, pin_sda); REG(IOC_I2CMSSCL) = ioc_input_sel(port_scl, pin_scl); /* Set pins as peripheral outputs */ ioc_set_sel(port_sda, pin_sda, IOC_PXX_SEL_I2C_CMSSDA); ioc_set_sel(port_scl, pin_scl, IOC_PXX_SEL_I2C_CMSSCL); /* Enable the I2C master module */ i2c_master_enable(); /* t the master clock frequency */ i2c_set_frequency(bus_speed); }
/** * \brief Initialize the SPI bus. * * This SPI init() function uses the following defines to set the pins: * SPI_CLK_PORT SPI_CLK_PIN * SPI_MOSI_PORT SPI_MOSI_PIN * SPI_MISO_PORT SPI_MISO_PIN * * This sets the mode to Motorola SPI with the following format options: * Clock phase: 1; data captured on second (rising) edge * Clock polarity: 1; clock is high when idle * Data size: 8 bits */ void spi_init(void) { spi_enable(); /* Start by disabling the peripheral before configuring it */ REG(SSI0_BASE + SSI_CR1) = 0; /* Set the IO clock as the SSI clock */ REG(SSI0_BASE + SSI_CC) = 1; /* Set the mux correctly to connect the SSI pins to the correct GPIO pins */ ioc_set_sel(SPI_CLK_PORT, SPI_CLK_PIN, IOC_PXX_SEL_SSI0_CLKOUT); ioc_set_sel(SPI_MOSI_PORT, SPI_MOSI_PIN, IOC_PXX_SEL_SSI0_TXD); REG(IOC_SSIRXD_SSI0) = (SPI_MISO_PORT * 8) + SPI_MISO_PIN; /* 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); /* 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); /* Configure the clock */ REG(SSI0_BASE + SSI_CPSR) = 2; /* 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); /* Enable the SSI */ REG(SSI0_BASE + SSI_CR1) |= SSI_CR1_SSE; }
/** * \brief Initialize the SPI bus. * * This SPI init() function uses the following #defines to set the pins: * SPI_CLK_PORT SPI_CLK_PIN * SPI_MOSI_PORT SPI_MOSI_PIN * SPI_MISO_PORT SPI_MISO_PIN * SPI_SEL_PORT SPI_SEL_PIN * * This sets the mode to Motorola SPI with the following format options: * SPI_CONF_PHASE: 0 or SSI_CR0_SPH * SPI_CONF_POLARITY: 0 or SSI_CR0_SPO * SPI_CONF_DATA_SIZE: 4 to 16 bits */ void spi_init(void) { spi_enable(); /* Start by disabling the peripheral before configuring it */ REG(SSI0_BASE + SSI_CR1) = 0; /* Set the IO clock as the SSI clock */ REG(SSI0_BASE + SSI_CC) = 1; /* Set the mux correctly to connect the SSI pins to the correct GPIO pins */ ioc_set_sel(SPI_CLK_PORT, SPI_CLK_PIN, IOC_PXX_SEL_SSI0_CLKOUT); ioc_set_sel(SPI_MOSI_PORT, SPI_MOSI_PIN, IOC_PXX_SEL_SSI0_TXD); REG(IOC_SSIRXD_SSI0) = (SPI_MISO_PORT * 8) + SPI_MISO_PIN; ioc_set_sel(SPI_SEL_PORT, SPI_SEL_PIN, IOC_PXX_SEL_SSI0_FSSOUT); /* 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); /* 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_DIS); /* Configure the clock */ REG(SSI0_BASE + SSI_CPSR) = 2; /* Put the ssi in Motorola SPI mode using the provided format options */ REG(SSI0_BASE + SSI_CR0) = SPI_CONF_PHASE | SPI_CONF_POLARITY | (SPI_CONF_DATA_SIZE - 1); /* Enable the SSI */ REG(SSI0_BASE + SSI_CR1) |= SSI_CR1_SSE; }
//Config PA1 as an PWM output pin void initPWM() { //Timer is 16Mhz /* Enable module clock for the GPTx in Active mode, GPT0 clock enable, CPU running */ REG(SYS_CTRL_RCGCGPT) |= SYS_CTRL_RCGCGPT_GPT0; disable_gptimer(); /* Use 16-bit timer */ REG(GPT_CONF_BASE + GPTIMER_CFG) = 0x04; /* Configure PWM mode, 0x00000008 Timer A alternate mode. */ REG(GPT_CONF_BASE + GPTIMER_TAMR) = 0; REG(GPT_CONF_BASE + GPTIMER_TAMR) |= GPTIMER_TAMR_TAAMS; /* To enable PWM mode, the TACM bit must be cleared and the lowest 2 bits (TAMR) field must be configured to 0x2. GPTIMER_TnMR bit values, GPTIMER_TAMR_TAMR_PERIODIC is 0x00000002 */ REG(GPT_CONF_BASE + GPTIMER_TAMR) |= GPTIMER_TAMR_TAMR_PERIODIC; //how often the counter is incremented: every pre-scaler / clock 16000000 seconds REG(GPT_CONF_BASE + GPTIMER_TAPR) = 0; //PRESCALER_VALUE /* Set the start value (period), count down */ REG(GPT_CONF_BASE+ GPTIMER_TAILR) = 16000; //frequency: 1kHz. 16000: 3E80, 16000000:F42400 /* Set the deassert period */ REG(GPT_CONF_BASE + GPTIMER_TAMATCHR) = 12800; //duty cycle: 20% so vibrator time is 20%. 800: 0x1F40, 8000000: 7A1200 // Defined in contiki/cpu/cc2538/dev/ioc.h /* Function select for Port:Pin. The third param sel can be any of the IOC_PXX_SEL_xyz defines. For example, IOC_PXX_SEL_UART0_TXD will set the port to act as UART0 TX. Selects one of the 32 pins on the four 8-pin I/O-ports (port A, port B, port C, and port D) to be the GPT0OCP1. Configure pin : PA:1 selected as GPT0OCP1*/ ioc_set_sel(PWM_GPIO_CONF_PORT, PWM_GPIO_CONF_PIN, IOC_CONF_SEL); /* Set Port:Pin override function, IOC_OVERRIDE_OE: Output */ ioc_set_over(PWM_GPIO_CONF_PORT, PWM_GPIO_CONF_PIN, IOC_OVERRIDE_OE); /* Configure the pin to be under peripheral control with PIN_MASK of port with PORT_BASE.*/ GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(PWM_GPIO_CONF_PORT), GPIO_PIN_MASK(PWM_GPIO_CONF_PIN)); enable_gptimer(); }
/*---------------------------------------------------------------------------*/ 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); }
/*---------------------------------------------------------------------------*/ 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); }