]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/commitdiff
Simplify DIN driver layer
authorMartin Koubek <martin.koubek@porsche-engineering.cz>
Mon, 16 Sep 2013 14:25:52 +0000 (16:25 +0200)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Fri, 20 Sep 2013 14:01:52 +0000 (16:01 +0200)
[Commit message edited by Michal Sojka]

rpp/include/drv/din.h
rpp/src/drv/din.c
rpp/src/rpp/din.c

index 8436f7029e19421cc9a8556d257d4a47b1b5dcb0..d06200289ac794c6f62a443807fffa184f751e32 100644 (file)
@@ -3,26 +3,94 @@
  *
  *  Created on: 17.12.2012
  *      Author: Michal Horn
+ *
+ *  Refactored by: Martin Koubek
+ *     martin.koubek@porsche-engineering.com
+ *     18.9.2013
  */
 
 #ifndef DIN_SPI_H_
 #define DIN_SPI_H_
 
+
+/******************************************************************************
+*   Include Files
+******************************************************************************/
 #include "drv/drv.h"
 
-#define DIN_SPICMD_INIT_VAL     0x007F0000
 
+/******************************************************************************
+*   Macro declaration sections
+******************************************************************************/
+
+/** This is a number of SpiCmdTable values!!! */
+#define NUM_SPI_CMD            13
+
+enum SpiCmdTable
+  {
+    DIN_RESET_CMD =                            13,     //0x0007F000
+    DIN_SWITCH_STATUS_CMD =    0,      //0x00000000,
+    DIN_SETTINGS_CMD,                          //0x00010000,
+    DIN_WAKE_UP_CMD_ENB,                       //0x00020000,
+    DIN_WAKE_UP_CMD_DIS,                       //0x00030000,
+    DIN_METALLIC_CMD_YES,                      //0x00040000,
+    DIN_METALLIC_CMD_NO,                       //0x00050000,
+    DIN_ANALOG_CMD,                            //0x00060000,
+    DIN_WETTING_CRNT_CMD_ON,           //0x00070000,
+    DIN_WETTING_CRNT_CMD_OFF,          //0x00080000,
+    DIN_TRI_STATE_CMD_YES,                     //0x00090000,
+    DIN_TRI_STATE_CMD_NO,                      //0x000A0000,
+    DIN_CALIBRATION_CMD,                       //0x000B0000,
+    DIN_SLEEP_CMD                                      //0x000C0000,
+  };
+
+
+/******************************************************************************
+*   Function declaration sections
+******************************************************************************/
+/**
+ * Send command and data through SPI. It modifies data by AND and XOR, updates
+ * shadow register in din_spi_shadow_reg_list and send the command + data to SPI
+ * din_set_reg(DIN_BIT_XY|DIN_BIT_AB, 0);                 // erase bits XY a AB
+ * din_set_reg(DIN_BIT_XY|DIN_BIT_AB, DIN_BIT_XY|DIN_BIT_AB); // set XY a AB
+ * din_set_reg(0, DIN_BIT_XY|DIN_BIT_AB);                     // modify XY a AB
+ *
+ * @param[in] SpiCmdTable list of supported commands
+ * @param[in] and_ and_ value is bitwise AND by shadow register for the command
+ * @param[in] xor_ xor_ value is bitwise XOR by product of shadow register AND
+ *                                     and_
+ * @return return spi response
+ */
+uint16_t din_set_reg(enum SpiCmdTable cmd_index, uint16_t and_, uint16_t xor_);
+
+/**
+ * Set voltage for DAC A and DAC B
+ *
+ */
 int8_t drv_din_ref(uint16_t ref_a, uint16_t ref_b);
 
+/**
+ * Read GPIO pin value
+ *
+ */
 int8_t drv_din_get_varthr(uint8_t pin);
-void din_set_pr(uint8_t word);
-void din_set_stat(uint16_t sp_state, uint16_t sg_state);
-void din_set_int(uint16_t sp_int_enable, uint16_t sg_int_enable);
+
+/**
+ * Get values of all DIN pins in form of 16-bit word DIN15,...,DIN0
+ * @return values of all pins.
+ */
 uint16_t din_get_val_word();
-int din_spi_transfer();
-void din_reset();
-void din_switch_st();
+
+/**
+ * Get latest response from SPI. Function does not send anything.
+ * @return latest spi response
+ */
 int din_spi_response();
