2018-01-24 16:36:19 +01:00
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*
*/
/** BusVoodoo UART mode (code)
* @ file busvoodoo_uart . c
* @ author King Kévin < kingkevin @ cuvoodoo . info >
* @ date 2018
* @ note peripherals used : USART @ ref busvoodoo_uart
*/
/* standard libraries */
# include <stdint.h> // standard integer types
# include <stdlib.h> // standard utilities
# include <string.h> // string utilities
/* STM32 (including CM3) libraries */
2018-07-13 18:31:39 +02:00
# include <libopencm3/cm3/nvic.h> // interrupt definitions
2018-01-24 16:36:19 +01:00
# include <libopencm3/stm32/gpio.h> // general purpose input output library
# include <libopencm3/stm32/rcc.h> // real-time control clock library
# include <libopencm3/stm32/usart.h> // USART utilities
/* own libraries */
# include "global.h" // board definitions
# include "print.h" // printing utilities
# include "menu.h" // menu definitions
2018-06-14 13:21:16 +02:00
# include "usart_enhanced.h" // utilities for USART enhancements
2018-01-24 16:36:19 +01:00
# include "busvoodoo_global.h" // BusVoodoo definitions
2018-02-06 12:33:00 +01:00
# include "busvoodoo_oled.h" // OLED utilities
2018-06-15 09:48:41 +02:00
# include "busvoodoo_uart_generic.h" // generic UART mode
2018-01-24 16:36:19 +01:00
# include "busvoodoo_uart.h" // own definitions
/** @defgroup busvoodoo_uart USART peripheral used for UART communication
* @ {
*/
2018-06-16 21:09:23 +02:00
# define BUSVOODOO_UART_USART 3 /**< USART peripheral */
2018-01-24 16:36:19 +01:00
/** @} */
2018-07-13 18:31:39 +02:00
# define BUSVOODOO_UART_RX_TIMER 2 /**< timer ID to capture RX edges */
# define BUSVOODOO_UART_RX_CHANNEL 4 /**< channel ID used as input capture to capture RX edges */
2018-06-15 09:48:41 +02:00
/** UART specific methods that will be called by the generic methods */
static const struct busvoodoo_uart_generic_specific_t busvoodoo_uart_generic_uart = {
2018-06-16 21:09:23 +02:00
. usart = USART ( BUSVOODOO_UART_USART ) ,
. usart_rcc = RCC_USART ( BUSVOODOO_UART_USART ) ,
. usart_rst = RST_USART ( BUSVOODOO_UART_USART ) ,
2018-06-15 09:48:41 +02:00
. multidrive = true ,
2018-06-16 21:09:23 +02:00
. tx_port = USART_TX_PORT ( BUSVOODOO_UART_USART ) ,
. tx_pin = USART_TX_PIN ( BUSVOODOO_UART_USART ) ,
. tx_rcc = RCC_USART_PORT ( BUSVOODOO_UART_USART ) ,
2018-06-15 09:48:41 +02:00
. tx_pre = NULL ,
. tx_post = NULL ,
2018-06-16 21:09:23 +02:00
. rx_port = USART_RX_PORT ( BUSVOODOO_UART_USART ) ,
. rx_pin = USART_RX_PIN ( BUSVOODOO_UART_USART ) ,
. rx_rcc = RCC_USART_PORT ( BUSVOODOO_UART_USART ) ,
2018-06-15 09:48:41 +02:00
. rx_pre = NULL ,
. rx_post = NULL ,
. hwflowctl = true ,
2018-06-16 21:09:23 +02:00
. rts_port = USART_RTS_PORT ( BUSVOODOO_UART_USART ) ,
. rts_pin = USART_RTS_PIN ( BUSVOODOO_UART_USART ) ,
. rts_rcc = RCC_USART_PORT ( BUSVOODOO_UART_USART ) ,
. cts_port = USART_CTS_PORT ( BUSVOODOO_UART_USART ) ,
. cts_pin = USART_CTS_PIN ( BUSVOODOO_UART_USART ) ,
. cts_rcc = RCC_USART_PORT ( BUSVOODOO_UART_USART ) ,
2018-07-13 18:31:39 +02:00
. timer = TIM ( BUSVOODOO_UART_RX_TIMER ) ,
. timer_rcc = RCC_TIM ( BUSVOODOO_UART_RX_TIMER ) ,
. timer_port = TIM_CH_PORT ( BUSVOODOO_UART_RX_TIMER , BUSVOODOO_UART_RX_CHANNEL ) ,
. timer_port_rcc = RCC_TIM_CH ( BUSVOODOO_UART_RX_TIMER , BUSVOODOO_UART_RX_CHANNEL ) ,
. timer_pin = TIM_CH_PIN ( BUSVOODOO_UART_RX_TIMER , BUSVOODOO_UART_RX_CHANNEL ) ,
. timer_ic = TIM_IC ( BUSVOODOO_UART_RX_CHANNEL ) ,
. timer_ic_in_ti = TIM_IC_IN_TI ( BUSVOODOO_UART_RX_CHANNEL ) ,
. timer_sr_ccif = TIM_SR_CCIF ( BUSVOODOO_UART_RX_CHANNEL ) ,
. timer_sr_ccof = TIM_SR_CCOF ( BUSVOODOO_UART_RX_CHANNEL ) ,
. timer_ccr = & TIM_CCR ( BUSVOODOO_UART_RX_TIMER , BUSVOODOO_UART_RX_CHANNEL ) ,
. timer_dier_ccie = TIM_DIER_CCIE ( BUSVOODOO_UART_RX_CHANNEL ) ,
. timer_nvic_irq = NVIC_TIM_IRQ ( BUSVOODOO_UART_RX_TIMER ) ,
2018-06-15 09:48:41 +02:00
} ;
2018-01-24 16:36:19 +01:00
/** setup UART mode
* @ param [ out ] prefix terminal prompt prefix
* @ param [ in ] line terminal prompt line to configure mode
* @ return if setup is complete
*/
static bool busvoodoo_uart_setup ( char * * prefix , const char * line )
{
bool complete = false ; // is the setup complete
if ( NULL = = line ) { // first call
2018-06-15 09:48:41 +02:00
busvoodoo_uart_generic_configure ( & busvoodoo_uart_generic_uart ) ; // provide the UART specific information
2018-01-24 16:36:19 +01:00
}
2018-06-15 09:48:41 +02:00
complete = busvoodoo_uart_generic_setup ( prefix , line ) ; // configure underlying generic UART
if ( complete ) { // generic configuration finished
busvoodoo_led_blue_off ( ) ; // disable blue LED because there is no activity
2018-07-13 18:31:39 +02:00
gpio_primary_remap ( AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON , AFIO_MAPR_TIM2_REMAP_PARTIAL_REMAP2 ) ; // remap timer 2 channel 4 to RX to be able to measure the edge timing
2018-06-15 09:48:41 +02:00
* prefix = " UART " ; // display mode
busvoodoo_oled_text_left ( * prefix ) ; // set mode title on OLED display
const char * pinout_io [ 10 ] = { " GND " , " 5V " , " 3V3 " , " LV " , " Rx " , " Tx " , " RTS " , " CTS " , NULL , NULL } ; // UART mode pinout
for ( uint8_t i = 0 ; i < LENGTH ( pinout_io ) & & i < LENGTH ( busvoodoo_global_pinout_io ) ; i + + ) {
busvoodoo_global_pinout_io [ i ] = pinout_io [ i ] ; // set pin names
}
if ( busvoodoo_full ) {
const char * pinout_rscan [ 5 ] = { " HV " , NULL , NULL , NULL , NULL } ; // HiZ mode RS/CAN pinout
for ( uint8_t i = 0 ; i < LENGTH ( pinout_rscan ) & & i < LENGTH ( busvoodoo_global_pinout_rscan ) ; i + + ) {
busvoodoo_global_pinout_rscan [ i ] = pinout_rscan [ i ] ; // set pin names
2018-01-24 16:36:19 +01:00
}
2018-06-15 09:48:41 +02:00
}
busvoodoo_oled_text_pinout ( ( const char * * ) pinout_io , true ) ; // set pinout on display
busvoodoo_oled_update ( ) ; // update display to show text and pinout
2018-01-24 16:36:19 +01:00
}
return complete ;
}
/** exit UART mode
*/
static void busvoodoo_uart_exit ( void )
{
2018-06-15 09:48:41 +02:00
busvoodoo_uart_generic_exit ( ) ; // exiting the underlying generic UART does everything we need
2018-07-13 18:31:39 +02:00
// disable timer 2 remapping set during configuration
uint32_t remap = AFIO_MAPR ; // get the remap setting
remap & = ~ AFIO_MAPR_SWJ_MASK ; // mask the SWJ setting since they are read only
remap & = ~ AFIO_MAPR_TIM2_REMAP_FULL_REMAP ; // clear the timer 2 remap
gpio_primary_remap ( AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON , remap ) ; // disable timer 2 remapping set during configuration
2018-03-22 15:57:49 +01:00
}
2018-04-04 17:14:36 +02:00
const struct busvoodoo_mode_t busvoodoo_uart_mode = {
. name = " uart " ,
. description = " Universal Asynchronous Receiver-Transmitter " ,
. full_only = false ,
. setup = & busvoodoo_uart_setup ,
2018-06-15 09:48:41 +02:00
. commands = busvoodoo_uart_generic_commands ,
. commands_nb = busvoodoo_uart_generic_commands_nb ,
2018-04-04 17:14:36 +02:00
. exit = & busvoodoo_uart_exit ,
2018-01-24 16:36:19 +01:00
} ;