debug tool for STM32F042F6P6

debug_complete.cpp

Committer:
bieleluk
Date:
2019-05-28
Revision:
27:e255eaf79cd2
Parent:
24:bc7c4e8f3fe0

File content as of revision 27:e255eaf79cd2:

#include "Debug.h"
    // definition of important constants


// create object of class Debug_led
//------------------------------------------------------------------------------------------------------------------

Debug_complete::Debug_complete(PinName tx_pin, PinName rx_pin, int baudrate) : pc(tx_pin,rx_pin, baudrate) {
    init();
}


// init function
//------------------------------------------------------------------------------------------------------------------
void Debug_complete::init() {

    pc.printf("\ec"); // erase whole window
    wait_ms(50); // wait until the erase is done
    pc.printf("serial successfully initialised\n\r\e[32;40mto start program press any button\e[97;40m");
    breakpoint_count=0; // set breakpoint count to 0
    pc.getc(); // wait for character to continue
    pc.printf("\r\e[2K\e[31;40mprogram is running\e[97;40m\r"); // continue in program
}


// perform one breakpoint
//------------------------------------------------------------------------------------------------------------------
void Debug_complete::breakpoint(int line_number) {
    breakpoint_count++;
    pc.printf("\ec"); // erase whole window
    wait_ms(50); // wait until the erase is done
    line(); // print line
    pc.printf("| Break number %d\t",breakpoint_count);
    if (line_number == -1){ // if line number was not inserted
        pc.printf("unknown line \n\r");
    }else{
        pc.printf("line %d\n\r",line_number);    
    }

    show_clk_config();
    show_adc1_config();
    show_all_timers_config();
    show_all_pins_config();
    
    pc.printf("\n\r\e[32;40mto continue press any button\e[97;40m");
    pc.getc(); // wait for character to continue
    pc.printf("\r\e[2K\e[31;40mprogram is running\e[97;40m");  // continue in program
    wait_ms(50);


}

