]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blobdiff - rpp/src/drv/din.c
Merge port and gpio definitions into one file in the DRV layer
[pes-rpp/rpp-lib.git] / rpp / src / drv / din.c
index 088c5ada8bff400b634f246027dfe3c213d700ad..ccdafb23548e3248503fe90a8fc5ef4d06f9d760 100644 (file)
-/*
- * din.c
+/* Copyright (C) 2012-2013 Czech Technical University in Prague
  *
- *  Created on: 17.12.2012
- *      Author: Michal Horn
+ * Authors:
+ *     - Michal Horn <hornmich@fel.cvut.cz>
+ *     - Martin Koubek <martin.koubek@porsche-engineering.com>
  *
- *  This file contains functions to control DIN
- *  Voltage on each pin can be set
- *  switch to ground or to battery on programable pins can be set
- *  interrupts on each pins can be disabled and enabled
+ * This document contains proprietary information belonging to Czech
+ * Technical University in Prague. Passing on and copying of this
+ * document, and communication of its contents is not permitted
+ * without prior written authorization.
+ *
+ * File : din.c
+
+ * Abstract:
+ *        This file is written for 33972 Multiple Switch
+ *        http://www.freescale.com/files/analog/doc/data_sheet/MC33972.pdf
+ *
+ *        This file contains functions to control DIN
+ *        Voltage on each pin can be set
+ *        switch to ground or to battery on programable pins can be set
+ *        interrupts on each pins can be disabled and enabled
  */
 
-//#include "drv_din.h"
+
+/******************************************************************************
+*   Include Files
+******************************************************************************/
 #include "drv/drv.h"
 
-/** Prepared command */
-uint32_t din_spi_cmd = DIN_SPICMD_INIT_VAL;
-/** Shadow variable used during sending */
-uint32_t din_spi_cmd_sh = DIN_SPICMD_INIT_VAL;
+
+
+/******************************************************************************
+*   Static Variable Definitions
+******************************************************************************/
 /** Stored response from SPI */
-uint32_t din_spi_resp = 0;
-/** Prepared command for change status on SP pins */
-uint32_t pin_st_p_cmd;
-/** Prepared command for change status on SG pins */
-uint32_t pin_st_g_cmd;
-/** Prepared command for disabling interrupt on SP pins */
-uint32_t pin_int_p_cmd;
-/** Prepared command for disabling interrupt on SG pins */
-uint32_t pin_int_g_cmd;
-
-/** Signal for state cmd transfer */
-uint8_t transfer_state_cmd = 0;
-/** Signal for interrupt cmd trasfer */
-uint8_t transfer_interrupt_cmd = 0;
-
-/** Indexes of bits in status commands assigned to pins */
-static const uint32_t din_set_pin_st_i[]  = {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7};
-/** Indexes of bits in switch-to commands assigned to pins */
-static const uint32_t din_set_pin_pr_i[]  = {0, 1, 2, 3, 4, 5, 6, 7};
-/** Indexes of bits in response assigned to pins */
-static const uint32_t din_get_pin_val_i[]  = {14, 15, 16, 17, 18, 19, 20, 21, 0, 1, 2, 3, 4, 5, 6, 7};
-
-/*
- * Get DIN pin value.
- * @param pin index of pin according the scheme (0-15)
- * @return value on pin or -1 if error
- */
-int din_get_pin_val(uint32_t pin) {
-    if (pin > 15) return -1;
-    return ((din_spi_resp & (1 << din_get_pin_val_i[pin])) > 0);
-}
+static uint32_t din_spi_resp = 0;
+
+/** Store commands in shadow registers */
+static uint16_t shadow_reg_list[DIN_NUM_SPI_CMD];
 
+/******************************************************************************
+*   Function Prototypes
+******************************************************************************/
 /**
- * Set programmable pin DIN_SP according bits in argument as switch-to-battery (1) or switch-to-ground(0)
- * @param word  8-bit array representing switch-to state
+ * Switch copy command, prepared by other functions, to shadow variable,
+ * convert command to MSB,
+ * transfer command to DIN
+ * store spi response
+ * return spi response
  */
-void din_set_pr(uint8_t word) {
-    int i;
-    uint8_t val;
-    din_spi_cmd = 1 << 16;  // Set command
-
-    for (i = 0; i < 8; i++,word >>= 1) {
-        val = word&0x1;
-        if (val == 1) {
-            din_spi_cmd |= 1 << din_set_pin_pr_i[i];
-        }
-        else if (val == 0) {
-            din_spi_cmd &= ~(1 << din_set_pin_pr_i[i]);
-        }
-    }
-}
+int din_spi_transfer_mst(const uint32_t din_spi_cmd);
+
+/******************************************************************************
+*   Close variable declaration sections
+******************************************************************************/
+/* Private defines */
+/* --------------- */
+/** Options: */
+/**   Bit 13: Output Gain Selection bit set = 1x (VOUT = VREF * D/4096)   */
+/**   Bit 15: DACA (0) or DACB (1) Selection bit.  */
+#define DACA_INIT_VAL   (_BV(13) | _BV(12)          )
+#define DACB_INIT_VAL   (_BV(13) | _BV(12) | _BV(15))
 
 /**
- * Set DIN pins to be tri-state (1) or Active (0)
- * @param sp_state 16-bit variable representing state of SP pins. (0 - active, 1 - tri-state).
- * @param sg_state 16-bit variable representing state of SP pins. (0 - active, 1 - tri-state).
+ * This find an index in register list
+ * @param command
+ * @return index
  */
