Add AFSK example

pull/1/head
Jonathan Brandenburg 8 years ago
parent 9f479800cb
commit 312af3b234

2
.gitignore vendored

@ -2,11 +2,11 @@
*.a
radiochat
radiopiglatin
testax5043
testax5043tx
testax5043rx
testax5043init
testax50432freq
testafsktx
doc/html/
doc/latex/
/.metadata/

@ -5,6 +5,7 @@ all: testax5043rx
all: testax5043tx
all: testax50432freq
all: testax5043init
all: testafsktx
rebuild: clean
rebuild: all
@ -18,6 +19,7 @@ clean:
rm -f testax5043tx
rm -f testax50432freq
rm -f testax5043init
rm -f testafsktx
rm -f libax5043.a
rm -f */*.o
rm -f */*/*.o
@ -67,6 +69,12 @@ testax50432freq: libax5043.a
testax50432freq: transmit2freq/transmit2freq_main.o
gcc -o testax50432freq -L./ transmit2freq/transmit2freq_main.o -lwiringPi -lax5043
testafsktx: libax5043.a
testafsktx: afsktx/ax25.o
testafsktx: afsktx/ax5043.o
testafsktx: afsktx/main.o
gcc -o testafsktx -L./ afsktx/ax25.o afsktx/ax5043.o afsktx/main.o -lwiringPi -lax5043
ax5043/generated/configcommon.o: ax5043/generated/configcommon.c
ax5043/generated/configcommon.o: ax5043/generated/configrx.h
ax5043/generated/configcommon.o: ax5043/generated/configtx.h
@ -243,3 +251,24 @@ init/init_main.o: ax5043/spi/ax5043spi.h
init/init_main.o: ax5043/spi/ax5043spi_p.h
cd init; gcc -I ../ax5043 -pedantic -Wconversion -Wall -Wextra -c init_main.c; cd ..
afsktx/ax25.o: afsktx/ax25.c
afsktx/ax25.o: afsktx/ax25.h
afsktx/ax25.o: afsktx/ax5043.h
afsktx/ax25.o: afsktx/status.h
cd afsktx; gcc -I ../ax5043 -pedantic -Wconversion -Wall -Wextra -c ax25.c; cd ..
afsktx/ax5043.o: afsktx/ax5043.c
afsktx/ax5043.o: afsktx/ax25.h
afsktx/ax5043.o: afsktx/ax5043.h
afsktx/ax5043.o: afsktx/status.h
afsktx/ax5043.o: afsktx/utils.h
afsktx/ax5043.o: ax5043/spi/ax5043spi.h
cd afsktx; gcc -I ../ax5043 -pedantic -Wconversion -Wall -Wextra -c ax5043.c; cd ..
afsktx/main.o: afsktx/main.c
afsktx/main.o: afsktx/status.h
afsktx/main.o: afsktx/ax5043.h
afsktx/main.o: afsktx/ax25.h
afsktx/main.o: ax5043/spi/ax5043spi.h
cd afsktx; gcc -I ../ax5043 -pedantic -Wconversion -Wall -Wextra -c main.c; cd ..

@ -0,0 +1,94 @@
/*
* A sample application transmitting AFSK at 1200 baud
*
* Portions Copyright (C) 2018 Libre Space Foundation
* Portions Copyright (C) 2018 Jonathan Brandenburg
*
* 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 "ax25.h"
#include <string.h>
#include "ax5043.h"
#include "status.h"
static uint8_t __tx_buffer[MAX_FRAME_LEN];
/**
* Creates the header field of the AX.25 frame
* @param conf the AX.25 handle
* @param dest_addr the destination callsign address
* @param dest_ssid the destination SSID
* @param src_addr the callsign of the source
* @param src_ssid the source SSID
* @param preamble_len the number of the AX.25 repetitions in the preamble
* @param postamble_len the number of the AX.25 repetitions in the postamble
*/
int ax25_init(ax25_conf_t *conf, const uint8_t *dest_addr, uint8_t dest_ssid,
const uint8_t *src_addr, uint8_t src_ssid, uint8_t preamble_len,
uint8_t postamble_len) {
uint16_t i = 0;
if (!conf || !dest_addr || !src_addr || preamble_len < 4
|| !postamble_len) {
return -PQWS_INVALID_PARAM;
}
conf->preamble_len = preamble_len;
conf->postable_len = postamble_len;
uint8_t *out = conf->addr_field;
for (i = 0; i < strnlen((char *) dest_addr, AX25_CALLSIGN_MAX_LEN); i++) {
*out++ = (uint8_t) (dest_addr[i] << 1);
}
/*
* Perhaps the destination callsign was smaller that the maximum allowed.
* In this case the leftover bytes should be filled with space
*/
for (; i < AX25_CALLSIGN_MAX_LEN; i++) {
*out++ = ' ' << 1;
}
/* Apply SSID, reserved and C bit */
/* FIXME: C bit is set to 0 implicitly */
*out++ = (uint8_t) ((0x0F & dest_ssid) << 1) | 0x60;
//*out++ = ((0b1111 & dest_ssid) << 1) | 0b01100000;
for (i = 0; i < strnlen((char *) src_addr, AX25_CALLSIGN_MAX_LEN); i++) {
*out++ = (uint8_t) (dest_addr[i] << 1);
}
for (; i < AX25_CALLSIGN_MAX_LEN; i++) {
*out++ = ' ' << 1;
}
/* Apply SSID, reserved and C bit. As this is the last address field
* the trailing bit is set to 1.
*/
/* FIXME: C bit is set to 0 implicitly */
*out++ = (uint8_t) ((0x0F & src_ssid) << 1) | 0x61;
//*out++ = ((0b1111 & src_ssid) << 1) | 0b01100001;
conf->addr_field_len = AX25_MIN_ADDR_LEN;
return PQWS_SUCCESS;
}
int ax25_tx_frame(ax25_conf_t *hax25, ax5043_conf_t *hax,
const uint8_t *payload, uint32_t len) {
if (!hax25 || !hax || !payload || !len) {
return -PQWS_INVALID_PARAM;
}
memcpy(__tx_buffer, hax25->addr_field, hax25->addr_field_len);
memcpy(__tx_buffer + hax25->addr_field_len, payload, len);
return ax5043_tx_frame(hax, __tx_buffer, len + hax25->addr_field_len,
hax25->preamble_len, hax25->postable_len, 1000);
}