// show configuration of one pin
//------------------------------------------------------------------------------------------------------------------
void Debug_complete::show_pin_config(pin_t pin){
    
    char portx = pin.port; // port of pin
    int pin_number = pin.number; // number of pin
    uint32_t gpio_address;
    uint32_t address_offset;
    
    // print pin port
    switch (portx){
        case 'A':
        case 'a':
            gpio_address = gpioa;
            pc.printf("| PA");
            break;
        case 'B':
        case 'b':
            gpio_address = gpiob;
            pc.printf("| PB");
            break;
        case 'f':
        case 'F':
            gpio_address = gpiof;
            pc.printf("| PF");
            break;
        default:
            pc.printf("non existing port\n\r");
            return;

    }    
    pc.printf("%d\t| ",pin_number); // print pin number

    // check the mode of pin
    address_offset = MODER_Offset;
    int return_value = check_2_bit(gpio_address,address_offset,pin_number);
    
    // check other meaningful features depending on mode of the pin
    if (return_value == 0){ //input mode
        pc.printf("input mode\t\t| ");
        // chceck pupdr register
        address_offset = PUPDR_Offset;
        return_value = check_2_bit(gpio_address,address_offset,pin_number);
        if (return_value == 0){ // pull none
            pc.printf("no resistor\t|\t\t");
        }else if (return_value == 1){ // pull up
            pc.printf("pull up\t|\t\t");
        }else if (return_value == 2){ // pull down
            pc.printf("pull down\t|\t\t");
        }else{
            pc.printf("ERROR, reserved value\n\r");
            return;            
        }
        pc.printf("| ");
        // check input value
        address_offset = IDR_Offset;
        return_value = check_1_bit(gpio_address,address_offset,pin_number);
        if (return_value == 0){  // log.0
            pc.printf("log.0");
        }else {                  // log.1
            pc.printf("log.1");
        }
        pc.printf(" |\n\r");  // go to next line       
    }else if (return_value == 1){ //output mode
        pc.printf("output mode\t\t| ");
        
        // check output mode register
        address_offset = OTYPER_Offset;
        return_value = check_1_bit(gpio_address,address_offset,pin_number);
        if (return_value == 0){        // push pull
            pc.printf("push pull\t");
        }else{                         // open drain
            pc.printf("open drain\t");
        } 
        pc.printf("| ");    
        
        // check speed of output pin
        address_offset = OSPEEDR_Offset;
        return_value = check_2_bit(gpio_address,address_offset,pin_number);
        if (return_value == 0 || return_value == 2){ // low speed
            pc.printf("low speed\t");
        }else if (return_value == 1){                // medium speed
            pc.printf("medium speed\t");
        }else{                                       // high speed
            pc.printf("high speed\t");
        }
        pc.printf("| ");    
        
        // check output value
        address_offset = ODR_Offset;
        return_value = check_1_bit(gpio_address,address_offset,pin_number);
        if (return_value == 0){   // log.0
            pc.printf("log.0");
        }else{                    // log.1
            pc.printf("log.1");
        } 
        pc.printf("\t|\n\r"); // go to next line
    }else if(return_value == 2){  // alternate mode
        pc.printf("alternate mode\t| ");
        int af_mode;
        // chceck whether the pin belongs between the lower 8 pins and use AFRL register 
        // or he pin belongs between the higher 8 pins and use AFRH register 
        if (pin_number <= 7){
            af_mode = check_alternative_mode(gpio_address,AFRL_Offset,pin_number);    
        }else{
            af_mode = check_alternative_mode(gpio_address,AFRH_Offset,pin_number - 8);    
        }  
        // print exact alternate functionality
        print_af_mode(portx, pin_number, af_mode);

    }else{   //analog mode
        pc.printf("analog mode\t\t|");
        if ((portx == 'A' || portx == 'a') && pin_number >= 0 && pin_number <= 7){
            show_analog_config(pin_number);
        }else if((portx == 'B' || portx == 'b') && pin_number == 1){
            show_analog_config(9);            
        }else{
            pc.printf("error");
            return;
        }
        
    } 
} 

