*
* 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_ */
* 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,
};
-// 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
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.
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,
* 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;
}
return LOW;
}
-
+/*
+ * pouzivat din_mod s pouzivanim enumu
+ */
int8_t rpp_din_update()
{
#if rppCONFIG_DRV == 1
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.
// 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.
// 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.
// 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
}
// 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.