@ -0,0 +1,62 @@
/*
* A sample application transmitting AFSK at 1200 baud
*
* Portions Copyright (C) 2018 Libre Space Foundation
* Portions Copyright (C) 2018 Jonathan Brandenburg
*
* 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/>.
*/
#ifndef AX25_H_
#define AX25_H_
#include <stdint.h>
#include "ax5043.h"
#define AX25_MAX_ADDR_LEN 28
#define AX25_MAX_FRAME_LEN 256
#define AX25_MIN_ADDR_LEN 14
#define AX25_SYNC_FLAG 0x7E
#define AX25_MIN_CTRL_LEN 1
#define AX25_MAX_CTRL_LEN 2
#define AX25_CALLSIGN_MAX_LEN 6
#define AX25_CALLSIGN_MIN_LEN 2
#define AX25_PREAMBLE_LEN 16
#define AX25_POSTAMBLE_LEN 16
/**
* AX.25 Frame types
*/
typedef enum {
AX25_I_FRAME, //!< AX25_I_FRAME Information frame
AX25_S_FRAME, //!< AX25_S_FRAME Supervisory frame
AX25_U_FRAME, //!< AX25_U_FRAME Unnumbered frame
AX25_UI_FRAME /**!< AX25_UI_FRAME Unnumbered information frame */
} ax25_frame_type_t;
typedef struct {
uint8_t preamble_len;
uint8_t postable_len;
uint8_t addr_field[AX25_MAX_ADDR_LEN];
uint32_t addr_field_len;
} ax25_conf_t;
int
ax25_init(ax25_conf_t *conf, const uint8_t *dest_addr, uint8_t dest_ssid,
const uint8_t *src_addr, uint8_t src_ssid, uint8_t preamble_len,
uint8_t postamble_len);
int ax25_tx_frame(ax25_conf_t *hax25, ax5043_conf_t *hax,
const uint8_t *payload, uint32_t len);
#endif /* AX25_H_ */

File diff suppressed because it is too large Load Diff