// print alternate function of pin
//------------------------------------------------------------------------------------------------------------------
void Debug_complete::print_af_mode( char portx, int pin_number, int af_mode){
    if       ( (portx == 'a' || portx == 'A') && pin_number == 0 && af_mode == 1){
        pc.printf("USART2_CTS");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 0 && af_mode == 2){
        pc.printf("TIM2_CH1_ETR");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 0 && af_mode == 3){
        pc.printf("TSC_G1_IO1");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 1 && af_mode == 1){
        pc.printf("USART2_RTS");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 1 && af_mode == 2){
        pc.printf("TIM2_CH2");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 1 && af_mode == 3){
        pc.printf("TSC_G1_IO2");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 2 && af_mode == 1){
        pc.printf("USART2_TX");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 2 && af_mode == 2){
        pc.printf("TIM2_CH3");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 2 && af_mode == 3){
        pc.printf("TSC_G1_IO3");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 3 && af_mode == 1){
        pc.printf("USART2_RX");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 3 && af_mode == 2){
        pc.printf("TIM2_CH4");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 3 && af_mode == 3){
        pc.printf("TSC_G1_IO4");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 4 && af_mode == 0){
        pc.printf("SPI1_NSS, I2S1_WS");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 4 && af_mode == 1){
        pc.printf("USART2_CK");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 4 && af_mode == 2){
        pc.printf("USB_NOE");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 4 && af_mode == 3){
        pc.printf("TSC_G2_IO1");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 4 && af_mode == 4){
                show_pwm_config(14, 1);
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 5 && af_mode == 0){
        pc.printf("SPI1_SCK, I2S1_CK");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 5 && af_mode == 1){
        pc.printf("CEC");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 5 && af_mode == 2){
        pc.printf("TIM2_CH1_ETR");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 5 && af_mode == 3){
        pc.printf("TSC_G2_IO2");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 6 && af_mode == 0){
        pc.printf("SPI1_MISO, I2S1_MCK");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 6 && af_mode == 1){
                show_pwm_config(3, 1);
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 6 && af_mode == 2){
        pc.printf("TIM1_BKIN");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 6 && af_mode == 3){
        pc.printf("TSC_G2_IO3");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 6 && af_mode == 5){
        pc.printf("TIM16_CH1");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 7 && af_mode == 0){
        pc.printf("SPI1_MOSI, I2S1_SD");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 7 && af_mode == 1){
        pc.printf("TIM3_CH2");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 7 && af_mode == 2){
        show_pwm_config(1, 1);
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 7 && af_mode == 3){
        pc.printf("TSC_G2_IO4");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 7 && af_mode == 4){
        pc.printf("TIM14_CH1");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 7 && af_mode == 5){
        pc.printf("TIM17_CH1");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 9 && af_mode == 1){
        pc.printf("USART1_TX");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 9 && af_mode == 2){
        show_pwm_config(1, 2);
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 9 && af_mode == 3){
        pc.printf("TSC_G4_IO1");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 9 && af_mode == 4){
        pc.printf("I2C1_SCL");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 9 && af_mode == 5){
        pc.printf("MCO");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 10 && af_mode == 0){
        pc.printf("TIM17_BKIN");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 10 && af_mode == 1){
        pc.printf("USART1_RX");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 10 && af_mode == 2){
        show_pwm_config(1, 3);
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 10 && af_mode == 3){
        pc.printf("TSC_G4_IO2");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 10 && af_mode == 4){
        pc.printf("I2C1_SDA");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 13 && af_mode == 0){
        pc.printf("SWDIO");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 13 && af_mode == 1){
        pc.printf("IR_OUT");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 13 && af_mode == 2){
        pc.printf("USB_NOE");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 14 && af_mode == 0){
        pc.printf("SWCLK");
    }else if ( (portx == 'a' || portx == 'A') && pin_number == 14 && af_mode == 1){
        pc.printf("USART2_TX");
    }else if ( (portx == 'b' || portx == 'B') && pin_number == 1 && af_mode == 0){
        pc.printf("TIM14_CH1");
    }else if ( (portx == 'b' || portx == 'B') && pin_number == 1 && af_mode == 1){
        pc.printf("TIM3_CH4");
    }else if ( (portx == 'b' || portx == 'B') && pin_number == 1 && af_mode == 2){
        show_pwm_config(1, 3);
    }else if ( (portx == 'a' || portx == 'B') && pin_number == 1 && af_mode == 3){
        pc.printf("TSC_G3_IO3");
    }else if ( (portx == 'b' || portx == 'B') && pin_number == 8 && af_mode == 0){
        pc.printf("CEC");
    }else if ( (portx == 'b' || portx == 'B') && pin_number == 8 && af_mode == 1){
        pc.printf("I2C1_SCL");
    }else if ( (portx == 'b' || portx == 'B') && pin_number == 8 && af_mode == 2){
        show_pwm_config(16, 1);
    }else if ( (portx == 'b' || portx == 'B') && pin_number == 8 && af_mode == 3){
        pc.printf("TSC_SYNC");
    }else if ( (portx == 'a' || portx == 'B') && pin_number == 8 && af_mode == 4){
        pc.printf("CAN_RX");
    }else if ( (portx == 'f' || portx == 'F') && pin_number == 0 && af_mode == 0){
        pc.printf("CRS_SYNC");
    }else if ( (portx == 'f' || portx == 'F') && pin_number == 0 && af_mode == 1){
        pc.printf("I2C1_SDA");
    }else if ( (portx == 'f' || portx == 'F') && pin_number == 1 && af_mode == 1){
        pc.printf("I2C1_SCL");
    }else{
        pc.printf("ERROR");
    }
    pc.printf("\n\r");
}
 