-void din_set_stat(uint16_t sp_state, uint16_t sg_state) {
-    int i;
-    uint16_t val;
-    uint32_t state = (sp_state&0xFF)|((sg_state&0xFF)<<8);
-    uint32_t* pin_cmd_ptr = NULL;
-    pin_st_p_cmd = 0x9 << 16;       // Set command for SP pins
-    pin_st_g_cmd = 0xA << 16;       // Set command for SG pins
-    for (i = 0; i < 16; i++,state >>= 1) {
-        val = state&0x1;
-        if (i < 8) {    // First 8 pins SP0 - SP7
-            pin_cmd_ptr = &pin_st_p_cmd;
-        }
-        else { // Another 8 pins SG0 - SG7
-            pin_cmd_ptr = &pin_st_g_cmd;
-        }
-
-        if (val) {
-            *pin_cmd_ptr |= 1 << din_set_pin_st_i[i];
-        }
-        else {
-            *pin_cmd_ptr &= ~(1 << din_set_pin_st_i[i]);
-        }
-    }
-    transfer_state_cmd = 1; // Enable transfer of two commands at once
+static uint32_t enum2cmd(const enum SpiCmdTable index)
+{
+       if (index == DIN_RESET_CMD)
+               return 0x007F0000;
+       else
+               return index << 16;
 }
 
-/**
- * Enable/disable interrupts for DIN pins as well as acting pins as wake-up
- * @param sp_int_enable 16-bit variable representing interrupt enablers for SP pins (0 - disable wake-up and interrupt, 1 - enable interrupt).
- * @param sg_int_enable 16-bit variable representing interrupt enablers for SG pins (0 - disable wake-up and interrupt, 1 - enable interrupt).
- */
-void din_set_int(uint16_t sp_int_enable, uint16_t sg_int_enable) {
-    int i;
-    uint16_t val;
-    uint32_t int_enable = (sp_int_enable&0xFF)|((sg_int_enable&0xFF)<<8);
-    uint32_t* pin_cmd_ptr = NULL;
-    pin_int_p_cmd = 0x2 << 16;      // Set command for SP pins
-    pin_int_g_cmd = 0x3 << 16;      // Set command for SG pins
-    for (i = 0; i < 16; i++,int_enable >>= 1) {
-        val = int_enable&0x1;
-        if (i < 8) {    // First 8 pins SP0 - SP7
-            pin_cmd_ptr = &pin_int_p_cmd;
-        }
-        else { // Another 8 pins SG0 - SG7
-            pin_cmd_ptr = &pin_int_g_cmd;
-        }
-
-        if (val) {
-            *pin_cmd_ptr |= 1 << din_set_pin_st_i[i];
-        }
-        else {
-            *pin_cmd_ptr &= ~(1 << din_set_pin_st_i[i]);
-        }
-    }
-    transfer_interrupt_cmd = 1; // Enable transfer of two commands at once
+/* Public functions */
+/* ---------------- */
+
+uint16_t din_set_reg(
+       enum SpiCmdTable spi_cmd_index, uint16_t clear_mask, uint16_t xor_mask)
+{
+       if (spi_cmd_index >= DIN_NUM_SPI_CMD)
+               return 0;
+
+       shadow_reg_list[spi_cmd_index] =
+               shadow_reg_list[spi_cmd_index] & ~clear_mask ^ xor_mask;
+
+       uint32_t din_spi_cmd = enum2cmd(spi_cmd_index) | shadow_reg_list[spi_cmd_index];
+
+       return din_spi_transfer_mst(din_spi_cmd);
 }
 
-/**
- * Prepare reset command to be sent through spi
- */
-void din_reset() {
-    din_spi_cmd = 0x7F0000;
+int8_t drv_din_ref(uint16_t ref_a, uint16_t ref_b)
+{
+
+       uint16_t cmd;
+
+       // Get descriptor
+       uint32_t commands[2];
+       dio_port_desc_t *desc = dio_port_get_dsc(DIO_PORT_NAME_DACDREF, -1);
+
+       // Send command for DAC A
+       cmd = DACA_INIT_VAL | (ref_a & 0x0FFF);
+
+       commands[0] = (cmd & 0xFF00) >> 8;
+       commands[1] = (cmd & 0xFF);
+       desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
+
+       // Send command for DAC B
+       cmd = DACB_INIT_VAL | (ref_b & 0x0FFF);
+
+       commands[0] = (cmd & 0xFF00) >> 8;
+       commands[1] = (cmd & 0xFF);
+       desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
+
+       // Fixme: check SPI return value.
+       return SUCCESS;
 }
 
-/**
- * Prepare switch status command to be sent through spi
- */
-void din_switch_st() {
-    din_spi_cmd = 0x0;
+
+int8_t drv_din_get_varthr(uint8_t pin)
+{
+
+       // Check range
+       if ((pin < 8) || (pin > 15))
+               return FAILURE;
+
+       dio_port_desc_t* port = dio_port_get_dsc(DIO_PORT_NAME_DINMCU, -1);
+       if (pin-8 >= port->numValues)
+               return FAILURE;
+
+       return dio_gpio_pin_get_value(port->config[pin - 8]);
 }
 
-/**
- * Get values of all DIN pins in form of 16-bit word DIN15,...,DIN0
- * @return values of all pins DIN0 - DIN15
- */
-uint16_t din_get_val_word() {
-    uint16_t word = 0;
-    int i;
-    for (i = 0; i < 16; i++) {
-        word |= din_get_pin_val(i) << i;
-    }
-    return word;
+uint16_t din_get_val_word()
+{
+       // How it should be.
+       //uint16_t sp = ((din_spi_resp >> 14) & 0x00FF);
+       //uint16_t sg = ((din_spi_resp << 8 ) & 0xFF00);
+
+       // How it actually is.
+       // Ignore datasheet, this is the actual response from the SPI driver:
+       // [xxxx xxxx][SG7-SG0][SP1 SP0 yy yyyy][zz SP7-SP2]
+       //  x: Unknown.
+       //  y: Maybe SG13-SG8, but untested.
+       //  z: Maybe therm flag and int flag.
+       // For SP: First get SP7-SP2 right, then add SP1 and SP0
+       uint16_t sp = ((din_spi_resp << 2) & 0x00FF) | ((din_spi_resp >> 14) & 0x3);
+       uint16_t sg = ((din_spi_resp >> 8) & 0xFF00);
+       uint16_t word = sg | sp;
+
+       return word;
 }
 
+
+int din_spi_response()
+{
+       return din_spi_resp;
+}
+
+
+/* Private functions */
+/* ----------------- */
 /**
  * Switch copy command, prepared by other functions, to shadow variable,
  * convert command to MSB,
@@ -166,56 +169,17 @@ uint16_t din_get_val_word() {
  * store spi response
  * return spi response
  */
-int din_spi_transfer_mst() {
-    port_desc_t* desc;
-    din_spi_cmd_sh = din_spi_cmd;
-    desc = hal_port_get_dsc(PORT_NAME_DINSPI, -1);
-    uint32_t commands[3];
-    commands[0] = (din_spi_cmd_sh & 0xFF0000) >> 16;
-    commands[1] = (din_spi_cmd_sh & 0xFF00) >> 8;
-    commands[2] = (din_spi_cmd_sh & 0xFF);
-
-    din_spi_resp = desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
-    return din_spi_resp;
-}
-
-/**
- * Transfer prepared commands through spi
- * With highest priority send state modification commands
- * With secondary priority send interrupt commands
- * In the end send other commands
- *
- * Store response from spi
- * Returns spi response
- */
-int din_spi_transfer() {
-    if (transfer_state_cmd) {
-        din_spi_cmd = pin_st_p_cmd;
-        din_spi_transfer_mst();
-        din_spi_cmd = pin_st_g_cmd;
-        transfer_state_cmd = 0;
-    }
-    else if (transfer_interrupt_cmd) {
-        din_spi_cmd = pin_int_p_cmd;
-        din_spi_transfer_mst();
-        din_spi_cmd = pin_int_g_cmd;
-        transfer_interrupt_cmd = 0;
-    }
-    return din_spi_transfer_mst();
-}
-
-/**
- * Get latest response from SPI. Function does not send anything.
- * @return latest spi response
- */
-int din_spi_response() {
-    return din_spi_resp;
-}
-
-/**
- * Get last command sent on SPI
- * @return latest sent command
- */
-int din_spi_get_cmd() {
-    return din_spi_cmd;
+int din_spi_transfer_mst(const uint32_t din_spi_cmd)
+{
+       dio_port_desc_t *desc;
+
+       desc = dio_port_get_dsc(DIO_PORT_NAME_DINSPI, -1);
+       uint32_t commands[3];
+       commands[0] = (din_spi_cmd & 0xFF0000) >> 16;   // command
+       commands[1] = (din_spi_cmd & 0xFF00) >> 8;      // 1.st B of data
+       commands[2] = (din_spi_cmd & 0xFF);             // 2.nd B of data
+
+       din_spi_resp = desc->port_setfnc_ptr(desc->config, desc->numValues,     \
+                                                                                commands);
+       return din_spi_resp;
 }