kopia lustrzana https://github.com/OpenRTX/OpenRTX
Module17: use hardware I2C for MCP4551
rodzic
b196ce9cbc
commit
7052dbcf8b
|
@ -422,7 +422,7 @@ mod17_src = ['platform/targets/Module17/platform.c',
|
||||||
'platform/drivers/baseband/radio_Mod17.cpp',
|
'platform/drivers/baseband/radio_Mod17.cpp',
|
||||||
'platform/drivers/audio/audio_Mod17.c',
|
'platform/drivers/audio/audio_Mod17.c',
|
||||||
'platform/drivers/audio/MAX9814_Mod17.cpp',
|
'platform/drivers/audio/MAX9814_Mod17.cpp',
|
||||||
'platform/drivers/baseband/MCP4551_Mod17.cpp']
|
'platform/drivers/baseband/MCP4551.c']
|
||||||
|
|
||||||
mod17_inc = ['platform/targets/Module17']
|
mod17_inc = ['platform/targets/Module17']
|
||||||
mod17_def = {'PLATFORM_MOD17': ''}
|
mod17_def = {'PLATFORM_MOD17': ''}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2021 - 2024 by Federico Amedeo Izzo IU2NUO, *
|
||||||
|
* Niccolò Izzo IU2KIN *
|
||||||
|
* Frederik Saraci IU2NRO *
|
||||||
|
* Silvano Seva IU2KWO *
|
||||||
|
* Mathis Schmieder DB9MAT *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "MCP4551.h"
|
||||||
|
|
||||||
|
// Common WIPER values
|
||||||
|
#define MCP4551_WIPER_MID 0x080
|
||||||
|
#define MCP4551_WIPER_A 0x100
|
||||||
|
#define MCP4551_WIPER_B 0x000
|
||||||
|
|
||||||
|
// Command definitions (sent to WIPER register)
|
||||||
|
#define MCP4551_CMD_WRITE 0x00
|
||||||
|
#define MCP4551_CMD_INC 0x04
|
||||||
|
#define MCP4551_CMD_DEC 0x08
|
||||||
|
#define MCP4551_CMD_READ 0x0C
|
||||||
|
|
||||||
|
|
||||||
|
int mcp4551_init(const struct i2cDevice *i2c, const uint8_t devAddr)
|
||||||
|
{
|
||||||
|
return mcp4551_setWiper(i2c, devAddr, MCP4551_WIPER_MID);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mcp4551_setWiper(const struct i2cDevice *i2c, const uint8_t devAddr,
|
||||||
|
const uint16_t value)
|
||||||
|
{
|
||||||
|
uint8_t data[2] =
|
||||||
|
{
|
||||||
|
(uint8_t)(value >> 8 & 0x01) | MCP4551_CMD_WRITE,
|
||||||
|
(uint8_t) value
|
||||||
|
};
|
||||||
|
|
||||||
|
i2c_acquire(i2c);
|
||||||
|
int ret = i2c_write(i2c, devAddr, data, 2, true);
|
||||||
|
i2c_release(i2c);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2021 - 2023 by Federico Amedeo Izzo IU2NUO, *
|
* Copyright (C) 2021 - 2024 by Federico Amedeo Izzo IU2NUO, *
|
||||||
* Niccolò Izzo IU2KIN *
|
* Niccolò Izzo IU2KIN *
|
||||||
* Frederik Saraci IU2NRO *
|
* Frederik Saraci IU2NRO *
|
||||||
* Silvano Seva IU2KWO *
|
* Silvano Seva IU2KWO *
|
||||||
|
@ -25,29 +25,31 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <datatypes.h>
|
#include <datatypes.h>
|
||||||
|
#include <peripherals/i2c.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Common WIPER values
|
/**
|
||||||
#define MCP4551_WIPER_MID 0x080
|
* Initialize the MCP4551 device.
|
||||||
#define MCP4551_WIPER_A 0x100
|
*
|
||||||
#define MCP4551_WIPER_B 0x000
|
* @param i2c: driver managing the I2C bus the chip is connected to.
|
||||||
|
* @param devAddr: I2C device address of the chip.
|
||||||
// Command definitions (sent to WIPER register)
|
* @return zero on success, a negative error code otherwise.
|
||||||
#define MCP4551_CMD_WRITE 0x00
|
*/
|
||||||
#define MCP4551_CMD_INC 0x04
|
int mcp4551_init(const struct i2cDevice *i2c, const uint8_t devAddr);
|
||||||
#define MCP4551_CMD_DEC 0x08
|
|
||||||
#define MCP4551_CMD_READ 0x0C
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise I2C.
|
* Set the MCP4551 wiper to a given position.
|
||||||
|
*
|
||||||
|
* @param i2c: driver managing the I2C bus the chip is connected to.
|
||||||
|
* @param devAddr: I2C device address of the chip.
|
||||||
|
* @param value: new wiper position.
|
||||||
|
* @return zero on success, a negative error code otherwise.
|
||||||
*/
|
*/
|
||||||
void i2c_init();
|
int mcp4551_setWiper(const struct i2cDevice *i2c, const uint8_t devAddr,
|
||||||
|
const uint16_t value);
|
||||||
void mcp4551_init(uint8_t addr);
|
|
||||||
void mcp4551_setWiper(uint8_t devAddr, uint16_t value);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,203 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2021 - 2023 by Federico Amedeo Izzo IU2NUO, *
|
|
||||||
* Niccolò Izzo IU2KIN *
|
|
||||||
* Frederik Saraci IU2NRO *
|
|
||||||
* Silvano Seva IU2KWO *
|
|
||||||
* Mathis Schmieder DB9MAT *
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* This program is distributed in the hope that it will be useful, *
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
||||||
* GNU General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU General Public License *
|
|
||||||
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include <peripherals/gpio.h>
|
|
||||||
#include <interfaces/delays.h>
|
|
||||||
#include <hwconfig.h>
|
|
||||||
#include "MCP4551.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Implementation of MCP4551 I2C interface.
|
|
||||||
*
|
|
||||||
* Hardware I2C is not yet implemented. Bit-bang, baby!
|
|
||||||
*/
|
|
||||||
|
|
||||||
void _i2c_start();
|
|
||||||
void _i2c_stop();
|
|
||||||
void _i2c_write(uint8_t val);
|
|
||||||
uint8_t _i2c_read(bool ack);
|
|
||||||
|
|
||||||
void i2c_init()
|
|
||||||
{
|
|
||||||
gpio_setMode(I2C_SDA, INPUT);
|
|
||||||
gpio_setMode(I2C_SCL, OUTPUT);
|
|
||||||
gpio_clearPin(I2C_SCL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mcp4551_init(uint8_t addr)
|
|
||||||
{
|
|
||||||
mcp4551_setWiper(addr, MCP4551_WIPER_MID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mcp4551_setWiper(uint8_t devAddr, uint16_t value)
|
|
||||||
{
|
|
||||||
_i2c_start();
|
|
||||||
_i2c_write(devAddr << 1);
|
|
||||||
uint8_t temp = ((value >> 8 & 0x01) | MCP4551_CMD_WRITE);
|
|
||||||
_i2c_write(temp);
|
|
||||||
temp = (value & 0xFF);
|
|
||||||
_i2c_write(temp);
|
|
||||||
_i2c_stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*uint16_t i2c_readReg16(uint8_t devAddr, uint8_t reg)
|
|
||||||
{
|
|
||||||
_i2c_start();
|
|
||||||
_i2c_write(devAddr << 1);
|
|
||||||
_i2c_write(reg);
|
|
||||||
_i2c_start();
|
|
||||||
_i2c_write(devAddr | 0x01);
|
|
||||||
uint8_t valHi = _i2c_read(true);
|
|
||||||
uint8_t valLo = _i2c_read(false);
|
|
||||||
_i2c_stop();
|
|
||||||
|
|
||||||
return (valHi << 8) | valLo;
|
|
||||||
} */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Software I2C routine
|
|
||||||
*/
|
|
||||||
|
|
||||||
void _i2c_start()
|
|
||||||
{
|
|
||||||
gpio_setMode(I2C_SDA, OUTPUT);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Lines commented to keep SCL high when idle
|
|
||||||
*
|
|
||||||
gpio_clearPin(I2C_SCL);
|
|
||||||
delayUs(2);
|
|
||||||
*/
|
|
||||||
|
|
||||||
gpio_setPin(I2C_SDA);
|
|
||||||
delayUs(5);
|
|
||||||
|
|
||||||
gpio_setPin(I2C_SCL);
|
|
||||||
delayUs(5);
|
|
||||||
|
|
||||||
gpio_clearPin(I2C_SDA);
|
|
||||||
delayUs(5);
|
|
||||||
|
|
||||||
gpio_clearPin(I2C_SCL);
|
|
||||||
delayUs(6);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _i2c_stop()
|
|
||||||
{
|
|
||||||
gpio_setMode(I2C_SDA, OUTPUT);
|
|
||||||
|
|
||||||
gpio_clearPin(I2C_SCL);
|
|
||||||
delayUs(5);
|
|
||||||
|
|
||||||
gpio_clearPin(I2C_SDA);
|
|
||||||
delayUs(5);
|
|
||||||
|
|
||||||
gpio_setPin(I2C_SCL);
|
|
||||||
delayUs(5);
|
|
||||||
|
|
||||||
gpio_setPin(I2C_SDA);
|
|
||||||
delayUs(5);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Lines commented to keep SCL high when idle
|
|
||||||
*
|
|
||||||
gpio_clearPin(I2C_SCL);
|
|
||||||
delayUs(5);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void _i2c_write(uint8_t val)
|
|
||||||
{
|
|
||||||
gpio_setMode(I2C_SDA, OUTPUT);
|
|
||||||
|
|
||||||
for(uint8_t i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
gpio_clearPin(I2C_SCL);
|
|
||||||
delayUs(1);
|
|
||||||
|
|
||||||
if(val & 0x80)
|
|
||||||
{
|
|
||||||
gpio_setPin(I2C_SDA);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gpio_clearPin(I2C_SDA);
|
|
||||||
}
|
|
||||||
|
|
||||||
val <<= 1;
|
|
||||||
delayUs(1);
|
|
||||||
gpio_setPin(I2C_SCL);
|
|
||||||
delayUs(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure SCL is low before releasing SDA */
|
|
||||||
gpio_clearPin(I2C_SCL);
|
|
||||||
|
|
||||||
/* Clock cycle for slave ACK/NACK */
|
|
||||||
gpio_setMode(I2C_SDA, INPUT_PULL_UP);
|
|
||||||
delayUs(5);
|
|
||||||
gpio_setPin(I2C_SCL);
|
|
||||||
delayUs(5);
|
|
||||||
gpio_clearPin(I2C_SCL);
|
|
||||||
delayUs(1);
|
|
||||||
|
|
||||||
/* Asserting SDA pin allows to fastly bring the line to idle state */
|
|
||||||
gpio_setPin(I2C_SDA);
|
|
||||||
gpio_setMode(I2C_SDA, OUTPUT);
|
|
||||||
delayUs(6);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t _i2c_read(bool ack)
|
|
||||||
{
|
|
||||||
gpio_setMode(I2C_SDA, INPUT_PULL_UP);
|
|
||||||
gpio_clearPin(I2C_SCL);
|
|
||||||
|
|
||||||
uint8_t value = 0;
|
|
||||||
for(uint8_t i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
delayUs(5);
|
|
||||||
gpio_setPin(I2C_SCL);
|
|
||||||
delayUs(5);
|
|
||||||
|
|
||||||
value <<= 1;
|
|
||||||
value |= gpio_readPin(I2C_SDA);
|
|
||||||
|
|
||||||
gpio_clearPin(I2C_SCL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set ACK/NACK state BEFORE putting SDA gpio to output mode.
|
|
||||||
* This avoids spurious spikes which can be interpreted as NACKs
|
|
||||||
*/
|
|
||||||
gpio_clearPin(I2C_SDA);
|
|
||||||
gpio_setMode(I2C_SDA, OUTPUT);
|
|
||||||
delayUs(5);
|
|
||||||
if(!ack) gpio_setPin(I2C_SDA);
|
|
||||||
|
|
||||||
/* Clock cycle for ACK/NACK */
|
|
||||||
delayUs(5);
|
|
||||||
gpio_setPin(I2C_SCL);
|
|
||||||
delayUs(5);
|
|
||||||
gpio_clearPin(I2C_SCL);
|
|
||||||
delayUs(5);
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
|
@ -35,8 +35,8 @@ void radio_init(const rtxStatus_t *rtxState)
|
||||||
|
|
||||||
radioStatus = OFF;
|
radioStatus = OFF;
|
||||||
|
|
||||||
mcp4551_setWiper(SOFTPOT_TX, mod17CalData.tx_wiper);
|
mcp4551_setWiper(&i2c1, SOFTPOT_TX, mod17CalData.tx_wiper);
|
||||||
mcp4551_setWiper(SOFTPOT_RX, mod17CalData.rx_wiper);
|
mcp4551_setWiper(&i2c1, SOFTPOT_RX, mod17CalData.rx_wiper);
|
||||||
}
|
}
|
||||||
|
|
||||||
void radio_terminate()
|
void radio_terminate()
|
||||||
|
@ -74,8 +74,8 @@ void radio_enableRx()
|
||||||
{
|
{
|
||||||
radioStatus = RX;
|
radioStatus = RX;
|
||||||
|
|
||||||
mcp4551_setWiper(SOFTPOT_TX, mod17CalData.tx_wiper);
|
mcp4551_setWiper(&i2c1, SOFTPOT_TX, mod17CalData.tx_wiper);
|
||||||
mcp4551_setWiper(SOFTPOT_RX, mod17CalData.rx_wiper);
|
mcp4551_setWiper(&i2c1, SOFTPOT_RX, mod17CalData.rx_wiper);
|
||||||
|
|
||||||
// Module17 PTT output is open drain. This means that, on MCU side, we have
|
// Module17 PTT output is open drain. This means that, on MCU side, we have
|
||||||
// to assert the gpio to bring it to low state.
|
// to assert the gpio to bring it to low state.
|
||||||
|
@ -89,8 +89,8 @@ void radio_enableTx()
|
||||||
{
|
{
|
||||||
radioStatus = TX;
|
radioStatus = TX;
|
||||||
|
|
||||||
mcp4551_setWiper(SOFTPOT_TX, mod17CalData.tx_wiper);
|
mcp4551_setWiper(&i2c1, SOFTPOT_TX, mod17CalData.tx_wiper);
|
||||||
mcp4551_setWiper(SOFTPOT_RX, mod17CalData.rx_wiper);
|
mcp4551_setWiper(&i2c1, SOFTPOT_RX, mod17CalData.rx_wiper);
|
||||||
max9814_setGain(mod17CalData.mic_gain);
|
max9814_setGain(mod17CalData.mic_gain);
|
||||||
|
|
||||||
if(mod17CalData.ptt_out_level)
|
if(mod17CalData.ptt_out_level)
|
||||||
|
|
|
@ -22,9 +22,12 @@
|
||||||
#ifndef HWCONFIG_H
|
#ifndef HWCONFIG_H
|
||||||
#define HWCONFIG_H
|
#define HWCONFIG_H
|
||||||
|
|
||||||
|
#include <peripherals/i2c.h>
|
||||||
#include <stm32f4xx.h>
|
#include <stm32f4xx.h>
|
||||||
#include "pinmap.h"
|
#include "pinmap.h"
|
||||||
|
|
||||||
|
extern const struct i2cDevice i2c1;
|
||||||
|
|
||||||
/* Screen dimensions */
|
/* Screen dimensions */
|
||||||
#define CONFIG_SCREEN_WIDTH 128
|
#define CONFIG_SCREEN_WIDTH 128
|
||||||
#define CONFIG_SCREEN_HEIGHT 64
|
#define CONFIG_SCREEN_HEIGHT 64
|
||||||
|
|
|
@ -61,9 +61,9 @@
|
||||||
#define POWER_SW GPIOA,15
|
#define POWER_SW GPIOA,15
|
||||||
|
|
||||||
/* I2C for MCP4551 */
|
/* I2C for MCP4551 */
|
||||||
#define I2C_SDA GPIOB,7
|
#define I2C1_SDA GPIOB,7
|
||||||
#define I2C_SCL GPIOB,6
|
#define I2C1_SCL GPIOB,6
|
||||||
#define SOFTPOT_RX 0x2E
|
#define SOFTPOT_RX 0x2E
|
||||||
#define SOFTPOT_TX 0x2F
|
#define SOFTPOT_TX 0x2F
|
||||||
|
|
||||||
#endif /* PINMAP_H */
|
#endif /* PINMAP_H */
|
||||||
|
|
|
@ -24,12 +24,16 @@
|
||||||
#include <interfaces/nvmem.h>
|
#include <interfaces/nvmem.h>
|
||||||
#include <interfaces/audio.h>
|
#include <interfaces/audio.h>
|
||||||
#include <peripherals/gpio.h>
|
#include <peripherals/gpio.h>
|
||||||
|
#include <drivers/i2c_stm32.h>
|
||||||
#include <calibInfo_Mod17.h>
|
#include <calibInfo_Mod17.h>
|
||||||
#include <ADC1_Mod17.h>
|
#include <ADC1_Mod17.h>
|
||||||
#include <backlight.h>
|
#include <backlight.h>
|
||||||
#include <hwconfig.h>
|
#include <hwconfig.h>
|
||||||
#include <MCP4551.h>
|
#include <MCP4551.h>
|
||||||
|
|
||||||
|
|
||||||
|
I2C_STM32_DEVICE_DEFINE(i2c1, I2C1, NULL)
|
||||||
|
|
||||||
extern mod17Calib_t mod17CalData;
|
extern mod17Calib_t mod17CalData;
|
||||||
|
|
||||||
static hwInfo_t hwInfo =
|
static hwInfo_t hwInfo =
|
||||||
|
@ -58,6 +62,32 @@ void platform_init()
|
||||||
gpio_setMode(PTT_OUT, OUTPUT);
|
gpio_setMode(PTT_OUT, OUTPUT);
|
||||||
gpio_clearPin(PTT_OUT);
|
gpio_clearPin(PTT_OUT);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if external I2C1 pull-ups are present. If they are not,
|
||||||
|
* enable internal pull-ups and slow-down I2C1.
|
||||||
|
*/
|
||||||
|
gpio_setMode(I2C1_SCL, INPUT_PULL_DOWN);
|
||||||
|
gpio_setMode(I2C1_SDA, INPUT_PULL_DOWN);
|
||||||
|
|
||||||
|
uint8_t i2cSpeed = I2C_SPEED_100kHz;
|
||||||
|
bool i2cPullups = gpio_readPin(I2C1_SCL)
|
||||||
|
& gpio_readPin(I2C1_SDA);
|
||||||
|
|
||||||
|
/* Set gpios to alternate function, connected to I2C peripheral */
|
||||||
|
if(i2cPullups == false)
|
||||||
|
{
|
||||||
|
gpio_setMode(I2C1_SCL, ALTERNATE_OD_PU | ALTERNATE_FUNC(4));
|
||||||
|
gpio_setMode(I2C1_SDA, ALTERNATE_OD_PU | ALTERNATE_FUNC(4));
|
||||||
|
i2cSpeed = I2C_SPEED_LOW;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gpio_setMode(I2C1_SCL, ALTERNATE_OD | ALTERNATE_FUNC(4));
|
||||||
|
gpio_setMode(I2C1_SDA, ALTERNATE_OD | ALTERNATE_FUNC(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c_init(&i2c1, i2cSpeed);
|
||||||
|
|
||||||
/* Set analog output for baseband signal to an idle level of 1.1V */
|
/* Set analog output for baseband signal to an idle level of 1.1V */
|
||||||
gpio_setMode(BASEBAND_TX, ANALOG);
|
gpio_setMode(BASEBAND_TX, ANALOG);
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
|
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
|
||||||
|
@ -66,10 +96,9 @@ void platform_init()
|
||||||
|
|
||||||
nvm_init();
|
nvm_init();
|
||||||
adc1_init();
|
adc1_init();
|
||||||
i2c_init();
|
|
||||||
mcp4551_init(SOFTPOT_RX);
|
|
||||||
mcp4551_init(SOFTPOT_TX);
|
|
||||||
audio_init();
|
audio_init();
|
||||||
|
mcp4551_init(&i2c1, SOFTPOT_RX);
|
||||||
|
mcp4551_init(&i2c1, SOFTPOT_TX);
|
||||||
|
|
||||||
/* Set defaults for calibration */
|
/* Set defaults for calibration */
|
||||||
mod17CalData.tx_wiper = 0x080;
|
mod17CalData.tx_wiper = 0x080;
|
||||||
|
|
Ładowanie…
Reference in New Issue