+
+/**
+ * Get last command sent on SPI
+ * @return latest sent command
+ */
 int din_spi_get_cmd();
 
 #endif /* DIN_SPI_H_ */
index 7a11dde1b5726f462859473242c6e37613de9027..16307d0ad2321a2760e475b08eed45ae274885d7 100644 (file)
@@ -4,6 +4,13 @@
  *  Created on: 17.12.2012
  *      Author: Michal Horn
  *
+ *  Refactored by: Martin Koubek
+ *     martin.koubek@porsche-engineering.com
+ *     18.9.2013
+ *
+ *  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
  */
 
 
+/******************************************************************************
+*   Include Files
+******************************************************************************/
 #include "drv/drv.h"
 
-/** Prepared command */
-static uint32_t din_spi_cmd = DIN_SPICMD_INIT_VAL;
-/** Shadow variable used during sending */
-static uint32_t din_spi_cmd_sh = DIN_SPICMD_INIT_VAL;
+
+
+/******************************************************************************
+*   Static Variable Definitions
+******************************************************************************/
 /** Stored response from SPI */
 static uint32_t din_spi_resp = 0;
-/** Prepared command for change status on SP pins */
-static uint32_t pin_st_p_cmd;
-/** Prepared command for change status on SG pins */
-static uint32_t pin_st_g_cmd;
-/** Prepared command for disabling interrupt on SP pins */
-static uint32_t pin_int_p_cmd;
-/** Prepared command for disabling interrupt on SG pins */
-static uint32_t pin_int_g_cmd;
-
-/** Signal for state cmd transfer */
-static uint8_t transfer_state_cmd = 0;
-/** Signal for interrupt cmd trasfer */
-static 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};
+
+/** Store commands in shadow registers */
+static uint16_t shadow_reg_list[NUM_SPI_CMD];
+
 
 const static uint32_t dsc_pin_map[8U] = {
     PIN_DSC_DIN8,
@@ -50,15 +47,62 @@ const static uint32_t dsc_pin_map[8U] = {
 };
 
 
-// See mcp4922.pdf p. 24
-// Options:
-//   Bit 13: Output Gain Selection bit set = 1x (VOUT = VREF * D/4096)
-//   Bit 15: DACA (0) or DACB (1) Selection bit.
+/******************************************************************************
+*   Function Prototypes
+******************************************************************************/
+/**
+ * Switch copy command, prepared by other functions, to shadow variable,
+ * convert command to MSB,
+ * transfer command to DIN
+ * store spi response
+ * return spi response
+ */
+int din_spi_transfer_mst(const uint32_t din_spi_cmd);
+
+/**
+ * This find an index in register list
+ * @param index
+ * @return command
+ */
+uint32_t din_spi_get_command_from_enum(const uint8_t index);
+
+
+
+/******************************************************************************
+*   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))
 
+
+/* Public functions */
+/* ---------------- */
+
+uint16_t din_set_reg(
+               enum SpiCmdTable spi_cmd_index, uint16_t clear_mask, uint16_t xor_mask)
+{
+       if ((uint8_t)spi_cmd_index > NUM_SPI_CMD){
+               return 0;
+       }
+       else{}
+
+       shadow_reg_list[spi_cmd_index] =
+                       shadow_reg_list[spi_cmd_index] & ~clear_mask ^ xor_mask;
+
+       uint32_t din_spi_cmd = din_spi_get_command_from_enum(spi_cmd_index) |
+                       shadow_reg_list[spi_cmd_index];
+
+       return din_spi_transfer_mst(din_spi_cmd);
+}
+
 int8_t drv_din_ref(uint16_t ref_a, uint16_t ref_b)
 {
+
     uint16_t cmd;
 
     // Get descriptor
@@ -94,106 +138,6 @@ int8_t drv_din_get_varthr(uint8_t pin) {
     return hal_gpio_pin_get_value(dsc_pin_map[pin - 8]);
 }
 
-/**
- * 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
- */
-void din_set_pr(uint8_t word) {
-    int i;
-    uint8_t val;
-    din_spi_cmd = 1 << 16;  // Settings 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]);
-        }
-    }
-}
-
-/**
- * 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 SG pins. (0 - active, 1 - tri-state).
- */
-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
-}
-
-/**
- * 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); // LSB
-    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
-}
-
-/**
- * Prepare reset command to be sent through spi
- */
-void din_reset() {
-    din_spi_cmd = 0x7F0000;
-}
-
-/**
- * Prepare switch status command to be sent through spi
- */
-void din_switch_st() {
-    din_spi_cmd = 0x0;
-}
-
-/**
- * Get values of all DIN pins in form of 16-bit word DIN15,...,DIN0
- * @return values of all pins.
- */
 uint16_t din_get_val_word()
 {
     // How it should be.
@@ -213,6 +157,14 @@ uint16_t din_get_val_word()
     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,
@@ -220,56 +172,33 @@ uint16_t din_get_val_word()
  * store spi response
  * return spi response
  */
-int din_spi_transfer_mst() {
+int din_spi_transfer_mst(const uint32_t din_spi_cmd) {
     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);
+    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);
+    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
+ * This find an index in register list
+ * @param command
+ * @return index
  */
-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();
-}
+uint32_t din_spi_get_command_from_enum(const uint8_t index)
+{
+       uint32_t command = 0x0;
 
-/**
- * Get latest response from SPI. Function does not send anything.
- * @return latest spi response
- */
-int din_spi_response() {
-    return din_spi_resp;
-}
+       if (index == DIN_RESET_CMD){
+               return 0x0007F000;
+       }
+       else {}
 
-/**
- * Get last command sent on SPI
- * @return latest sent command
- */
-int din_spi_get_cmd() {
-    return din_spi_cmd;
+       command = index << 16;
+       return command;
 }
index e6ea84f84e8b74976a1f26ee4dd8555311615ed3..85d0da4c4c35716b00547b1f70088a28ff76c834 100644 (file)
@@ -151,7 +151,9 @@ int8_t rpp_din_diag(uint8_t pin)
     return LOW;
 }
 
