// Automatically generated C++ file on Sat Dec 21 23:08:40 2024 // // To build with Digital Mars C++ Compiler: // // dmc -mn -WD cot_pwm_1.cpp kernel32.lib union uData { bool b; char c; unsigned char uc; short s; unsigned short us; int i; unsigned int ui; float f; double d; long long int i64; unsigned long long int ui64; char *str; unsigned char *bytes; }; // int DllMain() must exist and return 1 for a process to load the .DLL // See https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain for more information. int __stdcall DllMain(void *module, unsigned int reason, void *reserved) { return 1; } // #undef pin names lest they collide with names in any header file(s) you might include. #undef set #undef pwm1 #undef pwm2 #undef pwm3 #undef pwm4 #undef pwm5 #undef pwm6 #undef pwm7 #undef pwm8 #undef pwm9 #undef pwm10 #undef pwm11 #undef pwm12 #undef pwm13 #undef pwm14 #undef pwm15 #undef pwm16 extern "C" __declspec(dllexport) void cot_pwm_4(void **opaque, double t, union uData *data) { bool set = data[0].b; // Input: set signal bool &pwm1 = data[1].b; // Output: pwm1 bool &pwm2 = data[2].b; // Output: pwm2 bool &pwm3 = data[3].b; // Output: pwm3 bool &pwm4 = data[4].b; // Output: pwm4 bool &pwm5 = data[5].b; // Output: pwm5 bool &pwm6 = data[6].b; // Output: pwm6 bool &pwm7 = data[7].b; // Output: pwm7 bool &pwm8 = data[8].b; // Output: pwm8 bool &pwm9 = data[9].b; // Output: pwm9 bool &pwm10 = data[10].b; // Output: pwm10 bool &pwm11 = data[11].b; // Output: pwm11 bool &pwm12 = data[12].b; // Output: pwm12 bool &pwm13 = data[13].b; // Output: pwm13 bool &pwm14 = data[14].b; // Output: pwm14 bool &pwm15 = data[15].b; // Output: pwm15 bool &pwm16 = data[16].b; // Output: pwm16 static bool previous_set = false; // To detect rising edge static int pwm_counter = -1; // To keep track of which PWM to activate; Start from -1 so the first rising edge triggers pwm1 static double pwm_time[16] = {0}; // Store the time when each PWM "should" turn off static double pwm_on_time[16] = {0}; // Store the time when each PWM turns on static double pwm_off_time[16] = {0}; // Store the time when each PWM turns off static bool first_round_completed = false; // To track if the first round of PWM activations is done const double Vin = 12.0; // Input voltage const double Vout = 1.2; // Output voltage const double fsw = 600e+3; // Switching period const double mini_on_time = 50e-9; // Minimum on time: 50 ns const double mini_off_time = 200e-9; // Minimum off time: 200 ns // Calculate OnTime_COT based on the formula double OnTime_COT = (Vout / Vin) * 1 / fsw; // Time for each PWM to stay high // If OnTime_COT is less than mini_on_time, set it to mini_on_time if (OnTime_COT < mini_on_time) { OnTime_COT = mini_on_time; } // Detect rising edge of the 'set' signal if (!previous_set && set) { // Rising edge detected, activate the next PWM pwm_counter = (pwm_counter + 1) % 16; // Cycle through PWM1 to PWM16 // Check if it's the first round (PWM1 to PWM16) if (!first_round_completed) { // Set the current PWM pin high without mini_off_time constraint switch (pwm_counter) { case 0: pwm1 = true; break; case 1: pwm2 = true; break; case 2: pwm3 = true; break; case 3: pwm4 = true; break; case 4: pwm5 = true; break; case 5: pwm6 = true; break; case 6: pwm7 = true; break; case 7: pwm8 = true; break; case 8: pwm9 = true; break; case 9: pwm10 = true; break; case 10: pwm11 = true; break; case 11: pwm12 = true; break; case 12: pwm13 = true; break; case 13: pwm14 = true; break; case 14: pwm15 = true; break; case 15: pwm16 = true; break; } // Set the time when this PWM should be pulled low // The first PWM pin (pwm1) should have mini_on_time, not OnTime_COT if (pwm_counter == 0) { pwm_time[pwm_counter] = t + mini_on_time; // Use mini_on_time for pwm1 } else { pwm_time[pwm_counter] = t + OnTime_COT; // Use OnTime_COT for other PWM pins } pwm_on_time[pwm_counter] = t; // Store the time when the PWM turned on // After completing PWM16, mark the first round as complete if (pwm_counter == 15) { first_round_completed = true; } } else { // Apply mini_off_time constraint for all PWM pins after the first round if (t - pwm_off_time[pwm_counter] >= mini_off_time) { // Set the current PWM pin high switch (pwm_counter) { case 0: pwm1 = true; break; case 1: pwm2 = true; break; case 2: pwm3 = true; break; case 3: pwm4 = true; break; case 4: pwm5 = true; break; case 5: pwm6 = true; break; case 6: pwm7 = true; break; case 7: pwm8 = true; break; case 8: pwm9 = true; break; case 9: pwm10 = true; break; case 10: pwm11 = true; break; case 11: pwm12 = true; break; case 12: pwm13 = true; break; case 13: pwm14 = true; break; case 14: pwm15 = true; break; case 15: pwm16 = true; break; } // Set the time when this PWM should be pulled low pwm_time[pwm_counter] = t + OnTime_COT; // Use OnTime_COT for all PWM pins pwm_on_time[pwm_counter] = t; // Store the time when the PWM turned on } } } // If 30ns has passed and the set signal is still high, move to the next PWM if ((t - pwm_on_time[pwm_counter]) > 31e-9 && set) { // Move to the next PWM and set it high pwm_counter = (pwm_counter + 1) % 16; // Move to the next PWM in round-robin sequence // Check if it's the first round (PWM1 to PWM16) if (!first_round_completed) { // Set the next PWM pin high without mini_off_time constraint switch (pwm_counter) { case 0: pwm1 = true; break; case 1: pwm2 = true; break; case 2: pwm3 = true; break; case 3: pwm4 = true; break; case 4: pwm5 = true; break; case 5: pwm6 = true; break; case 6: pwm7 = true; break; case 7: pwm8 = true; break; case 8: pwm9 = true; break; case 9: pwm10 = true; break; case 10: pwm11 = true; break; case 11: pwm12 = true; break; case 12: pwm13 = true; break; case 13: pwm14 = true; break; case 14: pwm15 = true; break; case 15: pwm16 = true; break; } // Set the time when this PWM should be pulled low pwm_time[pwm_counter] = t + OnTime_COT; pwm_on_time[pwm_counter] = t; // Store the time when the PWM turned on // After completing PWM16, mark the first round as complete if (pwm_counter == 15) { first_round_completed = true; } } else { // Apply mini_off_time constraint after the first round if (t - pwm_off_time[pwm_counter] >= mini_off_time) { // Set the next PWM pin high switch (pwm_counter) { case 0: pwm1 = true; break; case 1: pwm2 = true; break; case 2: pwm3 = true; break; case 3: pwm4 = true; break; case 4: pwm5 = true; break; case 5: pwm6 = true; break; case 6: pwm7 = true; break; case 7: pwm8 = true; break; case 8: pwm9 = true; break; case 9: pwm10 = true; break; case 10: pwm11 = true; break; case 11: pwm12 = true; break; case 12: pwm13 = true; break; case 13: pwm14 = true; break; case 14: pwm15 = true; break; case 15: pwm16 = true; break; } // Set the time when this PWM should be pulled low pwm_time[pwm_counter] = t + OnTime_COT; pwm_on_time[pwm_counter] = t; // Store the time when the PWM turned on } } } // Turn off PWM pins when the time is reached for (int i = 0; i < 16; ++i) { if (t >= pwm_time[i]) { pwm_off_time[i] = t; switch (i) { case 0: pwm1 = false; break; case 1: pwm2 = false; break; case 2: pwm3 = false; break; case 3: pwm4 = false; break; case 4: pwm5 = false; break; case 5: pwm6 = false; break; case 6: pwm7 = false; break; case 7: pwm8 = false; break; case 8: pwm9 = false; break; case 9: pwm10 = false; break; case 10: pwm11 = false; break; case 11: pwm12 = false; break; case 12: pwm13 = false; break; case 13: pwm14 = false; break; case 14: pwm15 = false; break; case 15: pwm16 = false; break; } } } // Update the previous_set to check for rising edge in the next cycle previous_set = set; }