void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) { /* Sanity check arguments */ MBED_ASSERT(obj); if(FlowControlNone == type) { /* Disable Hardware Handshaking. */ _USART(obj)->US_MR = (_USART(obj)->US_MR & ~US_MR_USART_MODE_Msk) | US_MR_USART_MODE_NORMAL; return; } /*To determine the uart peripheral associated with pins*/ UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS); UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS); UARTName uart = (UARTName)pinmap_merge(uart_cts, uart_rts); MBED_ASSERT(uart != (UARTName)NC); if((FlowControlCTS == type) || (FlowControlRTSCTS== type)) { /* Configure CTS pin. */ pin_function(txflow, pinmap_find_function(txflow, PinMap_UART_CTS)); ioport_disable_pin(txflow); } if((FlowControlRTS == type) || (FlowControlRTSCTS== type)) { /* Configure CTS pin. */ pin_function(rxflow, pinmap_find_function(rxflow, PinMap_UART_RTS)); ioport_disable_pin(rxflow); } /* Set hardware handshaking mode. */ _USART(obj)->US_MR = (_USART(obj)->US_MR & ~US_MR_USART_MODE_Msk) | US_MR_USART_MODE_HW_HANDSHAKING; }
/** Initialize the SPI peripheral * * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral * @param[out] obj The SPI object to initialize * @param[in] mosi The pin to use for MOSI * @param[in] miso The pin to use for MISO * @param[in] sclk The pin to use for SCLK */ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk) { MBED_ASSERT(obj); MBED_ASSERT(mosi !=NC && miso!=NC && sclk !=NC ); if (g_sys_init == 0) { sysclk_init(); system_board_init(); g_sys_init = 1; } Spi *sercombase = pinmap_find_sercom(mosi,miso,sclk); MBED_ASSERT(sercombase!=NC); pinmap_find_spi_info(sercombase, obj); MBED_ASSERT(obj->spi.flexcom!=NC); MBED_ASSERT(obj->spi.pdc!=NC); /* Configure SPI pins */ pin_function(mosi, pinmap_find_function(mosi, PinMap_SPI_MOSI)); ioport_disable_pin(mosi); pin_function(miso, pinmap_find_function(miso, PinMap_SPI_MISO)); ioport_disable_pin(miso); pin_function(sclk, pinmap_find_function(sclk, PinMap_SPI_SCLK)); ioport_disable_pin(sclk); #if (SAMG55) /* Enable the peripheral and set SPI mode. */ flexcom_enable(obj->spi.flexcom); flexcom_set_opmode(obj->spi.flexcom, FLEXCOM_SPI); #else /* Configure an SPI peripheral. */ spi_enable_clock(sercombase); #endif spi_disable(sercombase); spi_reset(sercombase); spi_set_lastxfer(sercombase); spi_set_master_mode(sercombase); spi_disable_mode_fault_detect(sercombase); spi_set_peripheral_chip_select_value(sercombase, SPI_CHIP_SEL); spi_set_clock_polarity(sercombase, SPI_CHIP_SEL, SPI_CLK_POLARITY); spi_set_clock_phase(sercombase, SPI_CHIP_SEL, SPI_CLK_PHASE); spi_set_bits_per_transfer(sercombase, SPI_CHIP_SEL, SPI_CSR_BITS_8_BIT); spi_set_baudrate_div(sercombase, SPI_CHIP_SEL,(sysclk_get_cpu_hz() / gSPI_clock)); spi_set_transfer_delay(sercombase, SPI_CHIP_SEL, SPI_DLYBS,SPI_DLYBCT); spi_enable(sercombase); pdc_disable_transfer(obj->spi.pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); obj->spi.spi_base=sercombase; obj->spi.cs= SPI_CHIP_SEL; obj->spi.polarity=SPI_CLK_POLARITY; obj->spi.phase=SPI_CLK_PHASE; obj->spi.transferrate=SPI_CSR_BITS_8_BIT; obj->spi.is_slave=0; }
//****************************************************************************** void serial_init(serial_t *obj, PinName tx, PinName rx) { // Determine which uart is associated with each pin UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); // Make sure that both pins are pointing to the same uart MBED_ASSERT(uart != (UARTName)NC); // Set the obj pointer to the proper uart obj->uart = (mxc_uart_regs_t*)uart; // Set the uart index obj->index = MXC_UART_GET_IDX(obj->uart); obj->fifo = (mxc_uart_fifo_regs_t*)MXC_UART_GET_BASE_FIFO(obj->index); // Record the pins requested obj->tx = tx; obj->rx = rx; // Merge pin function requests for use with CMSIS init func ioman_req_t io_req = {0}; pin_function_t *pin_func = NULL; if (tx != NC) { pin_func = (pin_function_t *)pinmap_find_function(tx, PinMap_UART_TX); io_req.value = pin_func->req_val; } if (rx != NC) { pin_func = (pin_function_t *)pinmap_find_function(rx, PinMap_UART_RX); io_req.value |= pin_func->req_val; } // Using req and ack pointers of last pin function lookup obj->sys_cfg.io_cfg.req_reg = pin_func->reg_req; obj->sys_cfg.io_cfg.ack_reg = pin_func->reg_ack; obj->sys_cfg.io_cfg.req_val = io_req; obj->sys_cfg.clk_scale = CLKMAN_SCALE_DIV_8; // Configure the UART with default parameters obj->cfg.extra_stop = 0; obj->cfg.cts = 0; obj->cfg.rts = 0; obj->cfg.baud = DEFAULT_BAUD; obj->cfg.size = UART_DATA_SIZE_8_BITS; obj->cfg.parity = UART_PARITY_DISABLE; // Manage stdio UART if (uart == STDIO_UART) { stdio_uart_inited = 1; stdio_uart = *obj; } int retval = UART_Init(obj->uart, &obj->cfg, &obj->sys_cfg); MBED_ASSERT(retval == E_NO_ERROR); objs[obj->index] = obj; }
//****************************************************************************** void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { // Make sure pins are pointing to the same SPI instance SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); SPIName spi_cntl; // Control is SCK and optionaly SS if ((SPIName)spi_ssel != (SPIName)NC) { spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); } else { spi_cntl = spi_sclk; } SPIName spi = (SPIName)pinmap_merge(spi_data, spi_cntl); MBED_ASSERT((SPIName)spi != (SPIName)NC); obj->spi = (mxc_spim_regs_t *)spi; // Merge pin function requests for use with CMSIS init func ioman_req_t io_req; pin_function_t *pin_func; pin_func = (pin_function_t *)pinmap_find_function(mosi, PinMap_SPI_MOSI); io_req.value = pin_func->req_val; pin_func = (pin_function_t *)pinmap_find_function(miso, PinMap_SPI_MISO); io_req.value |= pin_func->req_val; pin_func = (pin_function_t *)pinmap_find_function(sclk, PinMap_SPI_SCLK); io_req.value |= pin_func->req_val; if ((SPIName)spi_ssel != (SPIName)NC) { pin_func = (pin_function_t *)pinmap_find_function(ssel, PinMap_SPI_SSEL); io_req.value |= pin_func->req_val; } // Using req and ack pointers of last pin function lookup sys_cfg_spim_t sys_cfg; sys_cfg.io_cfg.req_reg = pin_func->reg_req; sys_cfg.io_cfg.ack_reg = pin_func->reg_ack; sys_cfg.io_cfg.req_val = io_req; sys_cfg.clk_scale = CLKMAN_SCALE_AUTO; // Defaults spim_cfg_t spim_cfg; spim_cfg.mode = 0; spim_cfg.ssel_pol = 0; spim_cfg.baud = 1000000; SPIM_Init(obj->spi, &spim_cfg, &sys_cfg); obj->index = MXC_SPIM_GET_IDX(obj->spi); }
uint32_t pinmap_function(PinName pin, const PinMap* map) { uint32_t function = (uint32_t)NC; if (pin == (PinName)NC) return (uint32_t)NC; function = pinmap_find_function(pin, map); if ((uint32_t)NC == function) // no mapping available error("pinmap not found for function"); return function; }
//****************************************************************************** void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) { pin_function_t rtscts_pin_func = {0}; obj->cfg.cts = 0; obj->cfg.rts = 0; if ((FlowControlCTS == type) || (FlowControlRTSCTS == type)) { UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS); UARTName uart = (UARTName)pinmap_merge(uart_cts, (UARTName)obj->uart); // Assert pin is usable with existing uart MBED_ASSERT(uart != (UARTName)NC); pin_function_t *pin_func; pin_func = (pin_function_t *)pinmap_find_function(txflow, PinMap_UART_CTS); rtscts_pin_func.req_val |= pin_func->req_val; obj->cfg.cts = 1; } if ((FlowControlRTS == type) || (FlowControlRTSCTS == type)) { UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS); UARTName uart = (UARTName)pinmap_merge(uart_rts, (UARTName)obj->uart); MBED_ASSERT(uart != (UARTName)NC); pin_function_t *pin_func; pin_func = (pin_function_t *)pinmap_find_function(rxflow, PinMap_UART_RTS); rtscts_pin_func.req_val |= pin_func->req_val; obj->cfg.rts = 1; } obj->sys_cfg.io_cfg.req_val.value |= rtscts_pin_func.req_val; int retval = UART_Init(obj->uart, &obj->cfg, &obj->sys_cfg); MBED_ASSERT(retval == E_NO_ERROR); }
//****************************************************************************** void serial_break_set(serial_t *obj) { // Make sure that nothing is being sent while (((obj->uart->tx_fifo_ctrl & MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY) >> MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY_POS) > 0); while (!(obj->uart->intfl & MXC_F_UART_INTFL_TX_DONE)); // Configure TX to output 0 usurp_pin(obj->tx, 0); // GPIO is setup now, but we need to unmap UART from the pin pin_function_t *pin_func = (pin_function_t *)pinmap_find_function(obj->tx, PinMap_UART_TX); *pin_func->reg_req &= ~MXC_F_IOMAN_UART_REQ_IO_REQ; MBED_ASSERT((*pin_func->reg_ack & MXC_F_IOMAN_UART_ACK_IO_ACK) == 0); }
void pwmout_init(pwmout_t *obj, PinName pin) { obj->channel = (PWMName) pinmap_peripheral(pin, PinMap_PWM); obj->pin = pin; MBED_ASSERT(obj->channel != (PWMName) NC); /* Turn on clock */ CMU_ClockEnable(PWM_TIMER_CLOCK, true); /* Turn on timer */ if(!(PWM_TIMER->STATUS & TIMER_STATUS_RUNNING)) { TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT; TIMER_Init(PWM_TIMER, &timerInit); } // Set route enable if(pwmout_channel_route_active(pwmout_get_channel_route(obj->channel))) { //This channel was already in use //TODO: gracefully handle this case. mbed_error? return; } else { pwmout_set_channel_route(pwmout_get_channel_route(obj->channel)); blockSleepMode(EM1); pwmout_enable(obj, true); pwmout_enable_pins(obj, true); } // Set route location #ifdef _TIMER_ROUTELOC0_CC0LOC_LOC0 switch (obj->channel) { case PWM_CH0: PWM_TIMER->ROUTELOC0 &= ~_TIMER_ROUTELOC0_CC0LOC_MASK; PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTELOC0_CC0LOC_SHIFT; break; case PWM_CH1: PWM_TIMER->ROUTELOC0 &= ~_TIMER_ROUTELOC0_CC1LOC_MASK; PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin,PinMap_PWM)<< _TIMER_ROUTELOC0_CC1LOC_SHIFT; break; case PWM_CH2: PWM_TIMER->ROUTELOC0 &= ~_TIMER_ROUTELOC0_CC2LOC_MASK; PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTELOC0_CC2LOC_SHIFT; break; case PWM_CH3: PWM_TIMER->ROUTELOC0 &= ~_TIMER_ROUTELOC0_CC3LOC_MASK; PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTELOC0_CC3LOC_SHIFT; break; default: MBED_ASSERT(false); } #else // On P1, the route location is statically defined for the entire timer. PWM_TIMER->ROUTE &= ~_TIMER_ROUTE_LOCATION_MASK; if(pwmout_all_inactive()) { PWM_TIMER->ROUTE |= pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTE_LOCATION_SHIFT; } else { MBED_ASSERT((pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTE_LOCATION_SHIFT) == (PWM_TIMER->ROUTE & _TIMER_ROUTE_LOCATION_MASK)); } #endif // Set default 20ms frequency and 0ms pulse width pwmout_period(obj, 0.02); }
void serial_pinout_tx(PinName tx) { pin_function(tx, pinmap_find_function(tx, PinMap_UART_TX)); ioport_disable_pin(tx); }
void serial_init(serial_t *obj, PinName tx, PinName rx) { /* Sanity check arguments */ MBED_ASSERT(obj); int clockid = NC, flexcom = NC; /*To determine the uart peripheral associated with pins*/ UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); MBED_ASSERT(uart != (UARTName)NC); if (g_sys_init == 0) { sysclk_init(); system_board_init(); g_sys_init = 1; } pUSART_S(obj) = uart; pSERIAL_S(obj)->uart_serial_options.baudrate = (9600UL); pSERIAL_S(obj)->uart_serial_options.charlength = US_MR_CHRL_8_BIT; pSERIAL_S(obj)->uart_serial_options.paritytype = US_MR_PAR_NO; pSERIAL_S(obj)->uart_serial_options.stopbits = US_MR_NBSTOP_1_BIT; pSERIAL_S(obj)->actrec = false; pSERIAL_S(obj)->acttra = false; /* Configure UART pins */ if(tx != NC) { pin_function(tx, pinmap_find_function(tx, PinMap_UART_TX)); ioport_disable_pin(tx); } if(rx != NC) { pin_function(rx, pinmap_find_function(rx, PinMap_UART_RX)); ioport_disable_pin(rx); } clockid = get_usart_clock_id(uart); if (clockid != NC) { sysclk_enable_peripheral_clock(clockid); } flexcom = (int)get_flexcom_id(uart); #if (!SAM4L) #if (SAMG55) /* Configure flexcom for usart */ flexcom_enable((Flexcom* )flexcom); flexcom_set_opmode((Flexcom* )flexcom, FLEXCOM_USART); #else sysclk_enable_peripheral_clock(clockid); #endif /* Configure USART */ usart_init_rs232((Usart*)uart, (sam_usart_opt_t*)&(pSERIAL_S(obj)->uart_serial_options), sysclk_get_peripheral_hz()); #endif #if (SAM4L) sysclk_enable_peripheral_clock(clockid); /* Configure USART */ usart_init_rs232((Usart*)uart, (sam_usart_opt_t*)&(pSERIAL_S(obj)->uart_serial_options, sysclk_get_peripheral_bus_hz((Usart*)uart)); #endif /* Disable rx and tx in case 1 line only required to be configured for usart */ usart_disable_tx((Usart*)uart); usart_disable_rx((Usart*)uart); /* Enable the receiver and transmitter. */ if(tx != NC) { usart_enable_tx((Usart*)uart); } if(rx != NC) { usart_enable_rx((Usart*)uart); } if(uart == STDIO_UART) { stdio_uart_inited = 1; memcpy(&stdio_uart, obj, sizeof(serial_t)); } }