// show configuration of pin in analog mode 
//------------------------------------------------------------------------------------------------------------------ 
void Debug_complete::show_analog_config(int channel){
    int config = ADC1->CHSELR; // save actual configuration of adc 
    // adc conversion on channel from parameter
    ADC1->CR|=ADC_CR_ADSTP; // stop ongoing conversion
    ADC1->CR &= !ADC_CR_ADSTART;
    ADC1->CHSELR = 1 << channel; // select channel

    ADC1->CR |= ADC_CR_ADEN; 
    while ( (ADC1->ISR & ADC_ISR_ADRDY) == 0){}
    ADC1->CR |= ADC_CR_ADSTART; // Start the ADC conversion
    while ((ADC1->ISR & ADC_ISR_EOC) == 0){} // Wait end of conversion
    
    pc.printf("\t\t|\t\t| %d\t|\n\r",ADC1->DR);
    ADC1->CHSELR = config; // restore configuratoin of adc
}

// print configuration of pin in pwm output mode
//------------------------------------------------------------------------------------------------------------------
void Debug_complete::show_pwm_config(int timer, int channel){

    pc.printf("CCR = ");
    if       (timer == 1 && channel == 1){
        pc.printf("%3d",TIM1->CCR1);
    }else if (timer == 1 && channel == 2 ){
        pc.printf("%3d",TIM1->CCR2);
    }else if (timer == 1 && channel == 3 ){
        pc.printf("%3d",TIM1->CCR3);
    }else if (timer == 3 && channel == 1){
        pc.printf("%3d",TIM3->CCR1);
    }else if (timer == 14 && channel == 1){
        pc.printf("%3d",TIM14->CCR1);
    }else if (timer == 16 && channel == 1){
        pc.printf("%3d",TIM16->CCR1);
    }
}

// print configuration of timer
//------------------------------------------------------------------------------------------------------------------
void Debug_complete::show_tim_config(int timer){
    int alignment; // alignment of PWM
    int psc; // prescaler
    int arr; // auto reload value
    if (timer == 1){
        psc = TIM1->PSC;
        arr = TIM1->ARR;
        alignment = ((TIM1->CR1&TIM_CR1_CMS)>>5);
    }else if (timer == 3){
        psc = TIM3->PSC;
        arr = TIM3->ARR;
        alignment = ((TIM3->CR1&TIM_CR1_CMS)>>5);    
    }else if (timer == 14){
        psc = TIM14->PSC;
        arr = TIM14->ARR;
        alignment = ((TIM14->CR1&TIM_CR1_CMS)>>5);
    }else if (timer == 16){
        psc = TIM16->PSC;
        arr = TIM16->ARR;
        alignment = ((TIM16->CR1&TIM_CR1_CMS)>>5);    
    }
    pc.printf("| TIM%d\t|  %3d\t\t|  %5d\t\t| ",timer,psc,arr);

    if (alignment){
        pc.printf("center mode %d\t\t|",alignment);
    }else{
        pc.printf("edge mode\t\t|");
    }

    pc.printf("\n\r");
}

