dect: com-on-air: device driver core
Add the chip-specific parts of the com-on-air driver. Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
parent
28c157ecb4
commit
dfdc90c521
|
@ -40,6 +40,8 @@ source "drivers/net/Kconfig"
|
|||
|
||||
source "drivers/isdn/Kconfig"
|
||||
|
||||
source "drivers/dect/Kconfig"
|
||||
|
||||
source "drivers/telephony/Kconfig"
|
||||
|
||||
# input before char - char/joystick depends on it. As does USB.
|
||||
|
|
|
@ -82,6 +82,7 @@ obj-$(CONFIG_MD) += md/
|
|||
obj-$(CONFIG_BT) += bluetooth/
|
||||
obj-$(CONFIG_ACCESSIBILITY) += accessibility/
|
||||
obj-$(CONFIG_ISDN) += isdn/
|
||||
obj-$(CONFIG_DECT) += dect/
|
||||
obj-$(CONFIG_EDAC) += edac/
|
||||
obj-$(CONFIG_MCA) += mca/
|
||||
obj-$(CONFIG_EISA) += eisa/
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
menuconfig DECTDEVICES
|
||||
bool "DECT device support"
|
||||
help
|
||||
Say Y here to show DECT device driver options.
|
||||
|
||||
if DECTDEVICES
|
||||
|
||||
source "drivers/dect/coa/Kconfig"
|
||||
|
||||
endif
|
|
@ -0,0 +1 @@
|
|||
obj-$(CONFIG_DECT_COA) += coa/
|
|
@ -0,0 +1,2 @@
|
|||
config DECT_COA
|
||||
tristate
|
|
@ -0,0 +1,3 @@
|
|||
com_on_air-objs := sc14421_firmware.o sc14421.o
|
||||
|
||||
obj-$(CONFIG_DECT_COA) += com_on_air.o
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* com_on_air - basic driver for the Dosch and Amand "com on air" cards
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* authors:
|
||||
* (C) 2008 Andreas Schuler <krater at badterrorist dot com>
|
||||
* (C) 2008 Matthias Wenzel <dect at mazzoo dot de>
|
||||
* (C) 2009 Patrick McHardy <kaber@trash.net>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COM_ON_AIR_H
|
||||
#define COM_ON_AIR_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct coa_freq_map_entry {
|
||||
struct {
|
||||
u8 divisor;
|
||||
u8 swcnt;
|
||||
} rx, tx;
|
||||
};
|
||||
|
||||
struct coa_freq_map {
|
||||
struct coa_freq_map_entry carrier[DECT_CARRIER_NUM];
|
||||
};
|
||||
|
||||
struct coa_device;
|
||||
struct coa_radio_ops {
|
||||
void (*rx_init)(const struct coa_device *dev, u16 offset);
|
||||
void (*tx_init)(const struct coa_device *dev, u16 offset);
|
||||
void (*set_carrier)(const struct coa_device *dev, u16 offset,
|
||||
enum dect_slot_states mode, u8 carrier);
|
||||
u64 (*map_band)(struct coa_device *dev,
|
||||
const struct dect_band *band);
|
||||
const char *type;
|
||||
};
|
||||
|
||||
enum coa_device_types {
|
||||
COA_TYPE_PCI,
|
||||
COA_TYPE_PCMCIA,
|
||||
};
|
||||
|
||||
struct coa_device {
|
||||
const struct device *dev;
|
||||
unsigned int irq;
|
||||
|
||||
enum coa_device_types type;
|
||||
|
||||
const struct coa_radio_ops *radio_ops;
|
||||
struct coa_freq_map freq_map;
|
||||
|
||||
uint config_base;
|
||||
u8 __iomem *sc14421_base;
|
||||
u16 cfg_reg;
|
||||
u16 irq_reg;
|
||||
u16 code_base;
|
||||
u16 data_base;
|
||||
u16 data_mask;
|
||||
|
||||
u8 ctrl;
|
||||
};
|
||||
|
||||
extern irqreturn_t sc14421_interrupt(int irq, void *dev_id);
|
||||
extern const struct dect_transceiver_ops sc14421_transceiver_ops;
|
||||
|
||||
extern int sc14421_init_device(struct coa_device *dev);
|
||||
extern void sc14421_shutdown_device(struct coa_device *dev);
|
||||
|
||||
extern void sc14421_rfdesc_write(const struct coa_device *dev, u16 offset,
|
||||
const u8 *src, u16 length);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* com_on_air - basic driver for the Dosch and Amand "com on air" cards
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* authors:
|
||||
* (C) 2008 Andreas Schuler <krater at badterrorist dot com>
|
||||
* (C) 2008 Matthias Wenzel <dect at mazzoo dot de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DIP_OPCODE_H
|
||||
#define DIP_OPCODE_H
|
||||
|
||||
#define BR 0x01
|
||||
#define JMP 0x02
|
||||
#define JMP1 0x03
|
||||
#define RTN 0x04
|
||||
#define BK_A1 0x05
|
||||
#define WNTM1 0x06
|
||||
#define WNTP1 0x07
|
||||
#define WNT 0x08
|
||||
#define WT 0x09
|
||||
#define RFDIS 0x0a
|
||||
#define RFEN 0x0b
|
||||
#define LD_PTR 0x0c
|
||||
#define SLOTZERO 0x0d
|
||||
#define BK_A 0x0e
|
||||
#define BK_C 0x0f
|
||||
|
||||
|
||||
#define B_RST 0x20
|
||||
#define B_ST2 0x21
|
||||
#define B_XT 0x24
|
||||
#define B_BT2 0x25
|
||||
#define B_BTFU 0x25
|
||||
#define B_XOFF 0x26
|
||||
#define B_ON 0x27
|
||||
#define B_XON 0x27
|
||||
#define UNLCK 0x28
|
||||
#define B_SR 0x29
|
||||
#define B_XR 0x2b
|
||||
#define EN_SL_ADJ 0x2c
|
||||
#define B_BR2 0x2d
|
||||
#define B_BRFU 0x2d
|
||||
#define B_RINV 0x2e
|
||||
#define B_RON 0x2f
|
||||
|
||||
|
||||
#define B_ST 0x31
|
||||
#define B_TX 0x31
|
||||
#define B_AT 0x32
|
||||
#define B_RC 0x33
|
||||
#define B_BT 0x34
|
||||
#define B_BTFP 0x35
|
||||
#define B_BTP 0x35
|
||||
#define B_AT2 0x37
|
||||
#define B_WRS 0x39
|
||||
#define B_AR 0x3a
|
||||
#define B_BR 0x3c
|
||||
#define B_BRP 0x3d
|
||||
#define B_BRFP 0x3d
|
||||
#define B_AR2 0x3f
|
||||
|
||||
|
||||
#define D_RST 0x40
|
||||
#define D_ON 0x42
|
||||
#define D_OFF 0x43
|
||||
#define D_PREP 0x44
|
||||
#define WSC 0x48
|
||||
|
||||
|
||||
#define D_LDK 0x50
|
||||
#define D_LDS 0x57
|
||||
#define D_WRS 0x5f
|
||||
|
||||
|
||||
#define U_PSC 0x60
|
||||
#define U_INT0 0x61
|
||||
#define RCK_INT 0x62
|
||||
#define RCK_EXT 0x63
|
||||
#define B_WB_OFF 0x64
|
||||
#define B_WB_ON 0x65
|
||||
#define CLK1 0x66
|
||||
#define CLK3 0x67
|
||||
#define U_CK8 0x68
|
||||
#define U_CK4 0x69
|
||||
#define U_CK2 0x6a
|
||||
#define U_INT1 0x6b
|
||||
#define U_CK1 0x6c
|
||||
#define U_INT2 0x6d
|
||||
#define U_INT3 0x6f
|
||||
|
||||
|
||||
#define A_RCV0 0x80
|
||||
#define A_RCV36 0x82
|
||||
#define A_RCV30 0x83
|
||||
#define A_RCV24 0x84
|
||||
#define A_RCV18 0x85
|
||||
#define A_RCV12 0x86
|
||||
#define A_RCV6 0x87
|
||||
#define A_RCV33 0x8a
|
||||
#define A_RCV27 0x8b
|
||||
#define A_RCV21 0x8c
|
||||
#define A_RCV15 0x8d
|
||||
#define A_RCV9 0x8e
|
||||
#define A_RCV3 0x8f
|
||||
|
||||
|
||||
#define MEN3N 0xa2
|
||||
#define MEN3 0xa3
|
||||
#define MEN1N 0xa4
|
||||
#define MEN1 0xa5
|
||||
#define MEN2N 0xa6
|
||||
#define MEN2 0xa7
|
||||
#define M_RD 0xa8
|
||||
#define M_RST 0xa9
|
||||
|
||||
|
||||
#define M_WRS 0xb8
|
||||
#define M_WR 0xb9
|
||||
|
||||
|
||||
#define A_RST 0xc0
|
||||
#define A_MUTE 0xc1
|
||||
#define A_STOFF 0xc2
|
||||
#define A_ALAW 0xc3
|
||||
#define A_DT 0xc4
|
||||
#define A_NORM 0xc5
|
||||
#define A_LDR 0xc6
|
||||
#define A_LDW 0xc7
|
||||
#define A_LIN 0xc8
|
||||
#define A_MTOFF 0xc9
|
||||
#define A_MUTE1 0xca
|
||||
#define A_MTOFF1 0xcb
|
||||
#define A_STON 0xcc
|
||||
#define A_DT1 0xcd
|
||||
#define A_LDR1 0xce
|
||||
#define A_LDW1 0xcf
|
||||
|
||||
|
||||
#define A_STRN 0xe0
|
||||
#define P_LD 0xe8
|
||||
#define P_EN 0xe9
|
||||
#define P_SC 0xea
|
||||
#define A_RST1 0xeb
|
||||
#define P_LDL 0xec
|
||||
#define P_LDH 0xed
|
||||
#define C_ON 0xee
|
||||
#define C_OFF 0xef
|
||||
|
||||
|
||||
#define C_LD 0xfa
|
||||
|
||||
#endif
|
|
@ -0,0 +1,724 @@
|
|||
/*
|
||||
* com_on_air - basic driver for the Dosch and Amand "com on air" cards
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* authors:
|
||||
* (C) 2008 Andreas Schuler <krater at badterrorist dot com>
|
||||
* (C) 2008 Matthias Wenzel <dect at mazzoo dot de>
|
||||
* (C) 2009 Patrick McHardy <kaber@trash.net>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/dect.h>
|
||||
#include <net/dect/dect.h>
|
||||
#include <net/dect/mac_csf.h>
|
||||
#include <net/dect/transceiver.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "com_on_air.h"
|
||||
#include "sc14421_firmware.h"
|
||||
#include "dip_opcodes.h"
|
||||
|
||||
/*
|
||||
* The com-on-air devices contain a 2k data RAM and 512b code RAM. The address
|
||||
* space is layed out as follows:
|
||||
*
|
||||
* PCI - size 8k:
|
||||
*
|
||||
* 0x0a00 - 0x11ff: data memory
|
||||
* 0x1a00 - 0x1bff: code memory
|
||||
* 0x1f00 - 0x1fff: DIP control and status registers
|
||||
*
|
||||
* PCMCIA - size 1k:
|
||||
*
|
||||
* 0x0000 - 0x01ff: 256 bytes memory
|
||||
* 0x0200 - 0x02ff: DIP control and status registers
|
||||
*
|
||||
* Memory of the PCMCIA device is addressed in 16 bit little endian quantities.
|
||||
* To access data or code memory, the corresponding bank needs to be mapped
|
||||
* into the memory window.
|
||||
*
|
||||
* The first bank of the data memory contains DIP specific control data,
|
||||
* the remaining banks are used to store packet and slot configuration data.
|
||||
*/
|
||||
|
||||
#define SC14421_DIPSTOPPED 0x80
|
||||
#define SC14421_RAMBANK0 0x00
|
||||
#define SC14421_RAMBANK1 0x04
|
||||
#define SC14421_RAMBANK2 0x08
|
||||
#define SC14421_RAMBANK3 0x0c
|
||||
#define SC14421_RAMBANK4 0x10
|
||||
#define SC14421_RAMBANK5 0x14
|
||||
#define SC14421_RAMBANK6 0x18
|
||||
#define SC14421_RAMBANK7 0x1c
|
||||
#define SC14421_CODEBANK 0x20
|
||||
#define SC14421_BANKSIZE 0x100
|
||||
|
||||
/* Interrupts 0-3 */
|
||||
#define SC14421_IRQ_SLOT_0_5 0x01
|
||||
#define SC14421_IRQ_SLOT_6_11 0x02
|
||||
#define SC14421_IRQ_SLOT_12_17 0x04
|
||||
#define SC14421_IRQ_SLOT_18_23 0x08
|
||||
#define SC14421_IRQ_MASK 0x0f
|
||||
|
||||
/*
|
||||
* Burst Mode Controller control information
|
||||
*/
|
||||
|
||||
/* Maximum number of unmasked errors in S-field bits 8 to 31 */
|
||||
#define SC14421_BC0_S_ERR_SHIFT 4
|
||||
/* Invert incoming data (RDI) */
|
||||
#define SC14421_BC0_INV_RDI 0x08
|
||||
/* Invert outgoing data (TDO) */
|
||||
#define SC14421_BC0_INV_TDO 0x04
|
||||
/* Disable writing B-field on A-field CRC error */
|
||||
#define SC14421_BC0_SENS_A 0x02
|
||||
/* PP/FP mode */
|
||||
#define SC14421_BC0_PP_MODE 0x01
|
||||
|
||||
/* Error test mask for S-field bits 15-8 */
|
||||
#define SC14421_BC1_MASK_MASK 0xff
|
||||
|
||||
/* Sliding error test mask for S-field bits 15-8 */
|
||||
#define SC14421_BC2_SLIDE_MASK 0xff
|
||||
|
||||
/* DAC output value when BCM is active (for frequency control?) */
|
||||
#define SC14421_BC3_DAC_MASK 0x1f
|
||||
|
||||
/* Only perform phase jump for correct A-field CRC + SL_EN_ADJ command */
|
||||
#define SC14421_BC4_ADP 0x10
|
||||
/* Window in which S-field is accepted */
|
||||
#define SC14421_BC4_WIN_MASK 0x0f
|
||||
|
||||
/* Amplitude-trimming of gaussian shape */
|
||||
#define SC14421_BC5_VOL_SHIFT 4
|
||||
/* Disable scrambling */
|
||||
#define SC14421_BC5_SC_OFF 0x08
|
||||
/* PD1 synchronization pattern:
|
||||
* 0 = S-field received, 1 = preamble + first 2 bits of synchronization word */
|
||||
#define SC14421_BC5_DO_FR 0x04
|
||||
/* TDO output shape */
|
||||
#define SC14421_BC5_TDO_DIGITAL 0x00
|
||||
#define SC14421_BC5_TDO_GAUSIAN 0x01
|
||||
#define SC14421_BC5_TDO_POWER_DOWN 0x02
|
||||
#define SC14421_BC5_TDO_MID_LEVEL 0x03
|
||||
|
||||
/* Low 4 bits of multiframe number */
|
||||
#define SC14421_BC6_MFR_SHIFT 4
|
||||
#define SC14421_BC6_MFR_MASK 0xf0
|
||||
/* Frame number */
|
||||
#define SC14421_BC6_FR_MASK 0x0f
|
||||
|
||||
/*
|
||||
* Burst Mode Controller status information
|
||||
*/
|
||||
|
||||
/* Peak binary value of ADC (RSSI) */
|
||||
#define SC14421_ST0_ADC_MASK 0x3f
|
||||
|
||||
/* S-pattern recognized according to BMC configuration */
|
||||
#define SC14421_ST1_IN_SYNC 0x80
|
||||
|
||||
/* A-field R-CRC correct */
|
||||
#define SC14421_ST1_A_CRC 0x40
|
||||
|
||||
/* Protected Bn-subfield R-CRC correct */
|
||||
#define SC14421_ST1_B_CRC_MASK 0x3c
|
||||
#define SC14421_ST1_B1_CRC 0x20
|
||||
#define SC14421_ST1_B2_CRC 0x10
|
||||
#define SC14421_ST1_B3_CRC 0x08
|
||||
#define SC14421_ST1_B4_CRC 0x04
|
||||
|
||||
/* B-field X-CRC correct */
|
||||
#define SC14421_ST1_X_CRC 0x02
|
||||
|
||||
/* Z-field equals X-CRC */
|
||||
#define SC14421_ST1_Z_CRC 0x01
|
||||
|
||||
/* Phase offset of received S-field: which of the nine internal clock cycles
|
||||
* per symbol sampled the incoming data. The frequency deviation can be
|
||||
* calculated from the difference of the offsets of two consequitive frames as:
|
||||
*
|
||||
* K * (T / 9) / 10m = K * 96ns / 10m = K * 9.6ppm
|
||||
*/
|
||||
#define SC14421_ST2_TAP_SHIFT 4
|
||||
#define SC14421_ST2_TAP_MASK 0xf0
|
||||
|
||||
/* Number of unmasked S-field errors according to BMC configuration */
|
||||
#define SC14421_ST2_S_ERR_SHIFT 0
|
||||
#define SC14421_ST2_S_ERR_MASK 0x0f
|
||||
|
||||
/* Phase offset of received S-field. */
|
||||
#define SC14421_ST3_PHASE_MASK 0xff
|
||||
|
||||
/* DC offset of received data to comparator reference input (DAC) */
|
||||
#define SC14421_ST4_DC_MASK 0x3f
|
||||
|
||||
|
||||
static const u8 banktable[] = {
|
||||
SC14421_RAMBANK1, 0,
|
||||
SC14421_RAMBANK1, 0,
|
||||
SC14421_RAMBANK2, 0,
|
||||
SC14421_RAMBANK2, 0,
|
||||
SC14421_RAMBANK3, 0,
|
||||
SC14421_RAMBANK3, 0,
|
||||
SC14421_RAMBANK4, 0,
|
||||
SC14421_RAMBANK4, 0,
|
||||
SC14421_RAMBANK5, 0,
|
||||
SC14421_RAMBANK5, 0,
|
||||
SC14421_RAMBANK6, 0,
|
||||
SC14421_RAMBANK6, 0,
|
||||
};
|
||||
|
||||
static const u8 jumptable[] = {
|
||||
JP0, 0,
|
||||
JP2, 0,
|
||||
JP4, 0,
|
||||
JP6, 0,
|
||||
JP8, 0,
|
||||
JP10, 0,
|
||||
JP12, 0,
|
||||
JP14, 0,
|
||||
JP16, 0,
|
||||
JP18, 0,
|
||||
JP20, 0,
|
||||
JP22, 0
|
||||
};
|
||||
|
||||
static const u8 patchtable[] = {
|
||||
PP0, 0,
|
||||
PP2, 0,
|
||||
PP4, 0,
|
||||
PP6, 0,
|
||||
PP8, 0,
|
||||
PP10, 0,
|
||||
PP12, 0,
|
||||
PP14, 0,
|
||||
PP16, 0,
|
||||
PP18, 0,
|
||||
PP20, 0,
|
||||
PP22, 0
|
||||
};
|
||||
|
||||
static const u8 sc14421_rx_funcs[DECT_PACKET_MAX + 1][DECT_B_MAX + 1] = {
|
||||
[DECT_PACKET_P00][DECT_B_NONE] = RecvP32U,
|
||||
[DECT_PACKET_P32][DECT_B_UNPROTECTED] = RecvP32U,
|
||||
[DECT_PACKET_P32][DECT_B_PROTECTED] = RecvP32P,
|
||||
};
|
||||
|
||||
static const u8 sc14421_tx_funcs[DECT_PACKET_MAX + 1][DECT_B_MAX + 1] = {
|
||||
[DECT_PACKET_P00][DECT_B_NONE] = TransmitP00,
|
||||
[DECT_PACKET_P32][DECT_B_UNPROTECTED] = TransmitP32U,
|
||||
[DECT_PACKET_P32][DECT_B_PROTECTED] = TransmitP32P,
|
||||
};
|
||||
|
||||
/*
|
||||
* Raw IO functions
|
||||
*/
|
||||
static u8 sc14421_read(const struct coa_device *dev, u16 offset)
|
||||
{
|
||||
switch (dev->type) {
|
||||
case COA_TYPE_PCI:
|
||||
return readb(dev->sc14421_base + offset);
|
||||
case COA_TYPE_PCMCIA:
|
||||
return le16_to_cpu(readw(dev->sc14421_base + 2 * offset));
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static void sc14421_write(const struct coa_device *dev, u16 offset, u8 value)
|
||||
{
|
||||
switch (dev->type) {
|
||||
case COA_TYPE_PCI:
|
||||
writeb(value, dev->sc14421_base + offset);
|
||||
break;
|
||||
case COA_TYPE_PCMCIA:
|
||||
writew(cpu_to_le16(value), dev->sc14421_base + 2 * offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sc14421_stop_dip(struct coa_device *dev)
|
||||
{
|
||||
/* Prevent the interrupt handler from restarting the DIP */
|
||||
dev->ctrl = SC14421_DIPSTOPPED;
|
||||
|
||||
/* Stop the DIP and wait for interrupt handler to complete */
|
||||
sc14421_write(dev, dev->cfg_reg, SC14421_DIPSTOPPED);
|
||||
synchronize_irq(dev->irq);
|
||||
}
|
||||
|
||||
static void sc14421_start_dip(struct coa_device *dev)
|
||||
{
|
||||
dev->ctrl = 0;
|
||||
sc14421_write(dev, dev->cfg_reg, 0x00);
|
||||
}
|
||||
|
||||
static void sc14421_switch_to_bank(const struct coa_device *dev, u8 bank)
|
||||
{
|
||||
if (dev->type != COA_TYPE_PCMCIA)
|
||||
return;
|
||||
sc14421_write(dev, dev->cfg_reg, bank | dev->ctrl);
|
||||
/* need to wait for 4 IO cycles */
|
||||
inb_p(dev->config_base);
|
||||
inb_p(dev->config_base);
|
||||
inb_p(dev->config_base);
|
||||
inb_p(dev->config_base);
|
||||
}
|
||||
|
||||
/*
|
||||
* Code memory IO functions
|
||||
*/
|
||||
static void sc14421_write_cmd(const struct coa_device *dev, u16 label,
|
||||
u8 opcode, u8 operand)
|
||||
{
|
||||
sc14421_write(dev, dev->code_base + 2 * label + 0, opcode);
|
||||
sc14421_write(dev, dev->code_base + 2 * label + 1, operand);
|
||||
}
|
||||
|
||||
static void sc14421_to_cmem(const struct coa_device *dev,
|
||||
const u8 *src, u16 length)
|
||||
{
|
||||
u16 i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
sc14421_write(dev, dev->code_base + i, src[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Data memory IO functions
|
||||
*/
|
||||
static inline u8 sc14421_dread(const struct coa_device *dev, u16 offset)
|
||||
{
|
||||
return sc14421_read(dev, dev->data_base + (offset & dev->data_mask));
|
||||
}
|
||||
|
||||
static inline void sc14421_dwrite(const struct coa_device *dev,
|
||||
u16 offset, u8 value)
|
||||
{
|
||||
sc14421_write(dev, dev->data_base + (offset & dev->data_mask), value);
|
||||
}
|
||||
|
||||
static void sc14421_to_dmem(const struct coa_device *dev, u16 offset,
|
||||
const u8 *src, u16 length)
|
||||
{
|
||||
u16 i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
sc14421_dwrite(dev, offset + i, src[i]);
|
||||
}
|
||||
|
||||
static void sc14421_from_dmem(const struct coa_device *dev, u8 *dst,
|
||||
u16 offset, u16 length)
|
||||
{
|
||||
u16 i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
dst[i] = sc14421_dread(dev, offset + i);
|
||||
}
|
||||
|
||||
static u16 sc14421_slot_offset(u8 slot)
|
||||
{
|
||||
u16 offset;
|
||||
|
||||
offset = SC14421_BANKSIZE + slot / 4 * SC14421_BANKSIZE;
|
||||
if (slot & 0x2)
|
||||
offset += SC14421_BANKSIZE / 2;
|
||||
return offset;
|
||||
}
|
||||
|
||||
void sc14421_rfdesc_write(const struct coa_device *dev, u16 offset,
|
||||
const u8 *src, u16 length)
|
||||
{
|
||||
sc14421_to_dmem(dev, offset + RF_DESC, src, length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Transceiver operations
|
||||
*/
|
||||
|
||||
static void sc14421_disable(const struct dect_transceiver *trx)
|
||||
{
|
||||
sc14421_stop_dip(dect_transceiver_priv(trx));
|
||||
}
|
||||
|
||||
static void sc14421_enable(const struct dect_transceiver *trx)
|
||||
{
|
||||
const struct coa_device *dev = dect_transceiver_priv(trx);
|
||||
u8 slot;
|
||||
|
||||
/* Restore slot table to a pristine state */
|
||||
sc14421_switch_to_bank(dev, SC14421_CODEBANK);
|
||||
for (slot = 0; slot < DECT_FRAME_SIZE; slot += 2)
|
||||
sc14421_write_cmd(dev, patchtable[slot], WNT, 2);
|
||||
|
||||
if (trx->mode == DECT_TRANSCEIVER_MASTER)
|
||||
sc14421_write_cmd(dev, RFStart, BR, SlotTable);
|
||||
else {
|
||||
sc14421_write_cmd(dev, RFStart, BR, SyncInit);
|
||||
sc14421_write_cmd(dev, SyncLoop, BR, Sync);
|
||||
}
|
||||
|
||||
sc14421_start_dip(dect_transceiver_priv(trx));
|
||||
}
|
||||
|
||||
static void sc14421_confirm(const struct dect_transceiver *trx)
|
||||
{
|
||||
const struct coa_device *dev = dect_transceiver_priv(trx);
|
||||
|
||||
/*
|
||||
* This locks the firmware into a cycle where it will receive every
|
||||
* 24th slot. This must happen within the time it takes to transmit
|
||||
* 22 slots after the interrupt to lock to the correct signal.
|
||||
*/
|
||||
sc14421_switch_to_bank(dev, SC14421_CODEBANK);
|
||||
sc14421_write_cmd(dev, SyncLoop, BR, SyncLock);
|
||||
}
|
||||
|
||||
static void sc14421_unlock(const struct dect_transceiver *trx)
|
||||
{
|
||||
const struct coa_device *dev = dect_transceiver_priv(trx);
|
||||
|
||||
/* Restore jump into Sync loop */
|
||||
sc14421_switch_to_bank(dev, SC14421_CODEBANK);
|
||||
sc14421_write_cmd(dev, SyncLoop, BR, Sync);
|
||||
}
|
||||
|
||||
static void sc14421_lock(const struct dect_transceiver *trx, u8 slot)
|
||||
{
|
||||
const struct coa_device *dev = dect_transceiver_priv(trx);
|
||||
|
||||
/*
|
||||
* We're receiving the single slot "slot". Adjust the firmware so it
|
||||
* will jump into the correct slottable position on the next receive
|
||||
* event. This will automagically establish the correct slot numbers
|
||||
* and thereby interrupt timing for all slots.
|
||||
*/
|
||||
sc14421_switch_to_bank(dev, SC14421_CODEBANK);
|
||||
sc14421_write_cmd(dev, SyncLoop, BR, jumptable[slot]);
|
||||
}
|
||||
|
||||
static void sc14421_set_mode(const struct dect_transceiver *trx,
|
||||
const struct dect_channel_desc *chd,
|
||||
enum dect_slot_states mode)
|
||||
{
|
||||
const struct coa_device *dev = dect_transceiver_priv(trx);
|
||||
u8 slot = chd->slot;
|
||||
u16 off;
|
||||
|
||||
switch (mode) {
|
||||
case DECT_SLOT_IDLE:
|
||||
sc14421_switch_to_bank(dev, SC14421_CODEBANK);
|
||||
sc14421_write_cmd(dev, patchtable[slot], WNT, 2);
|
||||
break;
|
||||
case DECT_SLOT_SCANNING:
|
||||
case DECT_SLOT_RX:
|
||||
sc14421_switch_to_bank(dev, banktable[slot]);
|
||||
off = sc14421_slot_offset(slot);
|
||||
dev->radio_ops->rx_init(dev, off);
|
||||
|
||||
sc14421_switch_to_bank(dev, SC14421_CODEBANK);
|
||||
sc14421_write_cmd(dev, patchtable[slot], JMP,
|
||||
sc14421_rx_funcs[chd->pkt][chd->b_fmt]);
|
||||
break;
|
||||
case DECT_SLOT_TX:
|
||||
sc14421_switch_to_bank(dev, banktable[slot]);
|
||||
off = sc14421_slot_offset(slot);
|
||||
dev->radio_ops->tx_init(dev, off);
|
||||
|
||||
sc14421_switch_to_bank(dev, SC14421_CODEBANK);
|
||||
sc14421_write_cmd(dev, patchtable[slot], JMP,
|
||||
sc14421_tx_funcs[chd->pkt][chd->b_fmt]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sc14421_set_carrier(const struct dect_transceiver *trx,
|
||||
u8 slot, u8 carrier)
|
||||
{
|
||||
const struct coa_device *dev = dect_transceiver_priv(trx);
|
||||
const struct dect_transceiver_slot *ts = &trx->slots[slot];
|
||||
u16 off;
|
||||
|
||||
WARN_ON(ts->state == DECT_SLOT_IDLE);
|
||||
|
||||
sc14421_switch_to_bank(dev, banktable[slot]);
|
||||
off = sc14421_slot_offset(slot);
|
||||
dev->radio_ops->set_carrier(dev, off, ts->state, carrier);
|
||||
}
|
||||
|
||||
static u64 sc14421_set_band(const struct dect_transceiver *trx,
|
||||
const struct dect_band *band)
|
||||
{
|
||||
struct coa_device *dev = dect_transceiver_priv(trx);
|
||||
|
||||
return dev->radio_ops->map_band(dev, band);
|
||||
}
|
||||
|
||||
static void sc14421_tx(const struct dect_transceiver *trx, struct sk_buff *skb)
|
||||
{
|
||||
const struct coa_device *dev = dect_transceiver_priv(trx);
|
||||
u8 slot = DECT_TRX_CB(skb)->slot;
|
||||
u16 off;
|
||||
|
||||
sc14421_switch_to_bank(dev, banktable[slot]);
|
||||
off = sc14421_slot_offset(slot);
|
||||
|
||||
sc14421_to_dmem(dev, off + SD_PREAMBLE_OFF,
|
||||
skb_mac_header(skb), skb->mac_len);
|
||||
sc14421_to_dmem(dev, off + SD_DATA_OFF, skb->data, skb->len);
|
||||
sc14421_dwrite(dev, off + TX_DESC + TRX_DESC_FN,
|
||||
DECT_TRX_CB(skb)->frame);
|
||||
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
const struct dect_transceiver_ops sc14421_transceiver_ops = {
|
||||
.name = "sc14421",
|
||||
.slotmask = 0x555555,
|
||||
.eventrate = 6,
|
||||
.latency = 6,
|
||||
.disable = sc14421_disable,
|
||||
.enable = sc14421_enable,
|
||||
.confirm = sc14421_confirm,
|
||||
.unlock = sc14421_unlock,
|
||||
.lock = sc14421_lock,
|
||||
.set_mode = sc14421_set_mode,
|
||||
.set_carrier = sc14421_set_carrier,
|
||||
.set_band = sc14421_set_band,
|
||||
.tx = sc14421_tx,
|
||||
.destructor = dect_transceiver_free,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(sc14421_transceiver_ops);
|
||||
|
||||
static u8 sc14421_clear_interrupt(const struct coa_device *dev)
|
||||
{
|
||||
u8 int1, int2, cnt = 0;
|
||||
|
||||
int1 = sc14421_read(dev, dev->cfg_reg);
|
||||
/* is the card still plugged? */
|
||||
if (int1 == 0xff)
|
||||
return 0;
|
||||
|
||||
int2 = int1 & SC14421_IRQ_MASK;
|
||||
|
||||
/* Clear interrupt status before checking for any remaining events */
|
||||
if (int2 && dev->type == COA_TYPE_PCI)
|
||||
sc14421_write(dev, 0x1f02, 0x80);
|
||||
|
||||
while (int1) {
|
||||
cnt++;
|
||||
if (cnt > 254) {
|
||||
int2 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
int1 = sc14421_read(dev, dev->cfg_reg) & SC14421_IRQ_MASK;
|
||||
int2 |= int1;
|
||||
}
|
||||
|
||||
return int2 & SC14421_IRQ_MASK;
|
||||
}
|
||||
|
||||
static void sc14421_process_slot(const struct coa_device *dev,
|
||||
struct dect_transceiver *trx,
|
||||
struct dect_transceiver_event *event,
|
||||
u8 slot)
|
||||
{
|
||||
struct dect_transceiver_slot *ts = &trx->slots[slot];
|
||||
struct sk_buff *skb;
|
||||
u16 off;
|
||||
u8 rssi;
|
||||
|
||||
if (ts->state == DECT_SLOT_IDLE || ts->state == DECT_SLOT_TX)
|
||||
return;
|
||||
|
||||
sc14421_switch_to_bank(dev, banktable[slot]);
|
||||
off = sc14421_slot_offset(slot);
|
||||
|
||||
/*
|
||||
* The SC14421 contains a 6 bit ADC for RSSI measurement, convert to
|
||||
* units used by the stack.
|
||||
*/
|
||||
rssi = sc14421_dread(dev, off + SD_RSSI_OFF) * DECT_RSSI_RANGE / 63;
|
||||
|
||||
/* validate and clear checksum */
|
||||
if ((sc14421_dread(dev, off + SD_CSUM_OFF) & 0xc0) != 0xc0)
|
||||
goto out;
|
||||
sc14421_dwrite(dev, off + SD_CSUM_OFF, 0);
|
||||
|
||||
skb = dect_transceiver_alloc_skb(trx, slot);
|
||||
if (skb == NULL)
|
||||
goto out;
|
||||
sc14421_from_dmem(dev, skb->data, off + SD_DATA_OFF, skb->len);
|
||||
DECT_TRX_CB(skb)->rssi = rssi;
|
||||
__skb_queue_tail(&event->rx_queue, skb);
|
||||
|
||||
ts->rx_bytes += skb->len;
|
||||
ts->rx_packets++;
|
||||
out:
|
||||
ts->rssi = dect_average_rssi(ts->rssi, rssi);
|
||||
dect_transceiver_record_rssi(event, slot, rssi);
|
||||
|
||||
/* Update frame number for next reception */
|
||||
sc14421_dwrite(dev, off + RX_DESC + TRX_DESC_FN,
|
||||
dect_next_framenum(trx->cell->timer_base[DECT_TIMER_RX].framenum));
|
||||
}
|
||||
|
||||
irqreturn_t sc14421_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct dect_transceiver *trx = dev_id;
|
||||
struct coa_device *dev = dect_transceiver_priv(trx);
|
||||
struct dect_transceiver_event *event;
|
||||
u8 slot, i;
|
||||
|
||||
irq = sc14421_clear_interrupt(dev);
|
||||
if (!irq)
|
||||
return IRQ_NONE;
|
||||
|
||||
if (unlikely(hweight8(irq) != 1))
|
||||
dev_info(dev->dev, "lost some interrupts\n");
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (!(irq & (1 << i)))
|
||||
continue;
|
||||
|
||||
event = dect_transceiver_event(trx, i % 2, i * 6);
|
||||
if (event == NULL)
|
||||
goto out;
|
||||
|
||||
for (slot = 6 * i; slot < 6 * (i + 1); slot += 2)
|
||||
sc14421_process_slot(dev, trx, event, slot);
|
||||
|
||||
dect_transceiver_queue_event(trx, event);
|
||||
}
|
||||
out:
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sc14421_interrupt);
|
||||
|
||||
static void sc14421_write_bmc_config(const struct coa_device *dev,
|
||||
u16 off, bool pp, bool tx)
|
||||
{
|
||||
u8 cfg;
|
||||
|
||||
cfg = 2 << SC14421_BC0_S_ERR_SHIFT;
|
||||
cfg |= SC14421_BC0_INV_TDO;
|
||||
cfg |= SC14421_BC0_SENS_A;
|
||||
if (pp && !tx)
|
||||
cfg |= SC14421_BC0_PP_MODE;
|
||||
sc14421_dwrite(dev, off + 0, cfg);
|
||||
|
||||
/* S-field error mask */
|
||||
sc14421_dwrite(dev, off + 1, 0);
|
||||
/* S-field sliding window error mask */
|
||||
sc14421_dwrite(dev, off + 2, 0x3f);
|
||||
|
||||
/* DAC output */
|
||||
sc14421_dwrite(dev, off + 3, 0);
|
||||
|
||||
cfg = SC14421_BC4_ADP;
|
||||
cfg |= 0xf;
|
||||
cfg |= 0x80;
|
||||
sc14421_dwrite(dev, off + 4, cfg);
|
||||
|
||||
cfg = SC14421_BC5_DO_FR;
|
||||
cfg |= tx ? SC14421_BC5_TDO_DIGITAL : SC14421_BC5_TDO_POWER_DOWN;
|
||||
sc14421_dwrite(dev, off + 5, cfg);
|
||||
|
||||
/* Frame number */
|
||||
sc14421_dwrite(dev, off + 6, 0);
|
||||
}
|
||||
|
||||
static void sc14421_init_slot(const struct coa_device *dev, u8 slot)
|
||||
{
|
||||
u16 off;
|
||||
|
||||
sc14421_switch_to_bank(dev, banktable[slot]);
|
||||
off = sc14421_slot_offset(slot);
|
||||
sc14421_write_bmc_config(dev, off + TX_DESC, slot < 12, true);
|
||||
sc14421_write_bmc_config(dev, off + RX_DESC, slot < 12, false);
|
||||
dev->radio_ops->rx_init(dev, off);
|
||||
}
|
||||
|
||||
static int sc14421_check_dram(const struct coa_device *dev)
|
||||
{
|
||||
unsigned int bank, i;
|
||||
unsigned int cnt;
|
||||
u16 off;
|
||||
u8 val;
|
||||
|
||||
for (bank = 0; bank < 8; bank++) {
|
||||
sc14421_switch_to_bank(dev, 4 * bank);
|
||||
|
||||
off = bank * SC14421_BANKSIZE;
|
||||
for (i = 0; i < SC14421_BANKSIZE - 2; i++)
|
||||
sc14421_dwrite(dev, off + i, bank + i);
|
||||
}
|
||||
|
||||
cnt = 0;
|
||||
for (bank = 0; bank < 8; bank++) {
|
||||
sc14421_switch_to_bank(dev, 4 * bank);
|
||||
|
||||
off = bank * SC14421_BANKSIZE;
|
||||
for (i = 0; i < SC14421_BANKSIZE - 2; i++) {
|
||||
val = sc14421_dread(dev, off + i);
|
||||
if (val != ((bank + i) & 0xff)) {
|
||||
dev_err(dev->dev,
|
||||
"memory error bank %.2x offset %.2x: "
|
||||
"%.2x != %.2x\n", bank, i,
|
||||
val, (bank + i) & 0xff);
|
||||
cnt++;
|
||||
}
|
||||
sc14421_dwrite(dev, off + i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt > 0)
|
||||
dev_err(dev->dev, "found %u memory r/w errors\n", cnt);
|
||||
return cnt ? -1 : 0;
|
||||
}
|
||||
|
||||
int sc14421_init_device(struct coa_device *dev)
|
||||
{
|
||||
u8 slot;
|
||||
|
||||
dev->ctrl = SC14421_DIPSTOPPED;
|
||||
|
||||
if (sc14421_check_dram(dev) < 0)
|
||||
return -EIO;
|
||||
|
||||
dev_info(dev->dev, "Loading firmware ...\n");
|
||||
sc14421_switch_to_bank(dev, SC14421_CODEBANK);
|
||||
sc14421_to_cmem(dev, sc14421_firmware, sizeof(sc14421_firmware));
|
||||
|
||||
sc14421_clear_interrupt(dev);
|
||||
|
||||
/* Init DIP */
|
||||
sc14421_switch_to_bank(dev, SC14421_RAMBANK0);
|
||||
sc14421_write_bmc_config(dev, DIP_RF_INIT, false, false);
|
||||
for (slot = 0; slot < DECT_FRAME_SIZE; slot += 2)
|
||||
sc14421_init_slot(dev, slot);
|
||||
|
||||
/* Enable interrupts */
|
||||
if (dev->type == COA_TYPE_PCI)
|
||||
sc14421_write(dev, 0x1f06, 0x70);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sc14421_init_device);
|
||||
|
||||
void sc14421_shutdown_device(struct coa_device *dev)
|
||||
{
|
||||
sc14421_stop_dip(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sc14421_shutdown_device);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* automatically generated file
|
||||
* DO NOT EDIT
|
||||
* edit firmware/filename.asm instead
|
||||
*/
|
||||
|
||||
#include "sc14421_firmware.h"
|
||||
|
||||
const unsigned char sc14421_firmware[] = {
|
||||
0x01, 0x01, 0x01, 0xc3, 0x0d, 0x00, 0x0f, 0x20,
|
||||
0x08, 0x02, 0x0f, 0x30, 0x08, 0x02, 0x0f, 0x40,
|
||||
0x08, 0x02, 0x61, 0x00, 0x0f, 0x50, 0x08, 0x02,
|
||||
0x0f, 0x60, 0x08, 0x02, 0x0f, 0x70, 0x08, 0x02,
|
||||
0x6b, 0x00, 0x0f, 0x80, 0x08, 0x02, 0x0f, 0x90,
|
||||
0x08, 0x02, 0x0f, 0xa0, 0x08, 0x02, 0x6d, 0x00,
|
||||
0x0f, 0xb0, 0x08, 0x02, 0x0f, 0xc0, 0x08, 0x02,
|
||||
0x0f, 0xd0, 0x08, 0x02, 0x6f, 0x00, 0x01, 0x02,
|
||||
0x02, 0x86, 0x02, 0x40, 0x09, 0x01, 0x2d, 0x0e,
|
||||
0x02, 0x50, 0x01, 0x36, 0x02, 0x86, 0x02, 0x40,
|
||||
0x01, 0x75, 0x02, 0x86, 0x02, 0x55, 0x02, 0x64,
|
||||
0x01, 0x38, 0x02, 0x86, 0x02, 0x55, 0x09, 0x01,
|
||||
0x25, 0x0e, 0x02, 0x61, 0x01, 0x39, 0x02, 0x86,
|
||||
0x02, 0x55, 0x01, 0x7e, 0x39, 0x00, 0x09, 0x06,
|
||||
0x20, 0x00, 0xec, 0x50, 0x09, 0x05, 0x08, 0x01,
|
||||
0x04, 0x00, 0x20, 0x00, 0xec, 0x50, 0x04, 0x00,
|
||||
0xed, 0x40, 0xec, 0x01, 0x09, 0x19, 0x08, 0x01,
|
||||
0x09, 0x09, 0x27, 0x00, 0xed, 0x02, 0x09, 0x05,
|
||||
0x29, 0x00, 0x2c, 0x00, 0x09, 0x0c, 0xec, 0x02,
|
||||
0x09, 0x21, 0x3f, 0x06, 0x09, 0x3d, 0x04, 0x00,
|
||||
0x09, 0xf9, 0x09, 0x4f, 0xed, 0x01, 0xec, 0x40,
|
||||
0x04, 0x00, 0xed, 0x00, 0x09, 0x28, 0x20, 0x00,
|
||||
0x33, 0x50, 0x08, 0x01, 0x31, 0x00, 0x09, 0x01,
|
||||
0xed, 0x10, 0x09, 0x25, 0x37, 0x06, 0x09, 0x3d,
|
||||
0x04, 0x00, 0x09, 0xf9, 0x09, 0x54, 0x20, 0x00,
|
||||
0xec, 0x10, 0x09, 0x08, 0xec, 0x00, 0x04, 0x00,
|
||||
0x27, 0x00, 0x09, 0x0f, 0x26, 0x00, 0x09, 0x3d,
|
||||
0x04, 0x00, 0x09, 0x3d, 0x02, 0x68, 0x02, 0x68,
|
||||
0x02, 0x68, 0x09, 0x01, 0x27, 0x00, 0x09, 0x0b,
|
||||
0x04, 0x00, 0x3d, 0x0e, 0x02, 0x6d, 0x09, 0x03,
|
||||
0x2b, 0x00, 0x09, 0x06, 0x02, 0x52, 0x39, 0x00,
|
||||
0x09, 0x06, 0x01, 0x3d, 0x35, 0x0e, 0x02, 0x6d,
|
||||
0x09, 0x03, 0x24, 0x00, 0x09, 0x0d, 0x20, 0x00,
|
||||
0x02, 0x64, 0x01, 0x3d, 0x0b, 0x00, 0x09, 0x02,
|
||||
0xa4, 0x00, 0xb9, 0x4a, 0x09, 0x19, 0xa9, 0x00,
|
||||
0xa5, 0x00, 0xa4, 0x00, 0xb9, 0x4d, 0x09, 0x0a,
|
||||
0xa9, 0x00, 0xa5, 0x00, 0x09, 0x01, 0xec, 0x20,
|
||||
0x20, 0x00, 0x33, 0x58, 0x09, 0x08, 0xa7, 0x00,
|
||||
0x09, 0xb6, 0xa6, 0x00, 0xed, 0x00, 0x09, 0x10,
|
||||
0x04, 0x00, 0x50, 0x58, 0x09, 0x10, 0x50, 0x00,
|
||||
0x44, 0x00, 0x09, 0x27, 0x44, 0x00, 0x04, 0x00,
|
||||
0x5f, 0x00, 0x09, 0x0a, 0x5f, 0x00, 0x40, 0x00,
|
||||
0x04, 0x00, 0x57, 0x00, 0x09, 0x0a, 0x57, 0x00,
|
||||
0x04, 0x00, 0x40, 0x00, 0x0f, 0x20, 0x02, 0x86,
|
||||
0x09, 0xfa, 0xea, 0x20, 0xed, 0x42, 0x28, 0x00,
|
||||
0x09, 0x40, 0x26, 0x00, 0x29, 0x00, 0x08, 0x14,
|
||||
0x03, 0xbd, 0x20, 0x00, 0x6b, 0x00, 0x08, 0x17,
|
||||
0x01, 0xaf, 0x08, 0x17, 0xea, 0x00, 0x02, 0x20,
|
||||
0x61, 0x00, 0x08, 0x16, 0x01, 0xaf, 0x20, 0x00,
|
||||
0x0f, 0x00, 0x33, 0x00, 0x09, 0x08, 0x20, 0x00,
|
||||
0x09, 0x0a, 0xe9, 0x00, 0xe8, 0x04, 0x62, 0x00,
|
||||
0x0b, 0x00, 0x01, 0xae, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff};
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef SC14421_FIRMWARE
|
||||
#define SC14421_FIRMWARE
|
||||
|
||||
extern const unsigned char sc14421_firmware[509];
|
||||
|
||||
#define DIP_RF_INIT 0x0
|
||||
#define RF_DESC 0x4A
|
||||
#define RX_DESC 0x58
|
||||
#define TX_DESC 0x50
|
||||
#define TRX_DESC_FN 0x6
|
||||
#define SD_RSSI_OFF 0x0
|
||||
#define SD_CSUM_OFF 0x1
|
||||
#define SD_PREAMBLE_OFF 0x1
|
||||
#define SD_DATA_OFF 0x6
|
||||
#define PP0 0x4
|
||||
#define PP2 0x6
|
||||
#define PP4 0x8
|
||||
#define PP6 0xB
|
||||
#define PP8 0xD
|
||||
#define PP10 0xF
|
||||
#define PP12 0x12
|
||||
#define PP14 0x14
|
||||
#define PP16 0x16
|
||||
#define PP18 0x19
|
||||
#define PP20 0x1B
|
||||
#define PP22 0x1D
|
||||
#define JP0 0x3
|
||||
#define JP2 0x5
|
||||
#define JP4 0x7
|
||||
#define JP6 0xA
|
||||
#define JP8 0xC
|
||||
#define JP10 0xE
|
||||
#define JP12 0x11
|
||||
#define JP14 0x13
|
||||
#define JP16 0x15
|
||||
#define JP18 0x18
|
||||
#define JP20 0x1A
|
||||
#define JP22 0x1C
|
||||
#define RFStart 0xCD
|
||||
#define SlotTable 0x2
|
||||
#define SyncInit 0xAE
|
||||
#define Sync 0xAF
|
||||
#define SyncLock 0xBF
|
||||
#define SyncLoop 0xC2
|
||||
#define RecvP32U 0x20
|
||||
#define RecvP32P 0x26
|
||||
#define TransmitP00 0x29
|
||||
#define TransmitP32U 0x2D
|
||||
#define TransmitP32P 0x33
|
||||
|
||||
#endif /* SC14421_FIRMWARE */
|
Reference in New Issue