@ -0,0 +1,582 @@
/*
* A sample application transmitting AFSK at 1200 baud
*
* Portions Copyright (C) 2018 Libre Space Foundation
* Portions Copyright (C) 2018 Jonathan Brandenburg
*
* 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/>.
*/
#ifndef AX5043_H_
#define AX5043_H_
#include <stdint.h>
#define FREQUENCY_OFFSET -80000
#define APRS_VHF 440390000
/******************************************************************************
************************* RF Configuration ***********************************
*****************************************************************************/
#define RX_FREQ_HZ (APRS_VHF + FREQUENCY_OFFSET)
#define TX_FREQ_HZ (APRS_VHF + FREQUENCY_OFFSET)
/* Reference Oscillator frequency */
#define XTAL_FREQ_HZ 16000000
/**
* The maximum allowed frame size
*/
#define MAX_FRAME_LEN 1024
#define RX_BAUDRATE 1200
#define TX_BAUDRATE 1200
#define MIN_RF_FREQ_INT_VCO_RFDIV0 800000000
#define MAX_RF_FREQ_INT_VCO_RFDIV0 1050000000
#define MIN_RF_FREQ_INT_VCO_RFDIV1 (MIN_RF_FREQ_INT_VCO_RFDIV0 / 2)
#define MAX_RF_FREQ_INT_VCO_RFDIV1 (MAX_RF_FREQ_INT_VCO_RFDIV0 / 2)
#define MIN_RF_FREQ_EXT_VCO_RFDIV0 54000000
#define MAX_RF_FREQ_EXT_VCO_RFDIV0 525000000
#define MIN_RF_FREQ_EXT_VCO_RFDIV1 (MIN_RF_FREQ_EXT_VCO_RFDIV0 / 2)
#define MAX_RF_FREQ_EXT_VCO_RFDIV1 (MAX_RF_FREQ_EXT_VCO_RFDIV0 / 2)
/**
* Ramp up/Ramp down period of the power amplifier in microseconds
*/
#define PWRAMP_RAMP_PERIOD_US 200
/******************************************************************************
******************** AX5043 control SPI registers ***************************
*****************************************************************************/
/* Status and test registers */
#define AX5043_REG_REV 0x0
#define AX5043_REG_SCRATCH 0x1
/* Power and voltage regulator */
#define AX5043_REG_PWRMODE 0x2
#define AX5043_REG_POWSTAT 0x3
#define AX5043_REG_POWSTICKYSTAT 0x4
#define AX5043_REG_POWIRQMASK 0x5
/* Interrupt control */
#define AX5043_REG_IRQMASK1 0x6
#define AX5043_REG_IRQMASK0 0x7
#define AX5043_REG_RADIOEVENTMASK1 0x8
#define AX5043_REG_RADIOEVENTMASK0 0x9
#define AX5043_REG_IRQREQUEST1 0xC
#define AX5043_REG_IRQREQUEST0 0xD
#define AX5043_REG_RADIOEVENTREQ1 0xE
#define AX5043_REG_RADIOEVENTREQ0 0xF
/* Modulation and framing */
#define AX5043_REG_MODULATION 0x010
#define AX5043_REG_ENCODING 0x011
#define AX5043_REG_FRAMING 0x012
#define AX5043_REG_CRCINIT3 0x014
#define AX5043_REG_CRCINIT2 0x015
#define AX5043_REG_CRCINIT1 0x016
#define AX5043_REG_CRCINIT0 0x017
/* FEC */
#define AX5043_REG_FEC 0x018
#define AX5043_REG_FECSYNC 0x019
#define AX5043_REG_FECSTATUS 0x01A
/* Status */
#define AX5043_REG_RADIOSTATE 0x01C
#define AX5043_REG_XTALSTATUS 0x01D
/* Pin configuration */
#define AX5043_REG_PINSTATE 0x20
#define AX5043_REG_PINFUNCSYSCLK 0x21
#define AX5043_REG_PINFUNCDCLK 0x22
#define AX5043_REG_PINFUNCDATA 0x23
#define AX5043_REG_PINFUNCIRQ 0x24
#define AX5043_REG_PINFUNCANTSEL 0x25
#define AX5043_REG_PINFUNCPWRAMP 0x26
#define AX5043_REG_PWRAMP 0x27
/* FIFO control */
#define AX5043_REG_FIFOSTAT 0x28
#define AX5043_REG_FIFODATA 0x29
#define AX5043_REG_FIFOCOUNT1 0x2A
#define AX5043_REG_FIFOCOUNT0 0x2B
#define AX5043_REG_FIFOFREE1 0x2C
#define AX5043_REG_FIFOFREE0 0x2D
#define AX5043_REG_FIFOTHRESH1 0x2E
#define AX5043_REG_FIFOTHRESH0 0x2F
/* Frequency Synthesizer */
#define AX5043_REG_PLLLOOP 0x30
#define AX5043_REG_PLLCPI 0x31
#define AX5043_REG_PLLVCODIV 0x32
#define AX5043_REG_PLLRANGINGA 0x33
#define AX5043_REG_FREQA3 0x34
#define AX5043_REG_FREQA2 0x35
#define AX5043_REG_FREQA1 0x36
#define AX5043_REG_FREQA0 0x37
#define AX5043_REG_PLLLOOPBOOST 0x38
#define AX5043_REG_PLLCPIBOOST 0x39
#define AX5043_REG_PLLRANGINGB 0x3B
#define AX5043_REG_FREQB3 0x3C
#define AX5043_REG_FREQB2 0x3D
#define AX5043_REG_FREQB1 0x3E
#define AX5043_REG_FREQB0 0x3F
/* RSSI */
#define AX5043_REG_RSSI 0x40
#define AX5043_REG_BGNDRSSI 0x41
#define AX5043_REG_DIVERSITY 0x42
#define AX5043_REG_AGCCOUNTER 0x43
/* Receiver Tracking */
#define AX5043_REG_TRKDATARATE2 0x45
#define AX5043_REG_TRKDATARATE1 0x46
#define AX5043_REG_TRKDATARATE0 0x47
#define AX5043_REG_TRKAMPL1 0x48
#define AX5043_REG_TRKAMPL0 0x49
#define AX5043_REG_TRKPHASE1 0x4A
#define AX5043_REG_TRKPHASE0 0x4B
#define AX5043_REG_TRKRFFREQ2 0x4D
#define AX5043_REG_TRKRFFREQ1 0x4E
#define AX5043_REG_TRKRFFREQ0 0x4F
#define AX5043_REG_TRKFREQ1 0x50
#define AX5043_REG_TRKFREQ0 0x51
#define AX5043_REG_TRKFSKDEMOD1 0x52
#define AX5043_REG_TRKFSKDEMOD0 0x53
/* Timers */
#define AX5043_REG_TIMER2 0x59
#define AX5043_REG_TIMER1 0x5A
#define AX5043_REG_TIMER0 0x5B
/* Wakeup timer */
#define AX5043_REG_WAKEUPTIMER1 0x68
#define AX5043_REG_WAKEUPTIMER0 0x69
#define AX5043_REG_WAKEUP1 0x6A
#define AX5043_REG_WAKEUP0 0x6B
#define AX5043_REG_WAKEUPFREQ1 0x6C
#define AX5043_REG_WAKEUPFREQ0 0x6D
#define AX5043_REG_WAKEUPXOEARLY 0x6E
/* PHY related registers*/
#define AX5043_REG_IFFREQ1 0x100
#define AX5043_REG_IFFREQ0 0x101
#define AX5043_REG_DECIMATION 0x102
#define AX5043_REG_RXDATARATE2 0x103
#define AX5043_REG_RXDATARATE1 0x104
#define AX5043_REG_RXDATARATE0 0x105
#define AX5043_REG_MAXDROFFSET2 0x106
#define AX5043_REG_MAXDROFFSET1 0x107
#define AX5043_REG_MAXDROFFSET0 0x108
#define AX5043_REG_MAXRFOFFSET2 0x109
#define AX5043_REG_MAXRFOFFSET1 0x10A
#define AX5043_REG_MAXRFOFFSET0 0x10B
#define AX5043_REG_FSKDMAX1 0x10C
#define AX5043_REG_FSKDMAX0 0x10D
#define AX5043_REG_FSKDMIN1 0x10E
#define AX5043_REG_FSKDMIN0 0x10F
#define AX5043_REG_AFSKSPACE1 0x110
#define AX5043_REG_AFSKSPACE0 0x111
#define AX5043_REG_AFSKMARK1 0x112
#define AX5043_REG_AFSKMARK0 0x113
#define AX5043_REG_AFSKCTRL 0x114
#define AX5043_REG_AMPLFILTER 0x115
#define AX5043_REG_FREQUENCYLEAK 0x116
#define AX5043_REG_RXPARAMSETS 0x117
#define AX5043_REG_RXPARAMCURSET 0x118
/* Receiver Parameter Set 0 */
#define AX5043_REG_AGCGAIN0 0x120
#define AX5043_REG_AGCTARGET0 0x121
#define AX5043_REG_AGCAHYST0 0x122
#define AX5043_REG_AGCMINMAX0 0x123
#define AX5043_REG_TIMEGAIN0 0x124
#define AX5043_REG_DRGAIN0 0x125
#define AX5043_REG_PHASEGAIN0 0x126
#define AX5043_REG_FREQGAINA0 0x127
#define AX5043_REG_FREQGAINB0 0x128
#define AX5043_REG_FREQGAINC0 0x129
#define AX5043_REG_FREQGAIND0 0x12A
#define AX5043_REG_AMPLGAIN0 0x12B
#define AX5043_REG_FREQDEV10 0x12C
#define AX5043_REG_FREQDEV00 0x12D
#define AX5043_REG_FOURFSK0 0x12E
#define AX5043_REG_BBOFFSRES0 0x12F
/* Receiver Parameter Set 1 */
#define AX5043_REG_AGCGAIN1 0x130
#define AX5043_REG_AGCTARGET1 0x131
#define AX5043_REG_AGCAHYST1 0x132
#define AX5043_REG_AGCMINMAX1 0x133
#define AX5043_REG_TIMEGAIN1 0x134
#define AX5043_REG_DRGAIN1 0x135
#define AX5043_REG_PHASEGAIN1 0x136
#define AX5043_REG_FREQGAINA1 0x137
#define AX5043_REG_FREQGAINB1 0x138
#define AX5043_REG_FREQGAINC1 0x139
#define AX5043_REG_FREQGAIND1 0x13A
#define AX5043_REG_AMPLGAIN1 0x13B
#define AX5043_REG_FREQDEV11 0x13C
#define AX5043_REG_FREQDEV01 0x13D
#define AX5043_REG_FOURFSK1 0x13E
#define AX5043_REG_BBOFFSRES1 0x13F
/* Receiver Parameter Set 2 */
#define AX5043_REG_AGCGAIN2 0x140
#define AX5043_REG_AGCTARGET2 0x141
#define AX5043_REG_AGCAHYST2 0x142
#define AX5043_REG_AGCMINMAX2 0x143
#define AX5043_REG_TIMEGAIN2 0x144
#define AX5043_REG_DRGAIN2 0x145
#define AX5043_REG_PHASEGAIN2 0x146
#define AX5043_REG_FREQGAINA2 0x147
#define AX5043_REG_FREQGAINB2 0x148
#define AX5043_REG_FREQGAINC2 0x149
#define AX5043_REG_FREQGAIND2 0x14A
#define AX5043_REG_AMPLGAIN2 0x14B
#define AX5043_REG_FREQDEV12 0x14C
#define AX5043_REG_FREQDEV02 0x14D
#define AX5043_REG_FOURFSK2 0x14E
#define AX5043_REG_BBOFFSRES2 0x14F
/* Receiver Parameter Set 3 */
#define AX5043_REG_AGCGAIN3 0x150
#define AX5043_REG_AGCTARGET3 0x151
#define AX5043_REG_AGCAHYST3 0x152
#define AX5043_REG_AGCMINMAX3 0x153
#define AX5043_REG_TIMEGAIN3 0x154
#define AX5043_REG_DRGAIN3 0x155
#define AX5043_REG_PHASEGAIN3 0x156
#define AX5043_REG_FREQGAINA3 0x157
#define AX5043_REG_FREQGAINB3 0x158
#define AX5043_REG_FREQGAINC3 0x159
#define AX5043_REG_FREQGAIND3 0x15A
#define AX5043_REG_AMPLGAIN3 0x15B
#define AX5043_REG_FREQDEV13 0x15C
#define AX5043_REG_FREQDEV03 0x15D
#define AX5043_REG_FOURFSK3 0x15E
#define AX5043_REG_BBOFFSRES3 0x15F
/* Transmitter Parameters */
#define AX5043_REG_MODCFGF 0x160
#define AX5043_REG_FSKDEV2 0x161
#define AX5043_REG_FSKDEV1 0x162
#define AX5043_REG_FSKDEV0 0x163
#define AX5043_REG_MODCFGA 0x164
#define AX5043_REG_TXRATE2 0x165
#define AX5043_REG_TXRATE1 0x166
#define AX5043_REG_TXRATE0 0x167
#define AX5043_REG_TXPWRCOEFFA1 0x168
#define AX5043_REG_TXPWRCOEFFA0 0x169
#define AX5043_REG_TXPWRCOEFFB1 0x16A
#define AX5043_REG_TXPWRCOEFFB0 0x16B
#define AX5043_REG_TXPWRCOEFFC1 0x16C
#define AX5043_REG_TXPWRCOEFFC0 0x16D
#define AX5043_REG_TXPWRCOEFFD1 0x16E
#define AX5043_REG_TXPWRCOEFFD0 0x16F
#define AX5043_REG_TXPWRCOEFFE1 0x170
#define AX5043_REG_TXPWRCOEFFE0 0x171
/* PLL parameters */
#define AX5043_REG_PLLVCOI 0x180
#define AX5043_REG_PLLVCOIR 0x181
#define AX5043_REG_PLLLOCKDET 0x182
#define AX5043_REG_PLLRNGCLK 0x183
/* Crystal Oscillator */
#define AX5043_REG_XTALCAP 0x184
/* Baseband */
#define AX5043_REG_BBTUNE 0x188
#define AX5043_REG_BBOFFSCAP 0x189
/* MAC parameters */
/* Packet Format */
#define AX5043_REG_PKTADDRCFG 0x200
#define AX5043_REG_PKTLENCFG 0x201
#define AX5043_REG_PKTLENOFFSET 0x202
#define AX5043_REG_PKTMAXLEN 0x203
#define AX5043_REG_PKTADDR3 0x204
#define AX5043_REG_PKTADDR2 0x205
#define AX5043_REG_PKTADDR1 0x206
#define AX5043_REG_PKTADDR0 0x207
#define AX5043_REG_PKTADDRMASK3 0x208
#define AX5043_REG_PKTADDRMASK2 0x209
#define AX5043_REG_PKTADDRMASK1 0x20A
#define AX5043_REG_PKTADDRMASK0 0x20B
/* Pattern Match */
#define AX5043_REG_MATCH0PAT3 0x210
#define AX5043_REG_MATCH0PAT2 0x211
#define AX5043_REG_MATCH0PAT1 0x212
#define AX5043_REG_MATCH0PAT0 0x213
#define AX5043_REG_MATCH0LEN 0x214
#define AX5043_REG_MATCH0MIN 0x215
#define AX5043_REG_MATCH0MAX 0x216
#define AX5043_REG_MATCH1PAT1 0x218
#define AX5043_REG_MATCH1PAT0 0x219
#define AX5043_REG_MATCH1LEN 0x21C
#define AX5043_REG_MATCH1MIN 0x21D
#define AX5043_REG_MATCH1MAX 0x21E
/* Packet Controller */
#define AX5043_REG_TMGTXBOOST 0x220
#define AX5043_REG_TMGTXSETTLE 0x221
#define AX5043_REG_TMGRXBOOST 0x223
#define AX5043_REG_TMGRXSETTLE 0x224
#define AX5043_REG_TMGRXOFFSACQ 0x225
#define AX5043_REG_TMGRXCOARSEAGC 0x226
#define AX5043_REG_TMGRXAGC 0x227
#define AX5043_REG_TMGRXRSSI 0x228
#define AX5043_REG_TMGRXPREAMBLE1 0x229
#define AX5043_REG_TMGRXPREAMBLE2 0x22A
#define AX5043_REG_TMGRXPREAMBLE3 0x22B
#define AX5043_REG_RSSIREFERENCE 0x22C
#define AX5043_REG_RSSIABSTHR 0x22D
#define AX5043_REG_BGNDRSSIGAIN 0x22E
#define AX5043_REG_BGNDRSSITHR 0x22F
#define AX5043_REG_PKTCHUNKSIZE 0x230
#define AX5043_REG_PKTMISCFLAGS 0x231
#define AX5043_REG_PKTSTOREFLAGS 0x232
#define AX5043_REG_PKTACCEPTFLAGS 0x233
/* Special Functions */
/* General Purpose ADC */
#define AX5043_REG_GPADCCTRL 0x300
#define AX5043_REG_GPADCPERIOD 0x301
#define AX5043_REG_GPADC13VALUE1 0x308
#define AX5043_REG_GPADC13VALUE0 0x309
/* Low Power Oscillator Calibration */
#define AX5043_REG_LPOSCCONFIG 0x310
#define AX5043_REG_LPOSCSTATUS 0x311
#define AX5043_REG_LPOSCKFILT1 0x312
#define AX5043_REG_LPOSCKFILT0 0x313
#define AX5043_REG_LPOSCREF1 0x314
#define AX5043_REG_LPOSCREF0 0x315
#define AX5043_REG_LPOSCFREQ1 0x316
#define AX5043_REG_LPOSCFREQ0 0x317
#define AX5043_REG_LPOSCPER1 0x318
#define AX5043_REG_LPOSCPER0 0x319
/* Performance Tuning Registers */
#define AX5043_REG_XTALDIV 0xF35
/******************************************************************************
************************* Register values ************************************
*****************************************************************************/
#define AX5043_REV 0x51
#define AX5043_SCRATCH_TEST 0xAA
/* Power modes */
#define AX5043_POWERDOWN 0x0
#define AX5043_DEEPSLEEP BIT(0)
#define AX5043_STANDBY (BIT(2) | BIT(0))
#define AX5043_FIFO_ENABLED (BIT(2) | BIT(1) |BIT(0))
#define AX5043_RECEIVE_MODE (BIT(3))
#define AX5043_RECEIVER_RUNNING (BIT(3) | BIT(0))
#define AX5043_RECEIVER_WOR (BIT(3) | BIT(1) | BIT(0))
#define AX5043_TRANSMIT_MODE (BIT(3) | BIT(2))
#define AX5043_TRANSMIT_RUNNING (BIT(3) | BIT(2) | BIT(0))
#define AX5043_FULLTX AX5043_TRANSMIT_RUNNING
#define AX5043_PLLVCOI_MANUAL BIT(7)
/**
* Modem Domain Voltage Regulator Ready
*/
#define AX5043_SVMODEM BIT(3)
/**
* Init value for the VCO prior starting an autoranging
*/
#define AX5043_VCOR_INIT 8
#define AX5043_RFDIV0 0x0
#define AX5043_RFDIV1 BIT(2)
#define AX5043_FREQSHAPE_EXT_FILTER 0x0
#define AX5043_FREQSHAPE_INVALID 0x1
#define AX5043_FREQSHAPE_GAUSSIAN_BT_03 0x2
#define AX5043_FREQSHAPE_GAUSSIAN_BT_05 0x3
/**
* FSK modulation mode
*/
#define AX5043_MODULATION_FSK BIT(3)
/**
* AFSK modulation mode
*/
#define AX5043_MODULATION_AFSK (BIT(3)|BIT(1))
#define AX5043_ENC_INV BIT(0)
#define AX5043_ENC_DIFF BIT(1)
#define AX5043_ENC_SCRAM BIT(2)
/**
* HDLC Framing mode
*/
#define AX5043_HDLC_FRAMING BIT(2)
/**
* HDLC compliant CRC16
*/
#define AX5043_CRC16_CCITT BIT(4)
/**
* Set the FIFO to variable length data mode
*/
#define AX5043_FIFO_VARIABLE_DATA_CMD 0xe1
#define AX5043_FIFO_REPEATDATA_CMD (BIT(6) | BIT(5) | BIT(1))
/**
* FIFO commit command
*/
#define AX5043_FIFO_COMMIT_CMD BIT(2)
#define AX5043_FIFO_PKTSTART BIT(0)
#define AX5043_FIFO_PKTEND BIT(1)
#define AX5043_FIFO_NOCRC BIT(3)
#define AX5043_FIFO_RAW BIT(4)
/**
* Maximum chuck that can be committed on the FIFO
*/
#define AX5043_PKTCHUNKSIZE_240 0xd
#define AX5043_FIFO_MAX_SIZE 240
/**
* When this threshold of free bytes in the TX FIFO is reached,
* we'll put more data in the FIFO
*/
#define AX5043_FIFO_FREE_THR 128
/**
* TX antenna transmission mode
*/
#define AX5043_TX_SINGLE_ENDED BIT(1)
#define AX5043_TX_DIFFERENTIAL BIT(0)
/**
* External PA Control
*/
#define AX5043_EXT_PA_ENABLE 1
#define AX5043_EXT_PA_DISABLE 0
/**
* Frequency mode A or B actually selects at which registers
* the frequency configuration should be written.
*
* This is quite handy for different RX/TX frequencies, to avoid
* writing every time the two different frequency configurations.
*/
typedef enum {
FREQA_MODE = 0, //!< FREQA_MODE
FREQB_MODE = 1 //!< FREQB_MODE
} freq_mode_t;
typedef enum {
VCO_INTERNAL = 0, VCO_EXTERNAL = 1
} vco_mode_t;
typedef enum {
POWERDOWN,
DEEPSLEEP,
STANDBY,
FIFO_ENABLED,
RECEIVE_MODE,
RECEIVER_RUNNING,
RECEIVER_WOR,
TRANSMIT_MODE,
FULLTX
} power_mode_t;
typedef struct {
uint32_t tx_freq;
uint32_t rx_freq;
uint32_t f_xtal;
uint8_t f_xtaldiv;
uint32_t tx_baudrate;
uint32_t rx_baudrate;
uint8_t rf_init;
freq_mode_t freqsel;
vco_mode_t vco;
} ax5043_conf_t;
int ax5043_reset(ax5043_conf_t *conf);
int ax5043_init(ax5043_conf_t *conf, uint32_t f_xtal, vco_mode_t vco);
int ax5043_conf_tx_path(ax5043_conf_t *conf);
int ax5043_set_tx_freq(ax5043_conf_t *conf, uint32_t freq);
int ax5043_set_power_mode(ax5043_conf_t *conf, power_mode_t mode);
int ax5043_set_tx_baud(ax5043_conf_t *conf, uint32_t baud);
int ax5043_freqsel(ax5043_conf_t *conf, freq_mode_t f);
int ax5043_set_tx_synth(ax5043_conf_t *conf);
int ax5043_set_pll_params(ax5043_conf_t *conf);
int ax5043_autoranging(ax5043_conf_t *conf);
int ax5043_aprs_framing_setup(ax5043_conf_t *conf);
int ax5043_tx_frame(ax5043_conf_t *conf, const uint8_t *in, uint32_t len,
uint8_t preamble_len, uint8_t postamble_len, uint32_t timeout_ms);
int ax5043_spi_wait_xtal(ax5043_conf_t *conf, uint32_t timeout_ms);
int ax5043_spi_read_8(ax5043_conf_t *conf, uint8_t *out, uint16_t reg);
int ax5043_spi_read_16(ax5043_conf_t *conf, uint16_t *out, uint16_t reg);
int ax5043_spi_read_24(ax5043_conf_t *conf, uint32_t *out, uint16_t reg);
int ax5043_spi_read_32(ax5043_conf_t *conf, uint32_t *out, uint16_t reg);
int ax5043_spi_write(ax5043_conf_t *conf, uint16_t reg, const uint8_t *in,
uint32_t len);
int ax5043_spi_write_8(ax5043_conf_t *conf, uint16_t reg, uint8_t in);
int ax5043_spi_write_16(ax5043_conf_t *conf, uint16_t reg, uint16_t in);
int ax5043_spi_write_24(ax5043_conf_t *conf, uint16_t reg, uint32_t in);
int ax5043_spi_write_32(ax5043_conf_t *conf, uint16_t reg, uint32_t in);
int ax5043_enable_pwramp(ax5043_conf_t *conf, uint8_t enable);
int ax5043_set_antsel(ax5043_conf_t *conf, uint8_t val);
int ax5043_wait_for_transmit();
#endif /* AX5043_H_ */

@ -0,0 +1,85 @@
/*
* A sample application transmitting AFSK at 1200 baud
*
* Portions Copyright (C) 2018 Jonathan Brandenburg
*
* 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 <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "status.h"
#include "ax5043.h"
#include "ax25.h"
#include "spi/ax5043spi.h"
ax5043_conf_t hax5043;
ax25_conf_t hax25;
static void init_rf();
int main(void) {
setSpiChannel(SPI_CHANNEL);
setSpiSpeed(SPI_SPEED);
initializeSpi();
init_rf();
ax25_init(&hax25, (uint8_t *) "CALLXX", '2', (uint8_t *) "CALLXX", '2',
AX25_PREAMBLE_LEN,
AX25_POSTAMBLE_LEN);
int ret;
uint8_t data[1024];
// 0x03 is a UI frame
// 0x0F is no Level 3 protocol
const char *str = "\x03\x0fThis is an AX.25 Packet!!!";
/* Infinite loop */
for (;;) {
sleep(2);
printf("INFO: Transmitting a packet\n");
memcpy(data, str, strnlen(str, 256));
ret = ax25_tx_frame(&hax25, &hax5043, data, strnlen(str, 256));
if (ret) {
fprintf(stderr,
"ERROR: Failed to transmit AX.25 frame with error code %d\n",
ret);
exit(EXIT_FAILURE);
}
ax5043_wait_for_transmit();
if (ret) {
fprintf(stderr,
"ERROR: Failed to transmit entire AX.25 frame with error code %d\n",
ret);
exit(EXIT_FAILURE);
}
}
return 0;
}
static void init_rf() {
int ret;
ret = ax5043_init(&hax5043, XTAL_FREQ_HZ, VCO_INTERNAL);
if (ret != PQWS_SUCCESS) {
fprintf(stderr,
"ERROR: Failed to initialize AX5043 with error code %d\n", ret);
exit(EXIT_FAILURE);
}
}

@ -0,0 +1,37 @@
/*
* A sample application transmitting AFSK at 1200 baud
*
* Portions Copyright (C) 2018 Libre Space Foundation
* Portions Copyright (C) 2018 Jonathan Brandenburg
*
* 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/>.
*/
#ifndef STATUS_H_
#define STATUS_H_
/**
* Error codes of the PQWS. Users should return the negative of the error
* codes. NO_ERROR is set to zero.
*/
typedef enum {
PQWS_SUCCESS = 0, //!< All ok!
PQWS_INVALID_PARAM, //!< An invalid parameter was given
PQWS_MAX_SPI_TRANSFER_ERROR, //!< The requested SPI data transfer was larger than supported
PQWS_NO_RF_FOUND, //!< No suitable RF chip found
PQWS_AX5043_AUTORANGING_ERROR, //!< Auto ranging failed on AX5043
PQWS_TIMEOUT //!< A timeout occurred
} pqws_error_t;
#endif /* STATUS_H_ */

@ -0,0 +1,54 @@
/*
* A sample application transmitting AFSK at 1200 baud
*
* Portions Copyright (C) 2018 Libre Space Foundation
* Portions Copyright (C) 2018 Jonathan Brandenburg
*
* 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/>.
*/
#ifndef UTILS_H_
#define UTILS_H_
#include <sys/time.h>
#define BIT(x) (1 << x)
static inline size_t min_ul(size_t x, size_t y) {
size_t ret = x < y ? x : y;
return ret;
}
/**
*
* @return the milliseconds from the start of the program.
* Time is handled based on TIM2 timer.
*/
static inline uint32_t millis() {
static struct timeval tv_start;
static int tv_start_initialized = 0;
if (!tv_start_initialized) {
gettimeofday(&tv_start, NULL);
}
struct timeval tv_current;
gettimeofday(&tv_current, NULL);
uint32_t millis_elapsed = 0;
millis_elapsed = (uint32_t) (tv_current.tv_sec - tv_start.tv_sec) * 1000;
millis_elapsed += (uint32_t) (tv_current.tv_usec - tv_start.tv_usec) / 1000;
return millis_elapsed;
}
#endif /* UTILS_H_ */

@ -27,85 +27,289 @@
#include <wiringPiSPI.h>
#include <wiringPi.h>
#define MAX_SPI_WRITE_SIZE (512)
int spiChannel = -1;
int spiSpeed = -1;
void setSpiChannel(int newSpiChannel) {
spiChannel = newSpiChannel;
spiChannel = newSpiChannel;
}
void setSpiSpeed(int newSpiSpeed) {
spiSpeed = newSpiSpeed;
spiSpeed = newSpiSpeed;
}
void initializeSpi() {
//printf("INFO: Initializing SPI\n");
if (spiChannel < 0) {
fprintf(stderr, "ERROR: invalid SPI channel %d\n", spiChannel);
exit(EXIT_FAILURE);
}
if (spiSpeed < 0) {
fprintf(stderr, "ERROR: invalid SPI speed %d\n", spiSpeed);
exit(EXIT_FAILURE);
}
//printf("INFO: Initializing SPI\n");
if (spiChannel < 0) {
fprintf(stderr, "ERROR: invalid SPI channel %d\n", spiChannel);
exit(EXIT_FAILURE);
}
if (spiSpeed < 0) {
fprintf(stderr, "ERROR: invalid SPI speed %d\n", spiSpeed);
exit(EXIT_FAILURE);
}
int fd;
int fd;
wiringPiSetup();
wiringPiSetup();
fd = wiringPiSPISetup(spiChannel, spiSpeed);
if (fd < 0) {
fprintf(stderr, "ERROR: Cannot open SPI bus with error %d, %s\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
fd = wiringPiSPISetup(spiChannel, spiSpeed);
if (fd < 0) {
fprintf(stderr, "ERROR: Cannot open SPI bus with error %d, %s\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
//printf("INFO: Finished initializing SPI\n");
//printf("INFO: Finished initializing SPI\n");
}
void ax5043WriteReg(uint16_t reg, uint8_t val) {
uint8_t buf[3];
int result;
if (spiChannel < 0) {
fprintf(stderr, "ERROR: invalid SPI channel %d\n", spiChannel);
exit(EXIT_FAILURE);
}
buf[0] = (unsigned char)(0x00f0 | ((reg & 0xf00) >> 8));
buf[1] = (reg & 0xff);
buf[2] = val & 0xff;
result = wiringPiSPIDataRW(spiChannel, buf, sizeof(buf));
if (result < 0) {
fprintf(stderr, "Failed to write the register with result %d and error %s\n",
result, strerror(result));
exit(EXIT_FAILURE);
}
uint8_t buf[3];
int result;
if (spiChannel < 0) {
fprintf(stderr, "ERROR: invalid SPI channel %d\n", spiChannel);
exit(EXIT_FAILURE);
}
uint8_t mask = 0xF0;
buf[0] = mask | (~mask & (reg >> 8));
buf[1] = (reg & 0xff);
buf[2] = val & 0xff;
result = wiringPiSPIDataRW(spiChannel, buf, sizeof(buf));
if (result < 0) {
fprintf(stderr,
"Failed to write the register with result %d and error %s\n",
result, strerror(result));
exit(EXIT_FAILURE);
}
}
void ax5043WriteReg2(uint16_t reg, uint16_t val) {
uint8_t buf[4];
int result;
if (spiChannel < 0) {
fprintf(stderr, "ERROR: invalid SPI channel %d\n", spiChannel);
exit(EXIT_FAILURE);
}
uint8_t mask = 0xF0;
buf[0] = mask | (~mask & (reg >> 8));
buf[1] = (reg & 0xff);
buf[2] = (val >> 8) & 0xff;
buf[3] = val & 0xff;
result = wiringPiSPIDataRW(spiChannel, buf, sizeof(buf));
if (result < 0) {
fprintf(stderr,
"Failed to write the register with result %d and error %s\n",
result, strerror(result));
exit(EXIT_FAILURE);
}
}
void ax5043WriteReg3(uint16_t reg, uint32_t val) {
uint8_t buf[5];
int result;
if (spiChannel < 0) {
fprintf(stderr, "ERROR: invalid SPI channel %d\n", spiChannel);
exit(EXIT_FAILURE);
}
uint8_t mask = 0xF0;
buf[0] = mask | (~mask & (reg >> 8));
buf[1] = (reg & 0xff);
buf[2] = (val >> 16)& 0xff;
buf[3] = (val >> 8) & 0xff;
buf[4] = val & 0xff;
result = wiringPiSPIDataRW(spiChannel, buf, sizeof(buf));
if (result < 0) {
fprintf(stderr,
"Failed to write the register with result %d and error %s\n",
result, strerror(result));
exit(EXIT_FAILURE);
}
}
void ax5043WriteReg4(uint16_t reg, uint32_t val) {
uint8_t buf[6];
int result;
if (spiChannel < 0) {
fprintf(stderr, "ERROR: invalid SPI channel %d\n", spiChannel);
exit(EXIT_FAILURE);
}
uint8_t mask = 0xF0;
buf[0] = mask | (~mask & (reg >> 8));
buf[1] = (reg & 0xff);
buf[2] = (val >> 24) & 0xff;
buf[3] = (val >> 16) & 0xff;
buf[4] = (val >> 8) & 0xff;
buf[5] = val & 0xff;
result = wiringPiSPIDataRW(spiChannel, buf, sizeof(buf));
if (result < 0) {
fprintf(stderr,
"Failed to write the register with result %d and error %s\n",
result, strerror(result));
exit(EXIT_FAILURE);
}
}
void ax5043WriteRegN(uint16_t reg, const uint8_t *in, uint32_t len) {
uint8_t buf[MAX_SPI_WRITE_SIZE + 2];
int result;
if (spiChannel < 0) {
fprintf(stderr, "ERROR: invalid SPI channel %d\n", spiChannel);
exit(EXIT_FAILURE);
}
if (len > MAX_SPI_WRITE_SIZE) {
fprintf(stderr,
"ERROR: attempting to write too much data to SPI channel (max of %d): %d\n",
MAX_SPI_WRITE_SIZE, len);
exit(EXIT_FAILURE);
}
uint8_t mask = 0xF0;
buf[0] = mask | (~mask & (reg >> 8));
buf[1] = (reg & 0xff);
for (uint32_t i = 0; i < len; ++i) {
buf[i + 2] = *(in + i);
}
result = wiringPiSPIDataRW(spiChannel, buf, len + 2);
if (result < 0) {
fprintf(stderr,
"Failed to write the register with result %d and error %s\n",
result, strerror(result));
exit(EXIT_FAILURE);
}
}
uint8_t ax5043ReadReg(uint16_t reg) {
uint8_t buf[3];
int result;
if (spiChannel < 0) {
fprintf(stderr, "ERROR: invalid SPI channel %d\n", spiChannel);
exit(EXIT_FAILURE);
}
buf[0] = (unsigned char)(0x0070 | ((reg & 0xf00) >> 8));
buf[1] = (reg & 0xff);
buf[2] = 0x0000;
result = wiringPiSPIDataRW(spiChannel, buf, sizeof(buf));
if (result < 0) {
fprintf(stderr, "Failed to read register with result = %d and error %s\n",
result, strerror(errno));
exit(EXIT_FAILURE);
}
//printf("DEBUG: read value: %d\n", (int)buf[2]);
return (buf[2] & 0xff);
uint8_t buf[3];
int result;
if (spiChannel < 0) {
fprintf(stderr, "ERROR: invalid SPI channel %d\n", spiChannel);
exit(EXIT_FAILURE);
}
uint8_t mask = 0x70;
buf[0] = mask | (~mask & (reg >> 8));
buf[1] = (reg & 0xff);
buf[2] = 0x0000;
result = wiringPiSPIDataRW(spiChannel, buf, sizeof(buf));
if (result < 0) {
fprintf(stderr,
"Failed to read register with result = %d and error %s\n",
result, strerror(errno));
exit(EXIT_FAILURE);
}
//printf("DEBUG: read value: %d\n", (int)buf[2]);
return (buf[2]);
}
uint16_t ax5043ReadReg2(uint16_t reg) {
uint8_t buf[4];
int result;
if (spiChannel < 0) {
fprintf(stderr, "ERROR: invalid SPI channel %d\n", spiChannel);
exit(EXIT_FAILURE);
}
uint8_t mask = 0x70;
buf[0] = mask | (~mask & (reg >> 8));
buf[1] = (reg & 0xff);
buf[2] = 0x0000;
buf[3] = 0x0000;
result = wiringPiSPIDataRW(spiChannel, buf, sizeof(buf));
if (result < 0) {
fprintf(stderr,
"Failed to read register with result = %d and error %s\n",
result, strerror(errno));
exit(EXIT_FAILURE);
}
//printf("DEBUG: read value: %d\n", (int)buf[2]);
return (buf[3]) | (buf[2] << 8);
}
uint32_t ax5043ReadReg3(uint16_t reg) {
uint8_t buf[5];
int result;
if (spiChannel < 0) {
fprintf(stderr, "ERROR: invalid SPI channel %d\n", spiChannel);
exit(EXIT_FAILURE);
}
uint8_t mask = 0x70;
buf[0] = mask | (~mask & (reg >> 8));
buf[1] = (reg & 0xff);
buf[2] = 0x0000;
buf[3] = 0x0000;
buf[4] = 0x0000;
result = wiringPiSPIDataRW(spiChannel, buf, sizeof(buf));
if (result < 0) {
fprintf(stderr,
"Failed to read register with result = %d and error %s\n",
result, strerror(errno));
exit(EXIT_FAILURE);
}
//printf("DEBUG: read value: %d\n", (int)buf[2]);
return (buf[4]) | (buf[3] << 8) | (buf[2] << 16);
}
uint32_t ax5043ReadReg4(uint16_t reg) {
uint8_t buf[6];
int result;
if (spiChannel < 0) {
fprintf(stderr, "ERROR: invalid SPI channel %d\n", spiChannel);
exit(EXIT_FAILURE);
}
uint8_t mask = 0x70;
buf[0] = mask | (~mask & (reg >> 8));
buf[1] = (reg & 0xff);
buf[2] = 0x0000;
buf[3] = 0x0000;
buf[4] = 0x0000;
buf[5] = 0x0000;
result = wiringPiSPIDataRW(spiChannel, buf, sizeof(buf));
if (result < 0) {
fprintf(stderr,
"Failed to read register with result = %d and error %s\n",
result, strerror(errno));
exit(EXIT_FAILURE);
}
//printf("DEBUG: read value: %d\n", (int)buf[2]);
return (buf[5]) | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
}

@ -16,7 +16,7 @@
\file ax5043spi_p.h
\brief Provides an abstraction layer for the SPI interface communicating to the digital transceiver
*/
*/
#ifndef AX5043SPI_P_H_
#define AX5043SPI_P_H_
@ -27,47 +27,96 @@
#define SPI_SPEED (32000000) //!< The default SPI bus speed for the digital transceiver
/*! \fn void setSpiChannel(int newSpiChannel)
\brief Set the SPI channel for the digital transceiver.
\brief Set the SPI channel for the digital transceiver.
setSpiChannel must be called before initializeSpi(). The default is SPI_CHANNEL.
\param newSpiChannel The SPI channel for the digital transceiver.
\sa SPI_CHANNEL
\sa initializeSpi
*/
setSpiChannel must be called before initializeSpi(). The default is SPI_CHANNEL.
\param newSpiChannel The SPI channel for the digital transceiver.
\sa SPI_CHANNEL
\sa initializeSpi
*/
void setSpiChannel(int newSpiChannel);
/*! \fn void setSpiSpeed(int newSpiSpeed)
\brief Set the SPI bus speed for the digital transceiver.
setSpiSpeed must be called before initializeSpi(). The default is SPI_SPEED.
\param newSpiSpeed The SPI bus speed for the digital transceiver.
\sa SPI_SPEED
\sa initializeSpi
*/
\brief Set the SPI bus speed for the digital transceiver.
setSpiSpeed must be called before initializeSpi(). The default is SPI_SPEED.
\param newSpiSpeed The SPI bus speed for the digital transceiver.
\sa SPI_SPEED
\sa initializeSpi
*/
void setSpiSpeed(int newSpiSpeed);
/*! \fn void initializeSpi()
\brief Initilize the SPI bus to communicate with the digital transceiver.
\brief Initilize the SPI bus to communicate with the digital transceiver.
setSpiChannel() and setSpiSpeed() must both be called before initializeSPI().
\sa setSpiChannel
\sa setSpiSpeed
*/
setSpiChannel() and setSpiSpeed() must both be called before initializeSPI().
\sa setSpiChannel
\sa setSpiSpeed
*/
void initializeSpi(void);
/*! \fn void ax5043WriteReg(uint16_t reg, uint8_t val)
\brief Write a value to an AX5043 register.
\param reg The register to write.
\param val The value to right to the register.
*/
\brief Write a value to an AX5043 register.
\param reg The register to write.
\param val The value to right to the register.
*/
void ax5043WriteReg(uint16_t reg, uint8_t val);
/*! \fn void ax5043WriteReg2(uint16_t reg, uint16_t val)
\brief Write a two byte value to an AX5043 register.
\param reg The register to write.
\param val The value to right to the register.
*/
void ax5043WriteReg2(uint16_t reg, uint16_t val);
/*! \fn void ax5043WriteReg3(uint16_t reg, uint32_t val)
\brief Write a three byte value to an AX5043 register.
\param reg The register to write.
\param val The value to right to the register.
*/
void ax5043WriteReg3(uint16_t reg, uint32_t val);
/*! \fn void ax5043WriteReg4(uint16_t reg, uint32_t val)
\brief Write a four byte value to an AX5043 register.
\param reg The register to write.
\param val The value to right to the register.
*/
void ax5043WriteReg4(uint16_t reg, uint32_t val);
/*! \fn void ax5043WriteRegN(uint16_t reg, const uint8_t *in, uint32_t len)
\brief Write a four byte value to an AX5043 register.
\param reg The register to write.
\param val The value to right to the register.
*/
void ax5043WriteRegN(uint16_t reg, const uint8_t *in, uint32_t len);
/*! \fn uint8_t ax5043ReadReg(uint16_t reg)
\brief Read a value from an AX5043 register.
\param reg The register to read.
\return The value read from the register.
*/
\brief Read a one byte value from an AX5043 register.
\param reg The register to read.
\return The value read from the register.
*/
uint8_t ax5043ReadReg(uint16_t reg);
/*! \fn uint16_t ax5043ReadReg2(uint16_t reg)
\brief Read a two value from an AX5043 register.
\param reg The register to read.
\return The value read from the register.
*/
uint16_t ax5043ReadReg2(uint16_t reg);
/*! \fn uint32_t ax5043ReadReg3(uint16_t reg)
\brief Read a three byte value from an AX5043 register.
\param reg The register to read.
\return The value read from the register.
*/
uint32_t ax5043ReadReg3(uint16_t reg);
/*! \fn uint32_t ax5043ReadReg4(uint16_t reg)
\brief Read a four byte value from an AX5043 register.
\param reg The register to read.
\return The value read from the register.
*/
uint32_t ax5043ReadReg4(uint16_t reg);
#endif /* AX5043SPI_P_H_ */

Loading…
Cancel
Save

Powered by TurnKey Linux.