Ignore:
Timestamp:
Jan 13, 2025, 11:56:09 AM (2 days ago)
Author:
Zed
Message:

GSM thread was added.

Location:
ctrl/firmware/Main/CubeMX
Files:
6 added
6 edited

Legend:

Unmodified
Added
Removed
  • ctrl/firmware/Main/CubeMX/Core/Inc/main.h

    r58 r61  
    7878#define RST_DISPLAY_Pin GPIO_PIN_15
    7979#define RST_DISPLAY_GPIO_Port GPIOE
     80#define GSM_PWR_Pin GPIO_PIN_10
     81#define GSM_PWR_GPIO_Port GPIOD
    8082#define SD_DETECT_Pin GPIO_PIN_8
    8183#define SD_DETECT_GPIO_Port GPIOA
     
    9294#define TX2_LED_Pin GPIO_PIN_13
    9395#define TX2_LED_GPIO_Port GPIOG
     96#define BUZZER_Pin GPIO_PIN_15
     97#define BUZZER_GPIO_Port GPIOG
    9498
    9599/* USER CODE BEGIN Private defines */
  • ctrl/firmware/Main/CubeMX/Core/Inc/stm32h7xx_hal_conf.h

    r54 r61  
    7676/* #define HAL_SWPMI_MODULE_ENABLED   */
    7777#define HAL_TIM_MODULE_ENABLED
    78 /* #define HAL_UART_MODULE_ENABLED   */
     78#define HAL_UART_MODULE_ENABLED
    7979/* #define HAL_USART_MODULE_ENABLED   */
    8080/* #define HAL_IRDA_MODULE_ENABLED   */
  • ctrl/firmware/Main/CubeMX/Core/Src/app_threadx.c

    r58 r61  
    2929
    3030#include "keys_thread.h"
     31#include "gsm_thread.h"
    3132
    3233/* USER CODE END Includes */
     
    4041/* USER CODE BEGIN PD */
    4142
    42 #define MAIN_THREAD_STACK_SIZE_BYTES    (1024U)
     43#define KEYS_THREAD_STACK_SIZE_BYTES    (1024U)
     44#define GSM_THREAD_STACK_SIZE_BYTES             (1024U)
    4345
    4446/* USER CODE END PD */
     
    5355
    5456TX_THREAD scan_keys_thread_ptr;
     57TX_THREAD gsm_thread_ptr;
    5558
    5659/* USER CODE END PV */
     
    7275
    7376  TX_BYTE_POOL *byte_pool = (TX_BYTE_POOL*)memory_ptr;
    74   VOID *pointer;
     77  VOID *keys_thread_pointer;
     78  VOID *gsm_thread_pointer;
    7579
    7680  /* USER CODE END App_ThreadX_MEM_POOL */
     
    7983
    8084  // Allocate the stack for main thread
    81   ret = tx_byte_allocate(byte_pool, &pointer, MAIN_THREAD_STACK_SIZE_BYTES,
    82                                                  TX_NO_WAIT);
     85  ret = tx_byte_allocate(byte_pool, &keys_thread_pointer, KEYS_THREAD_STACK_SIZE_BYTES, TX_NO_WAIT);
    8386  if (ret != TX_SUCCESS) { printf("Cannot allocate bytes of memory!\n"); return ret; }
    8487
    85   ret = tx_thread_create(&scan_keys_thread_ptr, "Scan Keys Thread", scanKeysThread, 0x0001,
    86                                                 pointer, MAIN_THREAD_STACK_SIZE_BYTES, TX_MAX_PRIORITIES-1, TX_MAX_PRIORITIES-1,
    87                                                 TX_NO_TIME_SLICE, TX_AUTO_START);
    88   if (ret != TX_SUCCESS) { printf("Cannot create Scan Keys Thread!\n"); return ret; }
     88  char* scan_keys_thread_name = "Scan Keys Thread";
     89  ret = tx_thread_create(&scan_keys_thread_ptr, scan_keys_thread_name, scanKeysThread, 0x0001,  keys_thread_pointer, KEYS_THREAD_STACK_SIZE_BYTES, TX_MAX_PRIORITIES-1, TX_MAX_PRIORITIES-1, TX_NO_TIME_SLICE, TX_AUTO_START);
     90  if (ret != TX_SUCCESS) { printf("Cannot create %s!\n", scan_keys_thread_name); return ret; }
     91
     92
     93
     94  ret = tx_byte_allocate(byte_pool, &gsm_thread_pointer, GSM_THREAD_STACK_SIZE_BYTES, TX_NO_WAIT);
     95  if (ret != TX_SUCCESS) { printf("Cannot allocate bytes of memory!\n"); return ret; }
     96
     97  char* gsm_thread_name = "GSM Thread";
     98  ret = tx_thread_create(&gsm_thread_ptr, gsm_thread_name, gsmThread, 0x0001,   gsm_thread_pointer, GSM_THREAD_STACK_SIZE_BYTES, TX_MAX_PRIORITIES-1, TX_MAX_PRIORITIES-1, TX_NO_TIME_SLICE, TX_AUTO_START);
     99  if (ret != TX_SUCCESS) { printf("Cannot create %s!\n", gsm_thread_name); return ret; }
     100
     101
    89102
    90103  /* USER CODE END App_ThreadX_Init */
  • ctrl/firmware/Main/CubeMX/Core/Src/gpio.c

    r59 r61  
    6565  /*Configure GPIO pin Output Level */
    6666  HAL_GPIO_WritePin(GPIOG, POWER_5V_EN_Pin|POWER_10V_EN_Pin|ERROR_LED_Pin|CHARGE_LED_Pin
    67                           |RX2_LED_Pin|RX1_LED_Pin|TX2_LED_Pin, GPIO_PIN_RESET);
     67                          |RX2_LED_Pin|RX1_LED_Pin|TX2_LED_Pin|BUZZER_Pin, GPIO_PIN_RESET);
    6868
    6969  /*Configure GPIO pin Output Level */
    70   HAL_GPIO_WritePin(OUTPUT_ON_LED_GPIO_Port, OUTPUT_ON_LED_Pin, GPIO_PIN_RESET);
     70  HAL_GPIO_WritePin(GPIOD, GSM_PWR_Pin|OUTPUT_ON_LED_Pin, GPIO_PIN_RESET);
    7171
    7272  /*Configure GPIO pins : PE2 PE3 PE4 PE5
     
    141141
    142142  /*Configure GPIO pins : POWER_5V_EN_Pin POWER_10V_EN_Pin ERROR_LED_Pin CHARGE_LED_Pin
    143                            RX2_LED_Pin RX1_LED_Pin TX2_LED_Pin */
     143                           RX2_LED_Pin RX1_LED_Pin TX2_LED_Pin BUZZER_Pin */
    144144  GPIO_InitStruct.Pin = POWER_5V_EN_Pin|POWER_10V_EN_Pin|ERROR_LED_Pin|CHARGE_LED_Pin
    145                           |RX2_LED_Pin|RX1_LED_Pin|TX2_LED_Pin;
     145                          |RX2_LED_Pin|RX1_LED_Pin|TX2_LED_Pin|BUZZER_Pin;
    146146  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    147147  GPIO_InitStruct.Pull = GPIO_NOPULL;
     
    149149  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
    150150
    151   /*Configure GPIO pins : PD8 PD9 PD10 PD11
    152                            PD12 PD13 PD14 PD15
    153                            PD0 PD1 PD3 PD4
    154                            PD5 PD6 */
    155   GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
    156                           |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15
    157                           |GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_3|GPIO_PIN_4
    158                           |GPIO_PIN_5|GPIO_PIN_6;
     151  /*Configure GPIO pins : GSM_PWR_Pin OUTPUT_ON_LED_Pin */
     152  GPIO_InitStruct.Pin = GSM_PWR_Pin|OUTPUT_ON_LED_Pin;
     153  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     154  GPIO_InitStruct.Pull = GPIO_NOPULL;
     155  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     156  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
     157
     158  /*Configure GPIO pins : PD11 PD12 PD13 PD14
     159                           PD15 PD0 PD1 PD3
     160                           PD4 PD5 PD6 */
     161  GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
     162                          |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_3
     163                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
    159164  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    160165  GPIO_InitStruct.Pull = GPIO_NOPULL;
     
    162167
    163168  /*Configure GPIO pins : PG2 PG3 PG4 PG5
    164                            PG6 PG7 PG8 PG14
    165                            PG15 */
     169                           PG6 PG7 PG8 PG14 */
    166170  GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5
    167                           |GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_14
    168                           |GPIO_PIN_15;
     171                          |GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_14;
    169172  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    170173  GPIO_InitStruct.Pull = GPIO_NOPULL;
     
    177180  HAL_GPIO_Init(SD_DETECT_GPIO_Port, &GPIO_InitStruct);
    178181
    179   /*Configure GPIO pin : OUTPUT_ON_LED_Pin */
    180   GPIO_InitStruct.Pin = OUTPUT_ON_LED_Pin;
    181   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    182   GPIO_InitStruct.Pull = GPIO_NOPULL;
    183   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    184   HAL_GPIO_Init(OUTPUT_ON_LED_GPIO_Port, &GPIO_InitStruct);
    185 
    186182}
    187183
  • ctrl/firmware/Main/CubeMX/Core/Src/main.c

    r59 r61  
    2525#include "sdmmc.h"
    2626#include "spi.h"
     27#include "usart.h"
    2728#include "gpio.h"
    2829
     
    109110
    110111  /* USER CODE BEGIN SysInit */
    111 
     112#define MX_SDMMC1_SD_Init DoNothing
    112113  /* USER CODE END SysInit */
    113 #define MX_SDMMC1_SD_Init DoNothing
     114
    114115  /* Initialize all configured peripherals */
    115116  MX_GPIO_Init();
     
    118119  MX_SPI4_Init();
    119120  MX_SDMMC1_SD_Init();
     121  MX_USART3_UART_Init();
    120122  /* USER CODE BEGIN 2 */
    121123#undef MX_SDMMC1_SD_Init
  • ctrl/firmware/Main/CubeMX/charger.ioc

    r59 r61  
    3636Mcu.IP0=CORTEX_M7
    3737Mcu.IP1=DEBUG
     38Mcu.IP10=USART3
    3839Mcu.IP2=DMA
    3940Mcu.IP3=MEMORYMAP
     
    4445Mcu.IP8=SPI4
    4546Mcu.IP9=SYS
    46 Mcu.IPNb=10
     47Mcu.IPNb=11
    4748Mcu.Name=STM32H723ZETx
    4849Mcu.Package=LQFP144
     
    5354Mcu.Pin12=PE14
    5455Mcu.Pin13=PE15
    55 Mcu.Pin14=PC8
    56 Mcu.Pin15=PC9
    57 Mcu.Pin16=PA8
    58 Mcu.Pin17=PA13(JTMS/SWDIO)
    59 Mcu.Pin18=PA14(JTCK/SWCLK)
    60 Mcu.Pin19=PC10
     56Mcu.Pin14=PD8
     57Mcu.Pin15=PD9
     58Mcu.Pin16=PD10
     59Mcu.Pin17=PC8
     60Mcu.Pin18=PC9
     61Mcu.Pin19=PA8
    6162Mcu.Pin2=PC15-OSC32_OUT
    62 Mcu.Pin20=PC11
    63 Mcu.Pin21=PC12
    64 Mcu.Pin22=PD2
    65 Mcu.Pin23=PD7
    66 Mcu.Pin24=PG9
    67 Mcu.Pin25=PG10
    68 Mcu.Pin26=PG11
    69 Mcu.Pin27=PG12
    70 Mcu.Pin28=PG13
    71 Mcu.Pin29=VP_RTC_VS_RTC_Activate
     63Mcu.Pin20=PA13(JTMS/SWDIO)
     64Mcu.Pin21=PA14(JTCK/SWCLK)
     65Mcu.Pin22=PC10
     66Mcu.Pin23=PC11
     67Mcu.Pin24=PC12
     68Mcu.Pin25=PD2
     69Mcu.Pin26=PD7
     70Mcu.Pin27=PG9
     71Mcu.Pin28=PG10
     72Mcu.Pin29=PG11
    7273Mcu.Pin3=PH0-OSC_IN
    73 Mcu.Pin30=VP_SYS_VS_tim7
    74 Mcu.Pin31=VP_MEMORYMAP_VS_MEMORYMAP
    75 Mcu.Pin32=VP_STMicroelectronics.X-CUBE-AZRTOS-H7_VS_RTOSJjThreadX_6.4.0_3.3.0
    76 Mcu.Pin33=VP_STMicroelectronics.X-CUBE-AZRTOS-H7_VS_FileOoSystemJjFileX_6.4.0_3.3.0
    77 Mcu.Pin34=VP_STMicroelectronics.X-CUBE-AZRTOS-H7_VS_FileOoSystemJjInterfaces_3.3.0_3.3.0
     74Mcu.Pin30=PG12
     75Mcu.Pin31=PG13
     76Mcu.Pin32=PG15
     77Mcu.Pin33=VP_RTC_VS_RTC_Activate
     78Mcu.Pin34=VP_SYS_VS_tim7
     79Mcu.Pin35=VP_MEMORYMAP_VS_MEMORYMAP
     80Mcu.Pin36=VP_STMicroelectronics.X-CUBE-AZRTOS-H7_VS_RTOSJjThreadX_6.4.0_3.3.0
     81Mcu.Pin37=VP_STMicroelectronics.X-CUBE-AZRTOS-H7_VS_FileOoSystemJjFileX_6.4.0_3.3.0
     82Mcu.Pin38=VP_STMicroelectronics.X-CUBE-AZRTOS-H7_VS_FileOoSystemJjInterfaces_3.3.0_3.3.0
    7883Mcu.Pin4=PH1-OSC_OUT
    7984Mcu.Pin5=PF15
     
    8287Mcu.Pin8=PE7
    8388Mcu.Pin9=PE11
    84 Mcu.PinsNb=35
     89Mcu.PinsNb=39
    8590Mcu.ThirdParty0=STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0
    8691Mcu.ThirdPartyNb=1
     
    133138PC9.Mode=SD_4_bits_Wide_bus
    134139PC9.Signal=SDMMC1_D1
     140PD10.GPIOParameters=GPIO_Label
     141PD10.GPIO_Label=GSM_PWR
     142PD10.Locked=true
     143PD10.Signal=GPIO_Output
    135144PD2.Mode=SD_4_bits_Wide_bus
    136145PD2.Signal=SDMMC1_CMD
     
    139148PD7.Locked=true
    140149PD7.Signal=GPIO_Output
     150PD8.Locked=true
     151PD8.Mode=Asynchronous
     152PD8.Signal=USART3_TX
     153PD9.Locked=true
     154PD9.Mode=Asynchronous
     155PD9.Signal=USART3_RX
    141156PE11.GPIOParameters=GPIO_Label
    142157PE11.GPIO_Label=SPI4_NSS_DISPLAY
     
    199214PG13.Locked=true
    200215PG13.Signal=GPIO_Output
     216PG15.GPIOParameters=GPIO_Label
     217PG15.GPIO_Label=BUZZER
     218PG15.Locked=true
     219PG15.Signal=GPIO_Output
    201220PG9.GPIOParameters=GPIO_Label
    202221PG9.GPIO_Label=ERROR_LED
     
    256275RCC.DIVM1=5
    257276RCC.DIVM2=3
    258 RCC.DIVM3=1
     277RCC.DIVM3=25
    259278RCC.DIVN1=40
    260279RCC.DIVN2=40
    261 RCC.DIVN3=4
     280RCC.DIVN3=200
    262281RCC.DIVP1Freq_Value=100000000
    263282RCC.DIVP2Freq_Value=166666666.66666666
    264 RCC.DIVP3Freq_Value=50000000
     283RCC.DIVP3Freq_Value=100000000
    265284RCC.DIVQ1=4
    266285RCC.DIVQ1Freq_Value=50000000
    267286RCC.DIVQ2=11
    268287RCC.DIVQ2Freq_Value=30303030.3030303
    269 RCC.DIVQ3Freq_Value=50000000
     288RCC.DIVQ3=8
     289RCC.DIVQ3Freq_Value=25000000
    270290RCC.DIVR1Freq_Value=100000000
    271291RCC.DIVR2=10
    272292RCC.DIVR2Freq_Value=33333333.333333332
    273 RCC.DIVR3Freq_Value=50000000
     293RCC.DIVR3Freq_Value=100000000
    274294RCC.FDCANFreq_Value=50000000
    275295RCC.FMCFreq_Value=100000000
     
    279299RCC.I2C123Freq_Value=100000000
    280300RCC.I2C4Freq_Value=100000000
    281 RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM2,DIVM3,DIVN1,DIVN2,DIVN3,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLLFRACN,PLLSourceVirtual,QSPIFreq_Value,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Spi45ClockSelection,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
     301RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM2,DIVM3,DIVN1,DIVN2,DIVN3,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2,DIVQ2Freq_Value,DIVQ3,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLLFRACN,PLLSourceVirtual,QSPIFreq_Value,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Spi45ClockSelection,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578CLockSelection,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
    282302RCC.LPTIM1Freq_Value=100000000
    283303RCC.LPTIM2Freq_Value=100000000
    284304RCC.LPTIM345Freq_Value=100000000
    285305RCC.LPUART1Freq_Value=100000000
    286 RCC.LTDCFreq_Value=50000000
     306RCC.LTDCFreq_Value=100000000
    287307RCC.MCO1PinFreq_Value=64000000
    288308RCC.MCO2PinFreq_Value=100000000
     
    310330RCC.TraceFreq_Value=100000000
    311331RCC.USART16Freq_Value=100000000
    312 RCC.USART234578Freq_Value=100000000
     332RCC.USART234578CLockSelection=RCC_USART234578CLKSOURCE_PLL3
     333RCC.USART234578Freq_Value=25000000
    313334RCC.USBFreq_Value=50000000
    314335RCC.VCO1OutputFreq_Value=200000000
    315336RCC.VCO2OutputFreq_Value=333333333.3333333
    316 RCC.VCO3OutputFreq_Value=100000000
     337RCC.VCO3OutputFreq_Value=200000000
    317338RCC.VCOInput1Freq_Value=5000000
    318339RCC.VCOInput2Freq_Value=8333333.333333333
    319 RCC.VCOInput3Freq_Value=25000000
     340RCC.VCOInput3Freq_Value=1000000
    320341SDMMC1.ClockPowerSave=SDMMC_CLOCK_POWER_SAVE_ENABLE
    321342SDMMC1.HardwareFlowControl=SDMMC_HARDWARE_FLOW_CONTROL_ENABLE
     
    352373STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0_IsAnAzureRtosMw=true
    353374STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0_SwParameter=InterfacesCcFileOoSystemJjFileXOoSDOointerface\:true;ThreadXCcRTOSJjThreadXJjLowOoPowerOosupport\:true;FileXCcFileOoSystemJjFileXJjCore\:true;ThreadXCcRTOSJjThreadXJjCore\:true;
     375USART3.IPParameters=VirtualMode-Asynchronous
     376USART3.VirtualMode-Asynchronous=VM_ASYNC
    354377VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg
    355378VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP
Note: See TracChangeset for help on using the changeset viewer.