Skip to content

Instantly share code, notes, and snippets.

@LightningStalker
Created August 25, 2017 21:51
Show Gist options
  • Select an option

  • Save LightningStalker/34a5d9c74984901721ba94c530f7f949 to your computer and use it in GitHub Desktop.

Select an option

Save LightningStalker/34a5d9c74984901721ba94c530f7f949 to your computer and use it in GitHub Desktop.
Calculate PIC microcontroller timing loops of 1-4 stages using given inner loop overhead
/* compile with "gcc -Wall -opicloops picloops.c -lm"
*
* picloops.c - Calculate PIC microcontroller timing loops of 1-4 stages
* using given inner loop overhead
*
* Time in seconds and clock speed in MHz shall be specified on the
* command line in any order. For instance
* $ ./picloops 4 60
*
* Loosely based on picasm's pic loop calculator
*
* Author: Robert Dvoracek
* Contact/Website: http://kickme.to/lightningstalker
*
* Bugs: slightly inaccurate for inner loop overhead values other than 9
*
* A great source of info can be found at
* http://www.piclist.com/techref/microchip/PIC16DelayTutorial.htm*/
#include <stdio.h>
#include <math.h>
#include <errno.h>
#include <stdlib.h>
/*#define INNER_LOOP_OVERHEAD 4.0
#define MACHINE_CYCLE_MAX (THREE_STAGE_MAX) * 256 + 6
#define SINGLE_STAGE_MAX INNER_LOOP_OVERHEAD * 256 + 1
#define TWO_STAGE_MAX (SINGLE_STAGE_MAX + 1) * 256 + 3
#define THREE_STAGE_MAX (TWO_STAGE_MAX - 1) * 256 + 2
#define FOUR_STAGE_MAX MACHINE_CYCLE_MAX
#define FACTORB (INNER_LOOP_OVERHEAD * 256 + 2)
#define FACTORC (FACTORB * 256 + 2)
#define FACTORD (FACTORC * 256 + 2)
#define TWO_STAGE_ADD (FACTORB - 5)
#define THREE_STAGE_ADD (FACTORB + FACTORC - 9)
#define FOUR_STAGE_ADD (FACTORB + FACTORC + FACTORD - 13)*/
int main(int argc, char **argv) {
int counterA, counterB, counterC, counterD, leftover;
double inner_loop_overhead, machine_cycle_max, single_stage_max,
two_stage_max, three_stage_max, four_stage_max;
double factorB, factorC, factorD, two_stage_add, three_stage_add,
four_stage_add;
double time, cycles;
if (argc != 4) {
puts("Usage: $ picloops freqMHz time #cycles_in_inner_loop");
return(1);
}
counterA = counterB = counterC = counterD = -1;
time = 4.0 / (atof(argv[2]) * 1000000.0);
cycles = floor(atof(argv[1]) / time);
inner_loop_overhead = floor(atof(argv[3]));
single_stage_max = inner_loop_overhead * 256 + 1;
two_stage_max = (single_stage_max + 1) * 256 + 3;
three_stage_max = (two_stage_max - 1) * 256 + 2;
machine_cycle_max = (three_stage_max) * 256 + 6;
four_stage_max = machine_cycle_max;
factorB = (inner_loop_overhead * 256 + 2);
factorC = (factorB * 256 + 2);
factorD = (factorC * 256 + 2);
two_stage_add = (factorB - 5);
three_stage_add = (factorB + factorC - 9);
four_stage_add = (factorB + factorC + factorD - 13);
if(cycles <= single_stage_max) {
counterA = ((cycles - 1.0) / inner_loop_overhead);
leftover = (cycles - (inner_loop_overhead * counterA) - 1);
}
else if(cycles <= two_stage_max) {
counterB = ((cycles + two_stage_add) / factorB);
counterA = ((cycles + two_stage_add - factorB * counterB) / inner_loop_overhead);
leftover = (cycles - (inner_loop_overhead * counterA + factorB * counterB) + two_stage_add);
}
else if(cycles <= three_stage_max) {
counterC = ((cycles + three_stage_add) / factorC);
counterB = ((cycles + three_stage_add - counterC * factorC) / factorB);
counterA = ((cycles + three_stage_add - (counterC * factorC + counterB * factorB)) / inner_loop_overhead);
leftover = (cycles - (inner_loop_overhead * counterA + factorB * counterB + factorC * counterC) + three_stage_add);
}
else if(cycles <= four_stage_max) {
counterD = ((cycles + four_stage_add) / factorD);
counterC = ((cycles + four_stage_add - counterD * factorD) / factorC);
counterB = ((cycles + four_stage_add - (counterD * factorD + counterC * factorC)) / factorB);
counterA = ((cycles + four_stage_add - (counterD * factorD + counterC * factorC + counterB * factorB)) / inner_loop_overhead);
leftover = (cycles - (inner_loop_overhead * counterA + factorB * counterB + factorC * counterC + factorD * counterD) + four_stage_add);
}
if(counterA == 256)
counterA = 0;
if(counterB == 256)
counterB = 0;
if(counterC == 256)
counterC = 0;
printf("%d %d %d %d + %d\n", counterA, counterB, counterC, counterD, leftover);
printf("%f %f %f %f\n", two_stage_add, three_stage_add, four_stage_add, single_stage_max);
return(0);
}
//xa - x + (x - 1)
//9a - 1
//9a + 2306b - 2301
//9a + 2306b + 590338c - 592635
//9a + 2306b + 590338c + 151126530d - 151719161
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment