Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Mathis Schmieder (DB9MAT)
STM32_Pager
Commits
ebee6b51
Commit
ebee6b51
authored
Jan 20, 2017
by
Mathis, DB9MAT
Browse files
Initial support for RustPager and DAPNET Integration; Removal of POCSAG packet creation
parent
5d530a14
Changes
6
Hide whitespace changes
Inline
Side-by-side
Inc/RingBuffer.h
0 → 100644
View file @
ebee6b51
/*
* RingBuffer.h
*
* Created on: Jan 20, 2017
* Author: mathis
*/
#ifndef RINGBUFFER_H_
#define RINGBUFFER_H_
#define BUFFER_FAIL 0
#define BUFFER_SUCCESS 1
#define BUFFER_SIZE 256
#define BUFFER_MASK (BUFFER_SIZE-1)
struct
Buffer
{
uint8_t
data
[
BUFFER_SIZE
];
uint8_t
read
;
uint8_t
write
;
};
#endif
/* RINGBUFFER_H_ */
Inc/pocsag.h
deleted
100644 → 0
View file @
5d530a14
/*
* pocsag.h
*
* Created on: Nov 27, 2016
* Author: Mathis Schmieder (DB9MAT), db9mat@giev.de
*
* This library is heavily based upon the POCSAG library by ON1ARF
* https://github.com/on1arf/pocsag
* and on the SDRPager project by Ralf Wilke, DH3WR, et al.
* https://github.com/rwth-afu/SDRPager
*
* This library can be used in any non-commercial amateur radio project as long
* as the original authors and the source is distributed.
*/
#ifndef POCSAG_H_
#define POCSAG_H_
// enums:
typedef
enum
{
POCSAGRC_UNDETERMINED
=
0
,
// Undetermined error
POCSAGRC_INVALIDADDRESS
,
// RETURN CODE FOR INVALID ADDRESS
POCSAGRC_INVALIDSOURCE
,
// RETURN CODE FOR INVALID ADDRESS SOURCE
POCSAGRC_INVALIDBATCH2OPT
,
// RETURN CODE FOR INVALUD "BATCH2" OPTION
POCSAGRC_INVALIDINVERTOPT
// RETURN CODE FOR INVALID "INVERT" OPTION
}
Pocsag_error
;
typedef
enum
{
POCSAG_FAILED
=
0
,
// failed
POCSAG_SUCCESS
// success
}
Pocsag_rc
;
// structures
// a 2-batch pocsag message
typedef
struct
{
unsigned
char
sync
[
72
];
// batch 1
unsigned
char
synccw1
[
4
];
uint32_t
batch1
[
16
];
// batch 2
unsigned
char
synccw2
[
4
];
uint32_t
batch2
[
16
];
}
Pocsagmsg_s
;
// end struct
#define POC_BITS_PER_CW 20;
#define POC_BITS_PER_CHAR 7;
#define POC_BITS_PER_DIGIT 4;
// data
Pocsagmsg_s
Pocsagmsg
;
// public functions
int
CreatePocsag
(
long
int
,
int
,
char
*
,
int
);
int
GetPocsagSize
();
void
*
GetPocsagMsgPointer
();
// private functions
int
_pocsag_size
;
void
pocsag_replaceline
(
Pocsagmsg_s
*
,
int
,
uint32_t
);
uint32_t
pocsag_encodeMCW
(
uint32_t
msg
);
uint32_t
pocsag_encodeACW
(
long
int
addr
,
int
func
);
char
pocsag_encodeChar
(
char
ch
);
char
pocsag_encodeDigit
(
char
ch
);
void
pocsag_encodeNumber
(
uint32_t
addr
,
uint8_t
func
,
char
*
text
);
void
pocsag_encodeText
(
int
addr
,
int
func
,
char
*
text
);
uint32_t
pocsag_crc
(
uint32_t
cw
);
#endif
/* POCSAG_H_ */
Inc/rfm69.h
View file @
ebee6b51
...
...
@@ -17,6 +17,7 @@
#define RFM69_H_
#include "stm32f4xx_hal.h"
#include "RingBuffer.h"
#define RFM69_MAX_FIFO 64 ///< Maximum bytes FIFO
...
...
@@ -65,6 +66,7 @@ uint8_t rfm69_init(SPI_HandleTypeDef spiHandle, int highPowerDevice);
void
rfm69_setCustomConfig
(
const
uint8_t
config
[][
2
],
unsigned
int
length
);
int
rfm69_setPowerDBm
(
int8_t
dBm
);
int
rfm69_send
(
const
void
*
data
,
uint32_t
dataLength
);
int
rfm69_sendBuffer
(
struct
Buffer
*
buffer
);
int
rfm69_receive
(
char
*
data
,
unsigned
int
dataLength
);
RFM69Mode
rfm69_setMode
(
RFM69Mode
mode
);
void
rfm69_sleep
();
...
...
Src/main.c
View file @
ebee6b51
...
...
@@ -36,8 +36,8 @@
/* USER CODE BEGIN Includes */
#include "rfm69.h"
#include "pocsag.h"
#include <string.h>
#include "RingBuffer.h"
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
...
...
@@ -48,8 +48,7 @@ UART_HandleTypeDef huart2;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
char
UART2_Data
;
char
UART_Buffer
[
255
];
uint8_t
UART_i
=
0
;
struct
Buffer
buffer
=
{{},
0
,
0
};
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
...
...
@@ -62,6 +61,19 @@ static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
uint8_t
BufferIn
(
uint8_t
byte
)
{
uint8_t
next
=
((
buffer
.
write
+
1
)
&
BUFFER_MASK
);
if
(
buffer
.
read
==
next
)
return
BUFFER_FAIL
;
buffer
.
data
[
buffer
.
write
]
=
byte
;
buffer
.
write
=
next
;
return
BUFFER_SUCCESS
;
}
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
...
...
@@ -110,85 +122,15 @@ int main(void)
}
}
int
parse_uart
(
uint8_t
*
msg
)
{
/*
* We expect a message in the form of
* P:destination address:function bits:message
*
* example:
* P:10791:3:NOOT NOOT!
*/
if
(
msg
[
0
]
!=
'P'
)
{
// Wrong message format
char
*
answer
=
"EEE
\r\n
"
;
HAL_UART_Transmit
(
&
huart2
,
(
uint8_t
*
)
answer
,
strlen
(
answer
),
1000
);
return
-
1
;
}
// Create POCSAG message
int8_t
err
=
0
;
uint32_t
address
;
uint8_t
function
;
char
message
[
40
];
char
*
p
;
p
=
strtok
((
char
*
)
msg
,
":"
);
if
(
!
p
)
err
=
-
1
;
p
=
strtok
(
NULL
,
":"
);
if
(
p
)
address
=
atoi
(
p
);
else
err
=
-
1
;
p
=
strtok
(
NULL
,
":"
);
if
(
p
)
function
=
atoi
(
p
);
else
err
=
-
1
;
// get the message part
p
=
strtok
(
NULL
,
""
);
if
(
p
)
sprintf
(
message
,
"%s"
,
p
);
else
err
=
-
1
;
if
(
err
<
0
)
{
char
*
answer
=
"EEE
\r\n
"
;
HAL_UART_Transmit
(
&
huart2
,
(
uint8_t
*
)
answer
,
strlen
(
answer
),
1000
);
return
err
;
}
CreatePocsag
(
address
,
function
,
&
message
,
1
);
rfm69_send
((
uint8_t
*
)
GetPocsagMsgPointer
(),
GetPocsagSize
());
rfm69_sleep
();
return
err
;
}
void
HAL_UART_RxCpltCallback
(
UART_HandleTypeDef
*
huart
){
char
UART_Aux
[
255
];
if
(
huart
->
Instance
==
USART2
)
{
if
(
UART2_Data
!=
'\n'
)
{
UART_Buffer
[
UART_i
]
=
UART2_Data
;
UART_i
++
;
}
if
(
UART2_Data
!=
0x17
)
// end of transmission
BufferIn
(
UART2_Data
^=
0xff
);
// RFM69 needs the data inverted, hence XOR 0xFF
else
{
sprintf
(
UART_Aux
,
"%s"
,
UART_Buffer
);
parse_uart
((
uint8_t
*
)
&
UART_Aux
);
memset
(
&
UART_Buffer
[
0
],
0
,
sizeof
(
UART_Buffer
));
UART_i
=
0
;
}
rfm69_sendBuffer
(
&
buffer
);
HAL_UART_Receive_IT
(
&
huart2
,
(
uint8_t
*
)
&
UART2_Data
,
1
);
}
}
...
...
@@ -278,7 +220,7 @@ static void MX_USART2_UART_Init(void)
{
huart2
.
Instance
=
USART2
;
huart2
.
Init
.
BaudRate
=
1152
00
;
huart2
.
Init
.
BaudRate
=
384
00
;
huart2
.
Init
.
WordLength
=
UART_WORDLENGTH_8B
;
huart2
.
Init
.
StopBits
=
UART_STOPBITS_1
;
huart2
.
Init
.
Parity
=
UART_PARITY_NONE
;
...
...
Src/pocsag.c
deleted
100644 → 0
View file @
5d530a14
/*
* pocsag.c
*
* Created on: Nov 27, 2016
* Author: Mathis Schmieder (DB9MAT), db9mat@giev.de
*
* This library is heavily based upon the POCSAG library by ON1ARF
* https://github.com/on1arf/pocsag
* and on the SDRPager project by Ralf Wilke, DH3WR, et al.
* https://github.com/rwth-afu/SDRPager
*
* This library can be used in any non-commercial amateur radio project as long
* as the original authors and the source is distributed.
*/
#include <stdint.h>
#include <string.h>
#include <Pocsag.h>
static
char
isotab
[]
=
{
0x00
,
0x40
,
0x20
,
0x60
,
0x10
,
0x50
,
0x30
,
0x70
,
0x08
,
0x48
,
0x28
,
0x68
,
0x18
,
0x58
,
0x38
,
0x78
,
0x04
,
0x44
,
0x24
,
0x64
,
0x14
,
0x54
,
0x34
,
0x74
,
0x0c
,
0x4c
,
0x2c
,
0x6c
,
0x1c
,
0x5c
,
0x3c
,
0x7c
,
0x02
,
0x42
,
0x22
,
0x62
,
0x12
,
0x52
,
0x32
,
0x72
,
0x0a
,
0x4a
,
0x2a
,
0x6a
,
0x1a
,
0x5a
,
0x3a
,
0x7a
,
0x06
,
0x46
,
0x26
,
0x66
,
0x16
,
0x56
,
0x36
,
0x76
,
0x0e
,
0x4e
,
0x2e
,
0x6e
,
0x1e
,
0x5e
,
0x3e
,
0x7e
,
0x01
,
0x41
,
0x21
,
0x61
,
0x11
,
0x51
,
0x31
,
0x71
,
0x09
,
0x49
,
0x29
,
0x69
,
0x19
,
0x59
,
0x39
,
0x79
,
0x05
,
0x45
,
0x25
,
0x65
,
0x15
,
0x55
,
0x35
,
0x75
,
0x0d
,
0x4d
,
0x2d
,
0x6d
,
0x1d
,
0x5d
,
0x3d
,
0x7d
,
0x03
,
0x43
,
0x23
,
0x63
,
0x13
,
0x53
,
0x33
,
0x73
,
0x0b
,
0x4b
,
0x2b
,
0x6b
,
0x1b
,
0x5b
,
0x3b
,
0x7b
,
0x07
,
0x47
,
0x27
,
0x67
,
0x17
,
0x57
,
0x37
,
0x77
,
0x0f
,
0x4f
,
0x2f
,
0x6f
,
0x1f
,
0x5f
,
0x3f
,
0x7f
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x01
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x6d
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x1d
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x5d
,
0x3a
,
0x3a
,
0x3f
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x6f
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x1f
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x3a
,
0x5f
,
0x3a
,
0x3a
,
0x3a
};
int
GetPocsagSize
()
{
return
(
_pocsag_size
);
};
// end method Get Size
void
*
GetPocsagMsgPointer
()
{
return
((
void
*
)
&
Pocsagmsg
);
};
// end method Get Msg Pointer
int
CreatePocsag
(
long
int
address
,
int
function
,
char
*
text
,
int
option_invert
)
{
int
txtlen
;
// some sanity checks
txtlen
=
strlen
(
text
);
if
(
txtlen
>
40
)
{
// messages can be up to 40 chars (+ terminating EOT)
txtlen
=
40
;
};
// end if
// reinit state to 0 (no message)
_pocsag_size
=
0
;
// some sanity checks for the address
// addreess are 21 bits
if
((
address
>
0x1FFFFF
)
||
(
address
<=
0
))
{
return
(
POCSAG_FAILED
);
};
// end if
// source is 2 bits
if
((
function
<
0
)
||
(
function
>
3
))
{
return
(
POCSAG_FAILED
);
};
// end if
// option "invert" should be 0 or 1
if
((
option_invert
<
0
)
||
(
option_invert
>
1
))
{
return
(
POCSAG_FAILED
);
};
// end if
/* TODO check if needed
// replace terminating \0 by EOT
lastchar=text[txtlen];
text[txtlen]=0x04; // EOT (end of transmission)
txtlen++; // increase size by 1 (for EOT)
*/
// create packet
// part 0.1: frame syncronisation pattern
if
(
option_invert
==
0
)
{
memset
(
Pocsagmsg
.
sync
,
0xaa
,
72
);
}
else
{
memset
(
Pocsagmsg
.
sync
,
0x55
,
72
);
// pattern 0x55 is invers of 0xaa
};
// end else - if
// part 0.2: batch syncronisation
// a batch begins with a sync codeword
// 0111 1100 1101 0010 0001 0101 1101 1000
Pocsagmsg
.
synccw1
[
0
]
=
0x7c
;
Pocsagmsg
.
synccw1
[
1
]
=
0xd2
;
Pocsagmsg
.
synccw1
[
2
]
=
0x15
;
Pocsagmsg
.
synccw1
[
3
]
=
0xd8
;
Pocsagmsg
.
synccw2
[
0
]
=
0x7c
;
Pocsagmsg
.
synccw2
[
1
]
=
0xd2
;
Pocsagmsg
.
synccw2
[
2
]
=
0x15
;
Pocsagmsg
.
synccw2
[
3
]
=
0xd8
;
// invert bits if needed
if
(
option_invert
==
1
)
{
Pocsagmsg
.
synccw1
[
0
]
^=
0xff
;
Pocsagmsg
.
synccw1
[
1
]
^=
0xff
;
Pocsagmsg
.
synccw1
[
2
]
^=
0xff
;
Pocsagmsg
.
synccw1
[
3
]
^=
0xff
;
Pocsagmsg
.
synccw2
[
0
]
^=
0xff
;
Pocsagmsg
.
synccw2
[
1
]
^=
0xff
;
Pocsagmsg
.
synccw2
[
2
]
^=
0xff
;
Pocsagmsg
.
synccw2
[
3
]
^=
0xff
;
};
// part 0.3: init batches with all "idle-pattern"
for
(
int
l
=
0
;
l
<
16
;
l
++
)
{
Pocsagmsg
.
batch1
[
l
]
=
0x7a89c197
;
Pocsagmsg
.
batch2
[
l
]
=
0x7a89c197
;
};
// end for
// Encode text or numbers
// TODO check for proper function byte meanings.
if
(
function
==
3
)
pocsag_encodeText
(
address
,
function
,
text
);
if
(
function
==
0
)
pocsag_encodeNumber
(
address
,
function
,
text
);
// invert bits if needed
if
(
option_invert
)
{
for
(
int
l
=
0
;
l
<
16
;
l
++
)
{
Pocsagmsg
.
batch1
[
l
]
^=
0xffffffff
;
};
// end for
for
(
int
l
=
0
;
l
<
16
;
l
++
)
{
Pocsagmsg
.
batch2
[
l
]
^=
0xffffffff
;
};
// end for
};
/// convert to make endian/architecture independant
for
(
int
l
=
0
;
l
<
16
;
l
++
)
{
int32_t
t1
;
// structure to convert int32 to architecture / endian independant 4-char array
struct
int32_4char
{
union
{
int32_t
i
;
unsigned
char
c
[
4
];
};
}
t2
;
// struct int32_4char t2;
// batch 1
t1
=
Pocsagmsg
.
batch1
[
l
];
// left most octet
t2
.
c
[
0
]
=
(
t1
>>
24
)
&
0xff
;
t2
.
c
[
1
]
=
(
t1
>>
16
)
&
0xff
;
t2
.
c
[
2
]
=
(
t1
>>
8
)
&
0xff
;
t2
.
c
[
3
]
=
t1
&
0xff
;
// copy back
Pocsagmsg
.
batch1
[
l
]
=
t2
.
i
;
// batch 2
t1
=
Pocsagmsg
.
batch2
[
l
];
// left most octet
t2
.
c
[
0
]
=
(
t1
>>
24
)
&
0xff
;
t2
.
c
[
1
]
=
(
t1
>>
16
)
&
0xff
;
t2
.
c
[
2
]
=
(
t1
>>
8
)
&
0xff
;
t2
.
c
[
3
]
=
t1
&
0xff
;
// copy back
Pocsagmsg
.
batch2
[
l
]
=
t2
.
i
;
};
// end for
// TODO check how many batches need to be sent
// more then one batch found
// length = 2 batches (208 octets)
_pocsag_size
=
208
;
return
(
POCSAG_SUCCESS
);
};
// end function create_pocsag
void
pocsag_replaceline
(
Pocsagmsg_s
*
msg
,
int
line
,
uint32_t
val
)
{
// sanity checks
if
((
line
<
0
)
||
(
line
>
32
))
{
return
;
};
// end if
if
(
line
<
16
)
{
msg
->
batch1
[
line
]
=
val
;
}
else
{
msg
->
batch2
[
line
-
16
]
=
val
;
};
// end if
};
// end replaceline
uint32_t
pocsag_crc
(
uint32_t
cw
)
{
uint32_t
crc
;
uint32_t
d
;
uint32_t
m
;
char
p
;
// crc
crc
=
cw
;
d
=
0xED200000
;
for
(
m
=
0x80000000
;
(
m
&
0x400
)
==
0
;
m
>>=
1
)
{
// m ist Bitmaske mit nur einer 1, die vom MSB bis vor den Anfang
// des (CRC+Prait�t) bereichs l�uft, d.h. bis Bit 11 einschl.
if
((
crc
&
m
)
!=
0
)
crc
^=
d
;
d
>>=
1
;
}
cw
|=
crc
;
// parity
p
=
(
char
)
(((
cw
>>
24
)
&
0xff
)
^
((
cw
>>
16
)
&
0xff
)
^
((
cw
>>
8
)
&
0xff
)
^
(
cw
&
0xff
));
p
^=
(
p
>>
4
);
p
^=
(
p
>>
2
);
p
^=
(
p
>>
1
);
p
&=
0x01
;
return
cw
|
p
;
}
uint32_t
pocsag_encodeMCW
(
uint32_t
msg
)
{
return
(
0x80000000
|
((
msg
&
0x000fffff
)
<<
11
));
}
uint32_t
pocsag_encodeACW
(
long
int
addr
,
int
func
)
{
return
(((
addr
&
0x001ffff8
)
<<
10
)
|
((
func
&
0x00000003
)
<<
11
));
}
char
pocsag_encodeChar
(
char
ch
)
{
return
isotab
[
ch
&
0xff
];
}
char
pocsag_encodeDigit
(
char
ch
)
{
char
mirrorTab
[]
=
{
0x00
,
0x08
,
0x04
,
0x0c
,
0x02
,
0x0a
,
0x06
,
0x0e
,
0x01
,
0x09
};
if
(
ch
>=
'0'
&&
ch
<=
'9'
)
return
mirrorTab
[
ch
-
'0'
];
switch
(
ch
)
{
case
' '
:
return
0x03
;
case
'U'
:
return
0x0d
;
case
'_'
:
return
0x0b
;
case
'['
:
return
0x0f
;
case
']'
:
return
0x07
;
}
return
0x05
;
}
void
pocsag_encodeNumber
(
uint32_t
addr
,
uint8_t
func
,
char
*
text
)
{
uint32_t
msg
=
0
;
uint8_t
msgBitsLeft
;
uint8_t
framePos
=
((
addr
&
0x7
)
<<
1
);
// Adress-Codewort erzeugen und im Puffer speichern.
pocsag_replaceline
(
&
Pocsagmsg
,
framePos
,
pocsag_crc
(
pocsag_encodeACW
(
addr
,
func
)));
framePos
++
;
// Komplette Nachricht codieren und speichern.
msgBitsLeft
=
POC_BITS_PER_CW
;
for
(
int
i
=
0
;
i
<
strlen
(
text
);
i
++
)
{
char
ch
=
pocsag_encodeDigit
(
text
[
i
]);
msg
<<=
POC_BITS_PER_DIGIT
;
msg
|=
ch
;
msgBitsLeft
-=
POC_BITS_PER_DIGIT
;
if
(
msgBitsLeft
==
0
)
{
pocsag_replaceline
(
&
Pocsagmsg
,
framePos
,
pocsag_crc
(
pocsag_encodeMCW
(
msg
)));
framePos
++
;
msgBitsLeft
=
POC_BITS_PER_CW
;
}
}
// Wenn das letzte Codewort nicht komplett ist, wird es mit Spaces
// aufgefuellt.
uint8_t
bitpercw
=
POC_BITS_PER_CW
;
if
(
msgBitsLeft
!=
bitpercw
)
{
while
(
msgBitsLeft
>
0
)
{
msg
<<=
POC_BITS_PER_DIGIT
;
msg
|=
0x03
;
/* Space */
msgBitsLeft
-=
POC_BITS_PER_DIGIT
;
}
pocsag_replaceline
(
&
Pocsagmsg
,
framePos
,
pocsag_crc
(
pocsag_encodeMCW
(
msg
)));
}
}
void
pocsag_encodeText
(
int
addr
,
int
func
,
char
*
text
)
{
uint32_t
msg
=
0
;
uint8_t
msgBitsLeft
;
uint8_t
framePos
=
((
addr
&
0x7
)
<<
1
);
// Adress-Codewort erzeugen und im Puffer speichern.
pocsag_replaceline
(
&
Pocsagmsg
,
framePos
,
pocsag_crc
(
pocsag_encodeACW
(
addr
,
func
)));
framePos
++
;
// Komplette Nachricht codieren und speichern.
msgBitsLeft
=
POC_BITS_PER_CW
;
uint8_t
bitpercw
=
POC_BITS_PER_CW
;
uint8_t
bitperchar
=
POC_BITS_PER_CHAR
;
for
(
int
i
=
0
;
i
<
strlen
(
text
);
i
++
)
{
char
ch
=
pocsag_encodeChar
(
text
[
i
]);
if
(
msgBitsLeft
>=
bitperchar
)
{
msg
<<=
POC_BITS_PER_CHAR
;
msg
|=
ch
;
msgBitsLeft
-=
POC_BITS_PER_CHAR
;
if
(
msgBitsLeft
==
0
)
{
pocsag_replaceline
(
&
Pocsagmsg
,
framePos
,
pocsag_crc
(
pocsag_encodeMCW
(
msg
)));
framePos
++
;
msgBitsLeft
=
POC_BITS_PER_CW
;
}
}
else
{
msg
<<=
msgBitsLeft
;
msg
|=
ch
>>
(
bitperchar
-
msgBitsLeft
);
pocsag_replaceline
(
&
Pocsagmsg
,
framePos
,
pocsag_crc
(
pocsag_encodeMCW
(
msg
)));
framePos
++
;
msg
=
ch
;
msgBitsLeft
=
bitpercw
-
bitperchar
+
msgBitsLeft
;
}
}
if
(
msgBitsLeft
!=
bitpercw
)
{
msg
<<=
msgBitsLeft
;
pocsag_replaceline
(
&
Pocsagmsg
,
framePos
,
pocsag_crc
(
pocsag_encodeMCW
(
msg
)));
}
}
Src/rfm69.c
View file @
ebee6b51
...
...
@@ -423,6 +423,67 @@ int rfm69_send(const void* data, uint32_t dataLength)
return
dataLength
;
}
/**
* send buffer over the air.
*/
int
rfm69_sendBuffer
(
struct
Buffer
*
buffer
)
{
// switch to standby and wait for mode ready, if not in sleep mode