
/*
 * dials.c
 *
 *  Created on: 22 Jan 2016
 *      Author: Mike
 */
#include "stm32l1xx_hal.h"
#include "ap_math.h"
#include "font.h"
#include "SSD1306.h"
#include "dials.h"

// this is the number of degrees between top centre of scale and
// left or right hand end of scale : 90 degrees produces a semicircle.
static uint16_t a1 = 90;
static uint8_t xo = 64;
static uint8_t yo = 64;
static uint8_t siz = 32;

/* position is integer from 0 to SINE_STEPS */
void
dial_draw_needle (uint16_t position)
{
  int ang = SINE_SCALING * ((position - (SINE_STEPS/2)) * a1) / (SINE_STEPS/2);

  int si = ap_sin (ang);
  int co = ap_cos (ang);

  /* calculate a shift for a second side of the needle */
  int xl = ap_sin (ang - SINE_STEPS);
  int yl = ap_cos (ang - SINE_STEPS);

  int si2 = siz + 2;
  int si3 = 2 * siz / 3;

  int xs,ys;
  // three parallel lines
  xs = -xl;
  ys = -yl;
  int step;
  for(step =0; step < 3; step++)
    {
    drawLine (AP_SCALE(si*si2-xs) + xo, yo - AP_SCALE(co * si2 - ys),

    AP_SCALE(si*si3-xs) + xo,
	    yo - AP_SCALE(co * si3 - ys), INVERT);
    xs+=xl;
    ys+=yl;
    }
 }

/* initialise */
void
dial_size (uint8_t size)
{
  siz = size;
}

void dial_draw_scale (int16_t low, int16_t high, uint8_t width, uint8_t num_step,int16_t scale)
{
  int sz;
  int ang;
  int sc_low  = low/scale;
  int sc_high = high/scale;
  int step = 256 * a1 * 2 / (4 * (sc_high - sc_low));
  int t;
  ang = -a1 * 256;
  for (t = sc_low * 4; t <= sc_high * 4; t++)
    {
      int si = ap_sin ((ang*SINE_SCALING) / 256);
      int co = ap_cos ((ang*SINE_SCALING) / 256);

      int len;
      switch (t % 4)
	{
	case 0:
	  len = width;
	  break;
	case 1:
	case 3:
	case -1:
	case -3:
	  len = width / 4;
	  break;
	case 2:
	case -2:
	  len = width / 2;
	  break;
	}

      drawLine (AP_SCALE((siz)*si) + xo, yo - AP_SCALE((siz) * co),
      AP_SCALE((siz-len)*si) + xo,
		yo - AP_SCALE((siz - len) * co), 1);
      ang += step;
    }

  font_sig_digits (0,7,0,10,low);
  font_sig_digits(20,7,1,10,high);
}

void
dial_origin (uint8_t x, uint8_t y)
{
  xo = x;
  yo = y;
}