// print configuration of adc1 converter
//------------------------------------------------------------------------------------------------------------------
void Debug_complete::show_adc1_config(){
    line();
    pc.printf("| \e[93;40mADC1\e[97;40m ");
    
    //configuration of adc clock
    pc.printf("Clock = ");
    switch ((ADC1->CFGR2&ADC_CFGR2_CKMODE)>>30){
        case 0:
            pc.printf("ADCCLK");
            break;
        case 1:
            pc.printf("PCLK/2");
            break;
        case 2:
            pc.printf("PCLK/4");
            break;
        case 3:
            pc.printf("Reserved");
            break;
       
    }

    // resolution of adc1
    pc.printf("\t Res = %d bits\t Smp. time = ", 12-2*((ADC1->CFGR1&ADC_CFGR1_RES)>>2));
    switch (ADC1->SMPR&ADC_SMPR_SMP){
        case 0:
            pc.printf("1.5");
            break;
        case 1:
            pc.printf("7.5");
            break;
        case 2:
            pc.printf("13.5");
            break;
        case 3:pc.printf("28.5");
            break;
        case 4:pc.printf("41.5");
            break;
        case 5:pc.printf("55.5");
            break;
        case 6:
            pc.printf("71.5");
            break;
        case 7:pc.printf("239.5");
            break;
    }
    pc.printf("clk cycles\n\r");
}

//print configuration of board's clock
//------------------------------------------------------------------------------------------------------------------
void Debug_complete::show_clk_config(){
    line();
    pc.printf("| \e[93;40mCLK\e[97;40m\t");

    // type of clock
    int clk_typede = RCC->CFGR & RCC_CFGR_SW;     
    if (clk_typede == 0 && RCC->CR&RCC_CR_HSION){ // hsi clock
        pc.printf("HSI\t");
 
    }else if (clk_typede == 1 && RCC->CR&RCC_CR_HSEON){ // hse clock
        pc.printf("HSE\t");
        if (RCC->CR & RCC_CR_HSEBYP){ // bypassed hse clock
                pc.printf(" BYPASS");
        }
        
    }else if (clk_typede == 2 && RCC->CR&RCC_CR_PLLON){ // pll clock
        pc.printf("PLL\t");
        int var = (RCC->CFGR&RCC_CFGR_PLLMUL)>>18; // multiplication factor of pll clock
        pc.printf("mul. factor = %d\t",(var<14)?(var+2):16);
        
        var = (RCC->CFGR2&RCC_CFGR2_PREDIV); // divider of pll input clock
        pc.printf("PREDIV = %d\tPLL input:",var+1);

        int pllscr = (RCC->CFGR&0x00018000)>>15; // type of pll input clock
        switch (pllscr){
            case 0:
                pc.printf(" HSI/2");
                break;
            case 1:
                pc.printf(" HSI/PREDIV");
                break;
            case 2:
                pc.printf(" HSE/PREDIV");
                break;
            case 3:
                pc.printf("HSI48/PREDIV");
                break;
        }
        pc.printf(" ");
        
    }else if (clk_typede == 3 && (RCC->CR2&RCC_CR2_HSI48ON)){ //hsi48 clock
            pc.printf("HSI48");
    }else{      // none of previous options
            pc.printf("ERROR");
    }
    pc.printf("\n\r");             
}

//print configuration of timers
//------------------------------------------------------------------------------------------------------------------
void Debug_complete::show_all_timers_config(){
    line();
    pc.printf("| \e[93;40mTIM\e[97;40m\t| Prescaler\t| Auto reload value\t| Alignment\t\t|\n\r");
    show_tim_config(1);
    show_tim_config(3);
    show_tim_config(14);
    show_tim_config(16);
}

void Debug_complete::show_all_pins_config(){
    
    pin_t pins_F042[] = { 
    {'A',0},{'A',1},{'A',2},{'A',3},{'A',4},{'A',5},{'A',6},{'A',7},
    {'A',9},{'A',10},{'A',13},{'A',14},{'B',1},{'B',8},{'F',0},{'F',1} };
    int num_of_pins = 16;
    
    line();
    pc.printf("| \e[93;40mPIN\e[97;40m\t| mode of pin\t\t| Configuration\t\t\t| value\t|\n\r");
    
    for (int i = 0; i < num_of_pins; i++ ){
        show_pin_config(pins_F042[i]);
    }
    line();
}

//print line to terminal window
//------------------------------------------------------------------------------------------------------------------
void Debug_complete::line(){
    pc.printf("-------------------------------------------------------------------------\n\r");
}