//! \brief Configures the target clock appropriately for flash programming
//!        The speed would be the maximum safe value for an untrimmed target
//!
//! @param busFrequency    - Resulting BDM frequency after clock adjustment \n
//!                          For a HCS08/CFV1 with CLKSW=1 this will be the bus frequency
//!
//! @return error code, see \ref USBDM_ErrorCode
//!
USBDM_ErrorCode FlashProgrammer::configureTargetClock(unsigned long  *busFrequency) {
   LOGGING_E;

   //! MCG parameters for flash programming 4/8 MHz
   static const MK_MCG_ClockParameters_t MCG_FlashSpeedParameters = {
         // bdm clock = reference clock * 1024/2
         /* .mcgC1   = */ 0x04, // IREFS
         /* .mcgC2   = */ 0x40, // BDIV=/2
         /* .mcgC3   = */ 0x01, // VDIV=x4 (not used)
         /* .mcgTrim = */ 0x80, // TRIM=nominal
         /* .mcgSC   = */ 0x00, // FTRIM=0
         /* .mcgCT   = */ 0x00, // DMX32=0, DRS=0
   };

   MK_MCG_ClockParameters_t   MCG_SpeedParameters   = MCG_FlashSpeedParameters;

//   Logging::print("Configuring Target clock\n");

   switch (parameters.getClockType()) {
      case CLKEXT:
      case CLKINVALID:
      default:
         return configureExternal_Clock(busFrequency);
      case MKMCGV1:
         // Program clock for approx. 8 MHz
         MCG_SpeedParameters.mcgCT = 0x01; // DRS = 1
         return configureMCG_Clock(busFrequency, &MCG_SpeedParameters);
         break;
   }
   return PROGRAMMING_RC_ERROR_ILLEGAL_PARAMS;
}
//! \brief Configures the target clock appropriately for flash programming
//!        The speed would be the maximum safe value for an untrimmed target
//!
//! @param busFrequency    - Resulting BDM frequency after clock adjustment \n
//!                          For a HCS08/CFV1 with CLKSW=1 this will be the bus frequency
//!
//! @return error code, see \ref USBDM_ErrorCode
//!
USBDM_ErrorCode FlashProgrammer::configureTargetClock(unsigned long  *busFrequency) {
   LOGGING_E;

   //! ICSCG parameters for flash programming (Maximum safe speed untrimmed 4/8MHz)
   static const ICS_ClockParameters_t ICS_FlashSpeedParameters = {
         // bdm clock = reference clock * 512/1024
         /* .icsC1   = */ 0x04, // IREFS
         /* .icsC2   = */ 0x40, // BDIV=/2
         /* .icsTrim = */ 0x80, // TRIM=nominal
         /* .icsSC   = */ 0x00, // DRS=0,DMX32=0,FTRIM=0
   };
   //! ICSCG parameters for flash programming (Maximum safe speed untrimmed 4/8MHz)
   static const ICS_ClockParameters_t ICSV4_FlashSpeedParameters = {
         // bdm clock = reference clock * 512/1024
         /* .icsC1   = */ 0x04, // IREFS
         /* .icsC2   = */ 0x20, // BDIV=/2
         /* .icsTrim = */ 0x80, // TRIM=nominal
         /* .icsSC   = */ 0x00, // DRS=0,DMX32=0,FTRIM=0
   };
   //! ICGCG parameters for flash programming
   static const ICG_ClockParameters_t ICG_FlashSpeedParameters = {
         // bdm clock = 64*MFDt*reference clock/(7*RDFt) = 64*14*refClk/(7*2*2) = 32*refClk
         /* .icgC1     = */ 0x48, // CLKS=01, RANGE=1
         /* .icgC2     = */ 0x51, // MFD=5, RFD=1
         /* .icgFilter = */ 0x00, // Not used
         /* .icgTrim   = */ 0x80, // TRIM=128
   };
   //! ICGCG parameters for flash programming 4/8 MHz
   static const MCG_ClockParameters_t MCG_FlashSpeedParameters = {
         // bdm clock = reference clock * 1024/2
         /* .mcgC1   = */ 0x04, // IREFS
         /* .mcgC2   = */ 0x40, // BDIV=/2
         /* .mcgC3   = */ 0x01, // VDIV=x4 (not used)
         /* .mcgTrim = */ 0x80, // TRIM=nominal
         /* .mcgSC   = */ 0x00, // FTRIM=0
         /* .mcgCT   = */ 0x00, // DMX32=0, DRS=0
   };

   ICS_ClockParameters_t   ICS_SpeedParameters   = ICS_FlashSpeedParameters;
   ICS_ClockParameters_t   ICSV4_SpeedParameters = ICSV4_FlashSpeedParameters;
   ICG_ClockParameters_t   ICG_SpeedParameters   = ICG_FlashSpeedParameters;
   MCG_ClockParameters_t   MCG_SpeedParameters   = MCG_FlashSpeedParameters;

//   Logging::print("Configuring Target clock\n");

   switch (parameters.getClockType()) {
      case CLKEXT:
      case CLKINVALID:
         return configureExternal_Clock(busFrequency);
      case S08ICGV1:
      case S08ICGV2:
      case S08ICGV3:
      case S08ICGV4:
         // Program clock for approx. 8 MHz
         return configureICG_Clock(busFrequency, &ICG_SpeedParameters);
      case S08ICSV1:
      case S08ICSV2:
      case S08ICSV2x512:
      case S08ICSV3:
      case RS08ICSV1:
      case RS08ICSOSCV1:
         // Program clock for approx. 4/8 MHz
         return configureICS_Clock(busFrequency, &ICS_SpeedParameters);
      case S08ICSV4:
         // Program clock for approx. 4/8 MHz
         return configureICS_Clock(busFrequency, &ICSV4_SpeedParameters);
      case S08MCGV1:
      case S08MCGV3:
         // Program clock for approx. 4/8 MHz
         return configureMCG_Clock(busFrequency, &MCG_SpeedParameters);
         break;
      case S08MCGV2:
         // Program clock for approx. 8 MHz
         MCG_SpeedParameters.mcgCT = 0x01; // DRS = 1
         return configureMCG_Clock(busFrequency, &MCG_SpeedParameters);
         break;
   }
   return PROGRAMMING_RC_ERROR_ILLEGAL_PARAMS;
}