/*
 * drivers.c
 *
 *  Created on: May 22, 2013
 *      Author: dkempert
 */
#include "drivers.h"


/*********************************************************************************
* function:
*   void sseg_disp_ptn(alt_u32 base, alt_u8 *ptn)
*
* purpose: sends a pattern to a 7-segment display
* argument:
*   base: base address of discrete 7-segment digit
*   ptn:  pointer to the data
* return:
* note:
**********************************************************************************/
void sseg_disp_ptn(alt_u32 base, alt_u8 *ptn)
{
  alt_u32 sseg_data;
  int i;

  /* form a 32-bit data */
  for (i=0; i<4; i++) {
    sseg_data = (sseg_data << 8) | *ptn;
    ptn++;
  }
  pio_write(base, sseg_data);
}


/*********************************************************************************
* function:
*   alt_u8 sseg_conv_hex(int hex)
*
* purpose: converts a hex value into a bit pattern for the 7-segment displays
* argument:
*   hex:  the value to be converted
* return:
*   the bit pattern in 8 bits
* note:
**********************************************************************************/
alt_u8 sseg_conv_hex(int hex)
{
  /* active-low hex digit 7-seg patterns (0-9,a-f); MSB ignored */
  static const alt_u8 SSEG_HEX_TABLE[16] = {
    0x40, 0x79, 0x24, 0x30, 0x19, 0x92, 0x02, 0x78, 0x00, 0x10, // 0-9
    0x88, 0x03, 0x46, 0x21, 0x06, 0x0E}; // a-f

  alt_u8 ptn;
  if (hex < 16)
    ptn = SSEG_HEX_TABLE[hex];
  else
    ptn = 0xff; //blank
  return (ptn);
}

/*********************************************************************************
* function:
*   void timer_wr_prd(alt_u32 timer_base, alt_u32 prd)
*
* purpose: writes the period to the timer
* argument:
*   timer_base:  the base address of the timer
*   prd:  the period to be written
* return:
* note:
**********************************************************************************/
void timer_wr_prd(alt_u32 timer_base, alt_u32 prd)
{
  alt_u16 high, low;

  /* unpack 32-bit timeout period into two 16-bit half words */
  high = (alt_u16) (prd>>16);
  low = (alt_u16) (prd & 0x0000ffff);
  /* write timeout period */
  IOWR(timer_base, TIMER_PRDH_REG_OFT, high);
  IOWR(timer_base, TIMER_PRDL_REG_OFT, low);
  /* configure timer to start , continuous mode, enabling interrupt */
  IOWR(timer_base, TIMER_CTRL_REG_OFT, 0x0007);
}