-
+/*
+ * pouzivat din_mod s pouzivanim enumu
+ */
 int8_t rpp_din_update()
 {
     #if rppCONFIG_DRV == 1
@@ -161,8 +163,7 @@ int8_t rpp_din_update()
         uint16_t sg = 0x0;
 
         // Reset chip
-        din_reset();
-        din_spi_transfer();
+        din_set_reg(DIN_RESET_CMD, 0, 0);
         //rpp_sci_printf("din_reset()\r\n");
 
         // Set pull-type.
@@ -170,8 +171,7 @@ int8_t rpp_din_update()
         // DRV: 1 - set pin as switch-to-battery. RPP: 0 - pull-down.
         // DRV: 0 - set pin as switch-to-ground.  RPP: 1 - pull-up.
         sp = (~pull_cache) & 0xFF;
-        din_set_pr((uint8_t)sp);
-        din_spi_transfer();
+        din_set_reg(DIN_SETTINGS_CMD, 0xffff, sp);
         //rpp_sci_printf("din_set_pr(%X)\r\n", sp);
 
         // Set state type, active or tri-stated.
@@ -180,8 +180,8 @@ int8_t rpp_din_update()
         // DRV: 0 - active.    RPP: 1 - active.
         sp = ((~active_cache)     ) & 0xFF;
         sg = ((~active_cache) >> 8) & 0xFF;
-        din_set_stat(sp, sg);
-        din_spi_transfer();
+        din_set_reg(DIN_TRI_STATE_CMD_YES, 0xffff, sp);
+        din_set_reg(DIN_TRI_STATE_CMD_NO, 0xffff, sg);
         //rpp_sci_printf("din_set_stat(%X, %X)\r\n", sp, sg);
 
         // Set wake / interrupt.
@@ -190,8 +190,9 @@ int8_t rpp_din_update()
         // DRV: 0 - interrupt disabled. RPP: 0 - interrupt disabled.
         sp = (can_wake_cache     ) & 0xFF;
         sg = (can_wake_cache >> 8) & 0xFF;
-        din_set_int(sp, sg);
-        din_spi_transfer();
+
+        din_set_reg(DIN_WAKE_UP_CMD_ENB, 0xffff, sp);
+        din_set_reg(DIN_WAKE_UP_CMD_DIS, 0xffff, sg);
         //rpp_sci_printf("din_set_int(%X, %X)\r\n", sp, sg);
 
         // Mark configuration as commited
@@ -199,8 +200,7 @@ int8_t rpp_din_update()
     }
 
     // Update cached values
-    din_switch_st();
-    din_spi_transfer();
+    din_set_reg(DIN_SWITCH_STATUS_CMD, 0, 0);
     in_cache = din_get_val_word();
 
     // FIXME: Implement. Dummy assign for now.